VAO绘制了错误的索引缓冲区

时间:2018-10-25 15:39:43

标签: opengl vao

我正在尝试使用(相同的)基本着色器程序绘制多个对象。这些对象具有我打算通过调用glDrawElements使用关联的索引缓冲区绘制的顶点缓冲区。我已经为每个对象设置了VAO,并认为我已将索引缓冲区和顶点缓冲区与VAO相关联,但是当我绘制第二个(以及任何其他对象)时,它们是使用错误的顶点绘制的。

这是我的(伪造的)代码,用于设置VBO和EBO:

glGenBuffers(1, &vboCube);
glBindBuffer(GL_ARRAY_BUFFER, vboCube);
glBufferData(GL_ARRAY_BUFFER, getNumSphereVertices() * sizeof(Vertex), &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &iboCube);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboCube);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, getNumCubeIndices() * sizeof(uint32), &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);


glGenBuffers(1, &vboSphere);
glBindBuffer(GL_ARRAY_BUFFER, vboSphere);
glBufferData(GL_ARRAY_BUFFER, getNumSphereVertices() * sizeof(Vertex), &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &iboSphere);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboSphere);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, getNumSphereIndices() * sizeof(uint32), &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

修改: 这些已更新为使用DSA等效项,问题仍然存在。 DSA代码如下:

glCreateBuffers(1, &vboCube);
glBindBuffer(GL_ARRAY_BUFFER, vboCube);
glNamedBufferData(vboCube, getNumCubeVertices() * sizeof(Vertex), &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

接下来链接我的程序属性:

glUseProgram(programID);

uint32 vaoCube;
glCreateVertexArrays(1, &vaoCube);
glBindVertexArray(vaoCube);
i = 0
for each attribute:
    uint32 attribIndex = glGetAttribLocation(program, name.c_str());
    glVertexArrayVertexBuffer(vaoCube, i, vboCube, 0, stride);
    glEnableVertexArrayAttrib(vaoCube, attribIndex);
    glVertexArrayAttribFormat(vaoCube, attribIndex, numCells, dataType, normalise, offset);
    glVertexArrayAttribBinding(vaoCube, attribIndex, i);
    glVertexArrayBindingDivisor(vaoCube, i, divisor);
    i++
glBindVertexArray(0);

glBindVertexArray(vaoCube);
glVertexArrayElementBuffer(vaoCube, iboCube);
glBindVertexArray(0);


uint32 vaoSphere;
glCreateVertexArrays(1, &vaoSphere);
glBindVertexArray(vaoSphere);
i = 0
for each attribute:
    uint32 attribIndex = glGetAttribLocation(program, name.c_str());
    glVertexArrayVertexBuffer(vaoSphere, i, vboSphere, 0, stride);
    glEnableVertexArrayAttrib(vaoSphere, attribIndex);
    glVertexArrayAttribFormat(vaoSphere, attribIndex, numCells, dataType, normalise, offset);
    glVertexArrayAttribBinding(vaoSphere, attribIndex, i);
    glVertexArrayBindingDivisor(vaoSphere, i, divisor);
    i++
glBindVertexArray(0);

glBindVertexArray(vaoSphere);
glVertexArrayElementBuffer(vaoSphere, iboSphere);
glBindVertexArray(0);

最后绘制对象:

glBindVertexArray(vaoCube);
glDrawElements(GL_TRIANGLES, getNumCubeIndices(), GL_UNSIGNED_INT, (GLvoid*)0);
glBindVertexArray(0);


glBindVertexArray(vaoSphere);
glDrawElements(GL_TRIANGLES, getNumSphereIndices(), GL_UNSIGNED_INT, (GLvoid*)0);
glBindVertexArray(0);

最后的结果:

Cube and sphere

VAO设置不正确吗?

2 个答案:

答案 0 :(得分:2)

如果您使用的是ARB_direct_state_access / OpenGL 4.5,则应始终保持一致。因此,“我的(用于设置VBO和EBO的(伪))代码中的”所有内容都是错误的。您应该使用glCreateBufferglNamedBufferData等。

这很重要,因为尽管GL_ARRAY_BUFFER是上下文状态的一部分,而GL_ELEMENT_ARRAY_BUFFER是VAO状态的一部分。而且,如果您使用的是核心OpenGL,并且没有VAO绑定,这意味着没有元素数组缓冲区状态。因此,您的glBindBuffer通话应该出错,随后您尝试使用它们的尝试也会失败。

答案 1 :(得分:0)

问题出在上面显示的代码之外。上面的代码实际上有效。