使用不同的缓冲区在OpenGL中绘制多个对象

时间:2015-12-03 14:40:12

标签: opengl

使用OpenGL着色器,我想渲染两个对象。每个都由三角形的一组顶点位置和顶点索引定义。当我制作缓冲区时,我使用以下代码:

// Object 1 vertex positions
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, object1_vertices_size, object1_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

// Object 1 vertex indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, object1_indices_size, object1_indices, GL_STATIC_DRAW);

// Object 2 vertex positions
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, object2_vertices_size, object2_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

// Object 2 vertex indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, object2_indices_size, object2_indices, GL_STATIC_DRAW);

然后当我渲染场景时,我使用以下代码:

// Object 1
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glDrawElements(GL_TRIANGLES, object1_num_indices, GL_UNSIGNED_INT, (void*)0);

// Object 2
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glDrawElements(GL_TRIANGLES, object2_num_indices, GL_UNSIGNED_INT, (void*)0);

然而,这导致仅绘制对象2。我做错了什么?

2 个答案:

答案 0 :(得分:2)

如果你有openGL 3.3+,你应该使用VAO:

glBindVertexArray(vao1);
// Object 1 vertex positions
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, object1_vertices_size, object1_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

// Object 1 vertex indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, object1_indices_size, object1_indices, GL_STATIC_DRAW);

glBindVertexArray(vao2);
// Object 2 vertex positions
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, object2_vertices_size, object2_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

// Object 2 vertex indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, object2_indices_size, object2_indices, GL_STATIC_DRAW);

然后你只需要在绘图时绑定右边的vao:

// Object 1
glBindVertexArray(vao1);
glDrawElements(GL_TRIANGLES, object1_num_indices, GL_UNSIGNED_INT, (void*)0);

// Object 2
glBindVertexArray(vao2);
glDrawElements(GL_TRIANGLES, object2_num_indices, GL_UNSIGNED_INT, (void*)0);

否则你需要在draw:

之间重复绑定和glVertexAttribPointer调用
// Object 1
glBindBuffer(GL_ARRAY_BUFFER, object1_vertex_buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object1_index_buffer);
glDrawElements(GL_TRIANGLES, object1_num_indices, GL_UNSIGNED_INT, (void*)0);

// Object 2
glBindBuffer(GL_ARRAY_BUFFER, object2_vertex_buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object2_index_buffer);
glDrawElements(GL_TRIANGLES, object2_num_indices, GL_UNSIGNED_INT, (void*)0);

答案 1 :(得分:1)

如果这是所有代码,那么有几个问题:

  • 必须通过调用glEnableVertexAttribArray来启用顶点属性。
  • 在绘图代码中,您只是重新绑定索引缓冲区,而不是顶点缓冲区。 glBindBuffer(GL_ARRAY_BUFFER,...glVertexAttribPointer都会更改当前状态,因此您将使用第二个设置覆盖第一个对象设置。如果你真的想在没有VAO的情况下工作,你必须在每次绘制调用之前绑定正确的缓冲区并更新glVertexAttribPointer
  • 没有使用VAO(在Core配置文件中工作时必须使用VAO,但我建议在兼容模式下使用它们)