OpenGL 绘制多个对象
OpenGL drawing several objects
人们通常如何在 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 calculates/draw 只有在关闭此功能后才能看到所有内容,我只看到一个球体。那么,我该怎么办呢?
您似乎误解了绑定缓冲区的含义以及正确的调用顺序。
您预计在此序列中,绘制调用将从 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)。
人们通常如何在 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 calculates/draw 只有在关闭此功能后才能看到所有内容,我只看到一个球体。那么,我该怎么办呢?
您似乎误解了绑定缓冲区的含义以及正确的调用顺序。
您预计在此序列中,绘制调用将从 ID 为 m_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)。