OpenGL-Vertex-Array-Objects

OpenGL introduced yet-another object in the form of the “Vertex Array Object” to carry (in effect) the vertex format data. Here’s an example of how to create an OpenGL4.3+DSA Vertex Array Object.


//
// setup the DSA-style VAO
auto vao = gl43::varray::GenVertexArrays();
{
    const gl43::attribute_location vp = program.GetAttribLocation("vp");

    // why, yes! i will do this vertex
    vao.EnableVertexArrayAttribEXT(
        vp
    );

    // we only use group0, all the pointers in a group0 advance as one
    gl43::binding_group group0 = 0;

    // we'll read group0, from this buffer, starting here, and it's this wide
    vao.VertexArrayBindVertexBufferEXT(
        group0,
        vbo,
        /* offset = */ 0,
        /* stride = */ sizeof(float) * 3
    );

    // okay; now tell the VAO that attribute is in binding group0
    vao.VertexArrayVertexAttribBindingEXT(
        vp,
        group0
    );

    // last step! we need to tell OpenGL what that attribute actually is (this offset is from the start of the vertex)
    vao.VertexArrayVertexAttribFormatEXT(
        vp,
        /* count = */ 3,
        /* kind = */ gl43::kind::FLOAT,
        /* normalised = */ gl43::F,
        /* relative_offset = */ 0
    );
}

In case it’s not obvious; gl43 is my own hand-rolled GL function wrapper.1

I’m hoping that the gist of what I’m doing is obvious; leave a comment if it’s not.

So, olde-OpenGL had “vertex arrays” which were the start of this terminology. When shaders were introduced, OpenGL had started using “vertex buffers” to put the “vertex arrays” on GPU memory instead of CPU memory. With shaders, one had to use “attributes” to specify where and how to read elements from a vertex array. “Vertex Array Objects” added the option to set all of that once, then, flip it back on with a single call. Finally, the “groups” let one bind different VBO to different groups within the same VAO.

Simply put, all your “characters” should share the same (pool of?) few VBO objects while the trees, houses, and wagons have their own pools.

In general (IIRC) one should have multiple objects spread amongst fewer VBO to reduce the need for state switching. Switching between VBO might cause a “pipeline stall” as the GPU forces everything to complete before starting anything new. A “pipeline stall” means that the earlier steps in the GPU are sitting idle while the later ones finish what they’re doing; not good. The functionality described above supports sharing VBO in a way that … I think reduces the need for pipeline-stalls. The increased granularity of this approach feels better to me, and it’s what the API wants; forward to glory?


  1. “Defactoring” posts into “vanilla OpenGL” is one of the snags that’s kept me from posting this … for … like a year. If I need these notes, hopefully, I’ll be able to map these notes to real-OpenGL or whatever I’m using. If you need these notes - here’s hoping that they make some sense to you.

    [return]
comments powered by Disqus
Peter LaValle avatar
Peter LaValle
Any links probably include affiliate ids for that sweet sweet kickback - and some programs require that I tell you. The contents of this blog are likely unrelated - as they include games, paints, and build tools.