Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL VAO best practices

Im facing an issue which I believe to be VAO-dependant, but Im not sure..

I am not sure about the correct usage of a VAO, what I used to do during GL initialization was a simple

glGenVertexArrays(1,&vao)

followed by a

glBindVertexArray(vao)

and later, in my drawing pipeline, I just called glBindBuffer(), glVertexAttribPointer(), glEnableVertexAttribArray() and so on.. without caring about the initally bound VAO

is this a correct practice?

like image 672
user815129 Avatar asked Jan 19 '12 08:01

user815129


2 Answers

VAOs act similarly to VBOs and textures with regard to how they are bound. Having a single VAO bound for the entire length of your program will yield no performance benefits because you might as well just be rendering without VAOs at all. In fact it may be slower depending on how the implementation intercepts vertex attribute settings as they're being drawn.

The point of a VAO is to run all the methods necessary to draw an object once during initialization and cut out all the extra method call overhead during the main loop. The point is to have multiple VAOs and switch between them when drawing.

In terms of best practice, here's how you should organize your code:

initialization:
    for each batch
        generate, store, and bind a VAO
        bind all the buffers needed for a draw call
        unbind the VAO

main loop/whenever you render:
    for each batch
        bind VAO
        glDrawArrays(...); or glDrawElements(...); etc.
    unbind VAO

This avoids the mess of binding/unbinding buffers and passing all the settings for each vertex attribute and replaces it with just a single method call, binding a VAO.

like image 172
Robert Rouhani Avatar answered Oct 13 '22 00:10

Robert Rouhani


No, that's not how you use VAO. You should use VAO in same way how you are using VBO or textures, or shaders. First set it up. And during rendering only Bind them, without modifying it.

So with VAO you do following:

void Setup() {
    glGenVertexArrays(..);
    glBindVertexArray(..);
    // now setup all your VertexAttribPointers that will be bound to this VAO
   glBindBuffer(..);
   glVertexAttribPointer(..);
   glEnableVertexAttribArray(..);
}

void Render() {
    glBindVertexArray(vao);
    // that's it, now call one of glDraw... functions
    // no need to set up vertex attrib pointers and buffers!
    glDrawXYZ(..)
}

See also these links:

  • http://www.swiftless.com/tutorials/opengl4/4-opengl-4-vao.html
  • http://www.lastrayofhope.com/2011/07/30/using-vertex-array-objects/
like image 30
Mārtiņš Možeiko Avatar answered Oct 12 '22 23:10

Mārtiņš Možeiko