【问题标题】:Drawing multiple objects in OpenGL with different buffers在 OpenGL 中使用不同的缓冲区绘制多个对象
【发布时间】:2015-12-03 14:40:11
【问题描述】:

使用 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 被绘制。我做错了什么?

【问题讨论】:

  • 你在这里如何使用着色器?

标签: opengl


【解决方案1】:

如果你有 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);

否则您将需要在两次抽签之间重复绑定和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);

【讨论】:

【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多