glDrawElements

Hi everyone,

I had a quick question about the use of glDrawElements.

The last argument to this function is a pointer to the indices for drawing the elements.

In the tutorials I’ve done, I have always created a buffer object for indices and bounded it with glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibos[0]);

From what I’ve read, there is something different about indices when it comes to binding them and using them in a buffer.

My question is, what is the difference between creating a buffer object and binding it to GL_ELEMENT_ARRAY_BUFFER target for indices as opposed to specifying the index data in glDrawElements?
What is the better approach?
How exactly does the binding approach work? Is this binding stored in a VAO? Or do I have to bind the appropriate buffer for what I want to draw before I call glDrawElements?

Thanks so much everyone!

[…]there is something different about indices when it comes to binding them and using them in a buffer.

First of all, you don’t bind indices, you bind buffers (ok, and textures, and images, ah screw it). Second, you don’t use indices in a buffer. Basically you don’t use indices at all - the GPU does. You specify and store indices and the GPU uses indices to construct geometric primitives.

My question is, what is the difference between creating a buffer object and binding it to GL_ELEMENT_ARRAY_BUFFER target for indices as opposed to specifying the index data in glDrawElements?

It’s a case where the wording makes it unnecessarily confusing. Due to historical reasons, the 4th parameter to the function is void pointer to const since with client-side vertex arrays (and no buffer objects) you really passed in a pointer to the first element of a client-side index buffer - i.e. a pointer to some index array stored in system memory, not video memory as in the case of a buffer object. This is legacy GL!

Nowadays, with buffer objects, the 4th parameter is interpreted as an offset into the buffer bound to GL_ELEMENT_ARRAY_BUFFER.

What is the better approach?

I won’t give you advice to use legacy GL, i.e. clent-side vertex arrays. However, as a conversation with Dark Photon recently showed, there are cases where client-side arrays seem to perform better that vertex buffer objects. Still, in general the advice is to use GL 3.1+ style and functions.

Is this binding stored in a VAO? Or do I have to bind the appropriate buffer for what I want to draw before I call glDrawElements?

Yes, just like the buffer binding for GL_ARRAY_BUFFER. That’s one of the main reasons for VAOs, to nodd having to bind stuff everytime you use it - except for the VAO and binding the VAO is only needed if you actually change the binding somewhere else.