Я рисую чередуемый буфер — это общий буфер атрибутов вершин. Макет состоит из трех чисел с плавающей точкой в качестве координаты вершины и двух других атрибутов с плавающей точкой, чередующихся таким образом:
| float | float | float | float | float |
| coords.x | coords.y | coords.z | attrib1 | attrib2 |
|_______vertex coordinates_______|_________|_________|
Я ожидаю, что смогу нарисовать это просто glVertexAttribPointer
и это действительно похоже на работу — однако, это работает только если я тоже использую glEnableClientState(GL_VERTEX_ARRAY)
а также glVertexPointer()
, хотя я не обращаюсь gl_Vertex
в шейдер!
Минимальный вершинный шейдер (GLSL 1.20):
#version 120
attribute vec3 coords;
attribute float attrib1;
attribute float attrib2;
void main() {
gl_Position = gl_ModelViewProjectionMatrix * vec4(coords.x, coords.y, coords.z, 1.0);
// attrib1 and 2 are used here but this is not relevant
}
Код для рисования буферов:
// set up states
glUseProgram(shader);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLuint shader_att0 = glGetAttribLocation(shader, "coords");
GLuint shader_att1 = glGetAttribLocation(shader, "attrib1");
GLuint shader_att2 = glGetAttribLocation(shader, "attrib2");
glEnableVertexAttribArray(shader_att0);
glEnableVertexAttribArray(shader_att1);
glEnableVertexAttribArray(shader_att2);
// *** These two lines below should not be necessary: ***
//glEnableClientState(GL_VERTEX_ARRAY);
//glVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), reinterpret_cast<void*>(0));
// *** ...but without them, nothing is drawn! ***
glVertexAttribPointer(shader_att0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), reinterpret_cast<void*>(0)); // 0: vertex coords
glVertexAttribPointer(shader_att1, 1, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), reinterpret_cast<void*>(3 * sizeof(GLfloat))); // 1: attrib1
glVertexAttribPointer(shader_att2, 1, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), reinterpret_cast<void*>(4 * sizeof(GLfloat))); // 2: attrib2
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
// do the drawing
glDrawElements(GL_TRIANGLES, numverts, GL_UNSIGNED_INT, 0);
// revert all the states again
glUseProgram(0);
glDisableVertexAttribArray(shader_att0);
glDisableVertexAttribArray(shader_att1);
glDisableVertexAttribArray(shader_att2);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Все отлично работает в коде выше если Я раскомментирую две аннотированные строки; в противном случае ничего не рисуется.
Это действительно поставило меня в тупик … я где-то пропустил какое-то изменение состояния или я что-то забыл включить?
Изменить: я не использую VAO, и нет никакого другого состояния, кроме того, что вы видите здесь. Никаких текстур или других связанных буферов.
Из вашего связанного кода шейдера в комментариях:
#version 120
#pragma optimize(on)
#pragma debug(on)
attribute vec4 coords; // we only input a vec3, so w defaults to 1.0
attribute float lambertian_main;
attribute float lambertian_side;
varying float height;
varying float lambertian_main_frag;
varying float lambertian_side_frag;
void main() {
gl_Position = gl_ModelViewProjectionMatrix * coords;
lambertian_main_frag = lambertian_main;
lambertian_side_frag = lambertian_side;
height = gl_Vertex.y;
}
Вы являются с помощью gl_Vertex
здесь … И если он используется, он всегда получит атрибут ID 0. Это полностью объясняет поведение, которое вы видели и описывали как в вопросе, так и в комментариях. Просто используйте height = coords.y
и все будет работать так, как вы ожидаете.