Question

I have a rendering infrastructure that uses multiple vertex array objects to render a complex scene. Each vertex array object is responsible for maintaining its own set of bound buffers, pointers and attributes (as they are designed to do).

Given multiple array objects responsible for rendering, how do I introduce depth buffering in such a way that each separate array object uses the same depth buffer during rendering? In other words, how do I unify the concept of Vertex Array Objects (and their nice encapsulation properties) and depth buffering, which seems to be a more global concept.

All the examples I have found describe using a depth buffer in the context of a framebuffer. Apple descibes this technique here. So is the technique to implement the depth buffering at the framebuffer level and then have the vertex array objects write to that framebuffer? Is there an example I can follow that uses VAOs and depth buffering?

I have a class that encapsulates the vertex array object and this is its bind method (responsible for setting up the various buffer, pointers and attributes).

void scene_GLBuffer::BindTriangles()
{
    glBindVertexArrayOES(_mVertexArrayObject);
    glGenVertexArraysOES(1, &_mVertexArrayObject);

    // generate the buffer and configure the gl pointers for position and normal data
    glGenBuffers(1, &_mVertexPositionNormalTriangles);
    /* Bind and set up vertex position and normal data */
    glBindBuffer(GL_ARRAY_BUFFER, _mVertexPositionNormalTriangles);
    glBufferData(GL_ARRAY_BUFFER,
                 sizeof(crVertexPN)*_mPositionNormalTriangleData->size(),
                 _mPositionNormalTriangleData->data(),
                 GL_STATIC_DRAW);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE,
                          sizeof(crVertexPN), (void*)offsetof(crVertexPN,Position));
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE,
                          sizeof(crVertexPN), (void*)offsetof(crVertexPN,Normal));
    glEnableVertexAttribArray(GLKVertexAttribNormal);

    // generate the buffer and configure the gl pointers for color and alpha data
    glGenBuffers(1, &_mVertexColorTriangles);
    glBindBuffer(GL_ARRAY_BUFFER, _mVertexColorTriangles);
    glBufferData(GL_ARRAY_BUFFER,
                 sizeof(crVertexC)*_mColorTriangleData->size(),
                 _mColorTriangleData->data(),
                 GL_DYNAMIC_DRAW);
    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_TRUE,
                          sizeof(crVertexC), (void*)offsetof(crVertexC,Color));
    glEnableVertexAttribArray(GLKVertexAttribColor);
    glBindBuffer(GL_ARRAY_BUFFER,0);

    // generate the buffer and configure the gl pointers for triangle index data
    glGenBuffers(1, &_mVertexIndexTriangles);
    /* Bind and set up triangle index data */
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _mVertexIndexTriangles);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(bits32)*_mIndexTriangleData->size(),_mIndexTriangleData->data(), GL_STATIC_DRAW);
    //        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

    glBindVertexArrayOES(0);
}

After binding, the draw method is implemented as follows (and this draw method is called upon each individual vertex buffer object):

void scene_GLBuffer::Draw()
{
    glBindVertexArrayOES(_mVertexArrayObject);

    glBindBuffer(GL_ARRAY_BUFFER, _mVertexPositionNormalTriangles);
    glDrawElements(GL_TRIANGLES, _mIndexTriangleData->size(), GL_UNSIGNED_INT, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArrayOES(0);
}

All this works smoothly, but I am having trouble seeing where depth buffering fits into this.

Was it helpful?

Solution

I am having trouble seeing where depth buffering fits into this.

That's because it doesn't fit into any of that.

Vertex array objects are ways of encapsulating vertex array state. This state has nothing to do with other state like the current program object, currently bound textures, or the framebuffer. The last one is where the depth buffer comes from.

If you want to render several objects with VAOs to the same framebuffer, then simply don't change the framebuffer. This is how you render them all to the same image (for simplicity's sake, let's call it the screen). The depth buffer is a part of the framebuffer, so if you want to render to the same depth buffer, just don't change the framebuffer between the different objects.

In short, your object's Draw function should neither know nor care what depth buffer is being used currently. Just like the Draw function doesn't know or care what program is being used, what textures are bound, and what the current viewport is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top