6
\$\begingroup\$

Let's assume the following example

creation:

glBindVertexArray(vao)
   glBindBuffer(GL_ARRAY_BUFFER, vbo)
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices)

   // Filling up buffers

   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
   glBindBuffer(GL_ARRAY_BUFFER, 0)

glBindVertexArray(0) // Unbinding vertex array

This looks great from a code-beauty perspective. Each bind-unbind-pair is like parenthesis, so {[()]} (I am also actually using these indentions)

But it also results in a more code for rendering, because the buffers are unbound in the vao, they need to be rebound during rendering, which kind of defeats the purpose of a vao which represents a certain state you can just use whenever you need to.

Rendering would need to look like:

glBindVertexArray(vao)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices)
        // Do your drawing
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
    glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)

so it would be better to

glBindVertexArray(vao)
   glBindBuffer(GL_ARRAY_BUFFER, vbo)
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices)

   // Filling up buffers

glBindVertexArray(0) // Unbinding vertex array
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
glBindBuffer(GL_ARRAY_BUFFER, 0)

Just to make sure the buffers are not bound for another write or anything. Code-wise this looks kind of ugly.

But rendering then is just

glBindVertexArray(vao)
 // Do your drawing
glBindVertexArray(0)

Regarding the cost, the second one uses less (un)bindings, but also it could happen that the vao is already unbound (during rendering) but the vbo and element-buffer is not, so one could write messy data in there.

Am I missing something? Which way is more error-prone? Are the costs for un/binding neglect-able and is the beauty of code worth it?

\$\endgroup\$

1 Answer 1

8
\$\begingroup\$

The GL_ELEMENT_ARRAY_BUFFER binding is part of the VAO state so it should not be unbound. The GL_ARRAY_BUFFER binding isn't so it doesn't matter whether it is unbound or rebound.

If you use DSA it's more explicit.

glVertexArrayElementBuffer(vao, indices);
glVertexArrayVertexAttribOffset(vao, vbo, 1, 4, GL_FLOAT, false, sizeof(Vertex), offsetof(Vertex, pos));

It's more efficient to not unbind the buffer as it's an extra call that will get undone later.

Code beauty is not worth the penalty of rebinding the element buffer in your main render loop.

\$\endgroup\$
5
  • \$\begingroup\$ Can't upvote this enough. Code needs to be clearly readable but it is not an exercise in typography. Time you spend worrying about white-space layout or whether your function calls have a pleasing symmetry is time that could be better spent. \$\endgroup\$
    – Fibbs
    Commented Sep 5, 2015 at 4:24
  • \$\begingroup\$ @Fibbles: It's not so much about typography but more of "I see what's going on in one glance" as that is major error-source in OpenGL (at least as much as I've dealt with it in Teams) \$\endgroup\$
    – Sorona
    Commented Sep 10, 2015 at 7:59
  • \$\begingroup\$ @Teolha OpenGL is a massive state machine. So the challenge is more about knowing what state is set when. \$\endgroup\$ Commented Sep 10, 2015 at 8:13
  • \$\begingroup\$ @ratchetfreak: Exactly, and that's where readable code comes in. Worst problem I've seen so far: A deferred shader renderer that never unbound anything in the steps between because "We know what we're doing, it all makes sense." Ya, it did, until you wanted to add in another step somewhere... then you had to check through all the code before to find out what state OpenGL was in. So I'm kind of wary now... \$\endgroup\$
    – Sorona
    Commented Sep 10, 2015 at 8:22
  • \$\begingroup\$ Unbinding things is often very inefficient. VAOs are pretty much the only thing I explicitly unbind (there are a few others but they don't immediately spring to mind). In any large project you're much better off wrapping OpenGL calls and performing your own state tracking. \$\endgroup\$
    – Fibbs
    Commented Sep 11, 2015 at 19:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .