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


followed by a


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?

  • 30
    I am not sure why this question got a -1.. it doesnt show any effort and.or is unclear? I spent 3 days struggling with the specs, wikis and forums before posting this and didnt get any real reason I should use VAO.. meh.. – user815129 Jan 19 '12 at 9:08
  • 18
    Because for the cool bro's it's all obvious as soon as they have their cut-and-pastes handy, why bother with understanding stuff?? – mlvljr Nov 2 '13 at 19:33

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:

    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.

  • ah yes, infact I didnt use VAO at all before.. until GL specs began complaining an error might (and will be) thrown if no VAO is bound.. Thank you – user815129 Jan 19 '12 at 9:06
  • 1
    is it really necessary to unbind the VAO? Ive found different practices around – user815129 Jan 19 '12 at 10:41
  • 3
    It's not necessary, but I usually do it in case some other object decides to render without VAOs (debug drawing/font rendering library/etc.), as that would (as far as I know) replace the attribute settings for the currently bound VAO. – Robert Rouhani Jan 19 '12 at 18:18
  • 2
    Why is the unbind occurring only once and outside the loop? Shouldn't the unbind happen on a per-batch basis? – batbrat Feb 8 '13 at 7:50
  • 11
    Binding a new VAO replaces the old VAO. Unbinding inside the loop would just be extra work. – Robert Rouhani Feb 8 '13 at 19:51

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() {
    // now setup all your VertexAttribPointers that will be bound to this VAO

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

See also these links:

  • This answer should be higher. It specifically fixed a hard to track down bug of mine. – abarax Dec 23 '14 at 13:14
  • 2
    glEnableVertexAttribArray(...) should be called before glVertexAttribPointer(...). Some drivers (including mine) really doesn't like it the other way round. – RecursiveExceptionException Jul 16 '16 at 23:54
  • Upvoted because most of the examples aren't clear that you HAVE to call glEnableVertexAttribArray during the VAO binding. – Rupert Rawnsley Dec 24 '16 at 15:30

is this a correct practice?

Yes, this is perfectly legal and valid. Is it good? Well...

There has been some informal performance testing on this sort of thing. And it seems, at least on NVIDIA hardware where this was tested, the "proper" use of VAOs (ie: what everyone else advocated) actually is slower in many cases. This is especially true if changing VAOs does not change which buffers are bound.

No similar performance testing has taken place on AMD hardware, to my knowledge. In general, unless something changes with them, this is an acceptable use of VAOs.

  • 2
    Surely once each VAO has enough various state that it tracks, that switching the buffers and attrib ptrs manually during the render loop would require many calls, that we would start to see improved performance from the use of the VAO? – Steven Lu Sep 8 '13 at 20:49
  • Unfortunately, the link is dead. – Nick Caplinger Feb 23 '17 at 16:53

Robert's answer above worked for me when I tried it. For what it's worth here is the code, in Go, of using multiple Vertex Attribute Objects:

// VAO 1

vao1 := gl.GenVertexArray()

vbo1 := gl.GenBuffer()

verticies1 := []float32{0, 0, 0, 0, 1, 0, 1, 1, 0}
gl.BufferData(gl.ARRAY_BUFFER, len(verticies1)*4, verticies1, gl.STATIC_DRAW)

pa1 := program.GetAttribLocation("position")
pa1.AttribPointer(3, gl.FLOAT, false, 0, nil)
defer pa1.DisableArray()


// VAO 2

vao2 := gl.GenVertexArray()

vbo2 := gl.GenBuffer()

verticies2 := []float32{-1, -1, 0, -1, 0, 0, 0, 0, 0}
gl.BufferData(gl.ARRAY_BUFFER, len(verticies2)*4, verticies2, gl.STATIC_DRAW)

pa2 := program.GetAttribLocation("position")
pa2.AttribPointer(3, gl.FLOAT, false, 0, nil)
defer pa2.DisableArray()


Then in your main loop you can use them as such:

for !window.ShouldClose() {

    gl.DrawArrays(gl.TRIANGLES, 0, 3)

    gl.DrawArrays(gl.TRIANGLES, 0, 3)


    if window.GetKey(glfw.KeyEscape) == glfw.Press {

If you want to see the full source, it is available as a Gist and derived from the examples in go-gl:


Thanks everyone for the original answers, I had the same question as ECrownofFire.

  • 3
    You don't need to unbind vao1 before binding vao2, simply binding vao2 will suffice. – havokentity May 4 '15 at 5:46

Your Answer

