Usage of Vertex Array Objects

Hi,

I’m trying to use Vertex Array Objects to perform drawing in multiple stages.
My problem is that when I put data in the last VAO’s buffers everything is drawn fine.
When I put data in other VAO’s then my call to glDrawElements crashes.
I’m using VAO’s on the assumption that when I bind a VAO the buffers that were once bind-ed to the VAO are re-bind’ed. Is that correct?
To show in code what I’m doing:
I’m setting up my buffers like this:


    _vertexArrayObjects=malloc(_layerCount*sizeof(GLuint));
    _vertexBuffers=malloc(_layerCount*sizeof(GLuint));
    _vertexIndicesBuffers=malloc(_layerCount*sizeof(GLuint));
    _countOfIndices=calloc(_layerCount,sizeof(GLsizei));

    glGenVertexArrays(_layerCount, _vertexArrayObjects);
    glGenBuffers(_layerCount, _vertexBuffers);
    glGenBuffers(_layerCount, _vertexIndicesBuffers);

    for (GLsizei i=0; i<_layerCount; i++) {
        glBindVertexArray(_vertexArrayObjects[i]);
        glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffers[i]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vertexIndicesBuffers[i]);

        glEnableVertexAttribArray((GLuint)positionAttribute);
        glEnableVertexAttribArray((GLuint)layerAttribute);
        glEnableVertexAttribArray((GLuint)textureAttribute);
        glVertexAttribPointer((GLuint)positionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(some struct), (const GLvoid *)offsetof(some struct, position));
        glVertexAttribPointer((GLuint)layerAttribute, 1, GL_FLOAT, GL_FALSE, sizeof(some struct), (const GLvoid *)offsetof(some struct, layer));
        glVertexAttribPointer((GLuint)textureAttribute, 2, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(some struct), (const GLvoid *)offsetof(some struct, textureCoordinate));
    }

I then fill the buffers with looping over something like this:


                glBindVertexArray(_vertexArrayObjects[layerIndex]);

                _countOfIndices[layerIndex]=getIndicesCountForLayer(layerIndex);
                verticesBufferSize=getVerticesBufferSizeForLayer(layerIndex);

                glBufferData(GL_ARRAY_BUFFER, verticesBufferSize, NULL, GL_STATIC_DRAW);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, _countOfIndices[layerIndex]*sizeof(GLuint), NULL, GL_STATIC_DRAW);

                verticesBuffer=glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
                indicesBuffer=glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);

                CopyDataInBuffersForLayer(layerIndex,verticesBuffer,indicesBuffer)

                glUnmapBuffer(GL_ARRAY_BUFFER);
                glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);

And then I draw the layers by looping over this:


        glBindVertexArray(_vertexArrayObjects[i]);

        glUniform4f(_colorUniform, red, green, blue, alpha);

        glDrawElements(GL_TRIANGLES, _countOfIndices[i], GL_UNSIGNED_INT, NULL);

If I replace layerIndex with the maximum index (_layerCount-1) then everything works, so I assume my buffers get the correct data.
Did I misunderstood the use of VAO’s?

Thanks in advance.

Kind regards,

Remco Poelstra


glBindVertexArray(_vertexArrayObjects[layerIndex]);
 
_countOfIndices[layerIndex]=getIndicesCountForLayer(layerIndex);
verticesBufferSize=getVerticesBufferSizeForLayer(layerIndex);
 
glBufferData(GL_ARRAY_BUFFER, verticesBufferSize, NULL, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _countOfIndices[layerIndex]*sizeof(GLuint), NULL, GL_STATIC_DRAW);

Calling glBindVertexArray does not affect the buffers bound in the glBindBuffer() sense; VAOs have their own buffer bindings (normally set with glBindVertexBuffer) and glVertexAttribPointer() is a shortcut that can be thought of doing glVertexAttribFormat, glVertexAttribBinding, glBindVertexBuffer internally (see the spec (4.5) around page 338 for details). So the above will only affect whatever buffers happen to be bound to GL_{ELEMENT_,}ARRAY_BUFFER by a previous operation and all your loop iterations modify the same two buffer objects.

Many thanks.
Fixing this does indeed solve my problem!

Regards,

Remco Poelstra