3

我正在绘制一个交错缓冲区 - 它是一个通用顶点属性缓冲区。布局由三个作为顶点坐标的浮点数和其他两个浮点数属性组成,因此交错:

| 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,除了您在此处看到的内容之外,没有设置其他状态。没有纹理或其他缓冲区绑定。

4

1 回答 1

1

从评论中链接的着色器代码中:

#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,一切都会如您所愿。

于 2014-05-24T17:15:29.523 回答