我正在绘制一个交错缓冲区 - 它是一个通用顶点属性缓冲区。布局由三个作为顶点坐标的浮点数和其他两个浮点数属性组成,因此交错:
| float | float | float | float | float |
| coords.x | coords.y | coords.z | attrib1 | attrib2 |
|_______vertex coordinates_______|_________|_________|
我希望能够用 just 来绘制它glVertexAttribPointer
,这似乎确实有效 - 但是,它只有在我也使用 glEnableClientState(GL_VERTEX_ARRAY)
and时才有效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,除了您在此处看到的内容之外,没有设置其他状态。没有纹理或其他缓冲区绑定。