【问题标题】:OpenGL drawing several objectsOpenGL绘制几个对象
【发布时间】:2015-02-06 20:17:27
【问题描述】:

人们通常如何在 OpenGL 3.3+ 中绘制多个对象? 我有 2 个对象:一个地形和一个球体。对于每个对象,我有 2 个数组(顶点和索引)。我尝试设置不同的 VBO 和 IBO(像这样):

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);

    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
    glDrawElements(GL_TRIANGLES, (size-1)*(size-1)*6, GL_UNSIGNED_INT, 0);



    glBindBuffer(GL_ARRAY_BUFFER, m_VBOsphere);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBOsphere);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);

但看起来 GPU 仅在关闭此功能后才计算/绘制所有内容,而我只看到一个球体。那么,我该怎么办?

【问题讨论】:

  • 我没有看到任何问题。只是为了确保,如果你注释掉 3 行球体渲染,地形渲染得很好?

标签: c++ opengl vbo opengl-3


【解决方案1】:

您似乎误解了绑定缓冲区的含义以及正确的调用顺序。

您希望在这个序列中,draw call 会从 ID 为 m_VBO 的 VBO 获取其顶点:

glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glDrawElements(GL_TRIANGLES, (size-1)*(size-1)*6, GL_UNSIGNED_INT, 0);

这不是它的工作方式。当前的GL_ARRAY_BUFFER 绑定对绘图调用完全没有影响。

在调用glVertexAttribPointer() 时,您需要绑定正确的 VBO。除了为相应属性(格式、步幅等)的设置指定值的直接参数之外,此调用还指定 当前绑定 VBO 用作属性数据的源。

因此,您需要为每个对象调用glVertexAttribPointer(),并在绑定相应的VBO之后调用它们。

那么调用顺序是:

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);

glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glDrawElements(GL_TRIANGLES, (size-1)*(size-1)*6, GL_UNSIGNED_INT, 0);

glBindBuffer(GL_ARRAY_BUFFER, m_VBOsphere);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBOsphere);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

如果您想减少每次绘制调用之前所需的设置调用次数,请查找顶点数组对象 (VAO)。

【讨论】:

  • 非常感谢,您的回答真的很有帮助!
猜你喜欢
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 2021-12-30
  • 2013-07-04
  • 1970-01-01
相关资源
最近更新 更多