Я практикую текстуры в OpenGL, применяя простую текстуру белого цвета к квадрату. Код компилируется и работает нормально, но цвет квадрата просто черный, а не белый, как я указал.
Я думаю, это потому, что мой фрагментный шейдер не выполняет правильную выборку, это похоже на то, что данные, которые он возвращает из функции texture, равны нулю, поэтому текстура четырехугольника становится черной. Причина, по которой я так подозреваю, заключается в том, что, когда я запускаю программу, я могу сделать чистый белый цвет и немного сдвинуть одну из вершин на четырехугольнике, чтобы увидеть фон (поскольку он обычно заполняет всю поверхность). Тогда я могу ясно видеть белый фон с черным квадратом сверху. Таким образом, некоторый выходной цвет создается из фрагментного шейдера, это просто неправильный цвет, поскольку предоставленный мной небольшой массив пикселей имеет только белый цвет. Проблема в том, что я точно не знаю, почему код, который у меня есть, дает неверные результаты. Я пытаюсь следовать за книгой, в которой используется или менее тот же код. Я также пробовал искать его в разных руководствах, но все они, похоже, используют один и тот же подход, поэтому я застрял.
[РЕДАКТИРОВАТЬ]
Я обнаружил некоторые проблемы. Выполнив отслеживание ошибок с помощью glGetError (), я понял, что эта строка моего кода:
glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 4);
возвращает код ошибки 1282 (Недопустимая операция) из-за того, что второй параметр level равен 0. Если я установил для него значение 1, ошибка исчезнет. Тогда проблема становится такой:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_R, GL_FLOAT, myTexture);
Что возвращает ту же ошибку, но не исправляется изменением параметра level.
Это фрагментный и вершинный шейдер, который я использую:
Фрагментный шейдер
// FRAGMENT SHADER
#version 330
uniform sampler2D tex;
in vec2 vs_tex_coord;
layout (location = 0) out vec4 outputColor;
void main(void)
{
outputColor = texture(tex, vs_tex_coord);
}
Вершинный шейдер
// VERTEX SHADER
#version 330
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 in_tex_coord;
uniform vec2 offset;
out vec2 vs_tex_coord;
void main(void)
{
vec4 finalOffset = vec4(offset.x, offset.y, 0.0, 0.0);
gl_Position = position + finalOffset;
vs_tex_coord = in_tex_coord;
}
Код, который я использую для создания и хранения текстурных объектов, довольно прост:
glGenTextures(1, &textureHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureHandle);
glTexStorage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 4);
const GLubyte myTexture[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGB, GL_UNSIGNED_BYTE, myTexture);
myTexture просто содержит текстуру 4x4 во внутреннем формате RGB, где каждый компонент имеет 4 бита. Я установил их все в белый цвет.
Затем я просто создаю сэмплер по умолчанию, например:
glGenSamplers(1, &mySampler);
glBindSampler(0, mySampler);
И наконец рендер:
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(theProgram);
GLuint samplerLoc = glGetUniformLocation(theProgram, "tex");
if (samplerLoc == -1)
printf("Location name could not be found...\n");
glUniform1i(samplerLoc, 0);
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(16 * sizeof(float)));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
Массив, который я загружаю в VBO:
const float vertexPositions[] =
{
// Vertex position
-0.8f, -1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
// Texture coordinates
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
Это потому, что я неправильно использую объекты сэмплера? Нужно ли мне устанавливать для них какие-то настройки, прежде чем я смогу заставить его работать правильно? Я пропускаю какой-нибудь промежуточный шаг?
Для всех, кто интересуется, визуальный результат таков:
Вы можете увидеть белый очищенный фон, при этом я намеренно немного сдвинул одну из позиций вершины, чтобы вы могли видеть черный четырехугольник на белом фоне.
glTexStorage2D
+1 за использование неизменяемых текстур. - person Nicol Bolas   schedule 09.08.2013glBindTexture
, и не знаешь об этом. - person Nicol Bolas   schedule 09.08.2013