-1

I'm trying to draw multiple objects with a (the same) basic shader program. The objects have vertex buffers that I intend to draw using associated index buffers by calling glDrawElements. I've set up a VAO for each object and thought I'd associated the index buffer and vertex buffer with the VAO, but when I draw the second (and any additional objects) they are drawn using the wrong vertices.

Here's my (pseudoish) code for setting up the VBO's and EBO's:

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);

Edit: These have been updated to use DSA equivalents and the problem persists. DSA code as per:

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

Next linking my program attributes:

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);

And finally drawing the objects:

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);

Finally the result:

Cube and sphere

Is the VAO setup incorrect?

schwyzl
  • 321
  • 1
  • 11
  • 1
    @Rabbid76 sorry, that was a bad code to question conversion. vertexBufferBinding is the binding point of the VBO (vboCube and vboSphere in this instance). I've edited the code snippet to reflect this. – schwyzl Oct 25 '18 at 16:12

2 Answers2

2

If you are using ARB_direct_state_access/OpenGL 4.5, you should do so consistently and entirely. So all of that stuff in "my (pseudoish) code for setting up the VBO's and EBO's:" is wrong. You should be using glCreateBuffer, glNamedBufferData and the like.

This is important because while GL_ARRAY_BUFFER is part of context state, GL_ELEMENT_ARRAY_BUFFER is part of VAO state. And if you're using core OpenGL and don't have a VAO bound... that means there is no element array buffer state. So your glBindBuffer call should have errored out, and your subsequent attempts to use them would similarly fail.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Thanks for the feedback. I've updated the buffer creation and fill funcs to the DSA method. Interestingly I wasn't getting any GL errors with the other setup. The issue with the mangled sphere persists though. – schwyzl Oct 25 '18 at 17:56
0

The problem was external to the code shown above. The above code actually works.

schwyzl
  • 321
  • 1
  • 11