Vertex Arrays vs. VBOs vs. VAOs

Started by
2 comments, last by 21st Century Moose 11 years, 11 months ago
Greetings,

I was wondering if someone would help me check my understanding of these three concepts, in order to make sure that I have them straight.

[indent=1]1. With all three of these methods, DrawArrays is used to make the actual draw call (or DrawElements, if there are indices). There are other draw functions as well (e.g., for instanced geometry), but these are the simplest ones.

[indent=1]2. The "Arrays" in question refer to individual vertex attribute data arrays.

[indent=1]3. For fixed-function pipeline stuff, the available arrays include GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY, and so on. These arrays can be enabled and disabled individually, and are disabled by default. The data for these arrays can be specified using glVertexPointer, glColorPointer, glTexCoordPointer, etc. If a VBO is bound to GL_ARRAY_BUFFER at the time that gl*Pointer is called, then the pointer parameter specified is assumed to be an offset into that VBO. Otherwise, the pointer specified is assumed to be a direct pointer to the data on the CPU side. Although I've described this as "fixed-function pipeline stuff", the truth is that there are some deprecated built-in vertex attributes that you can use to access this data from GLSL shader code.

[indent=1]4. Under the new-ish shader-only approach, the "Arrays" in question are "vertex attribute arrays", which are analogous to GL_VERTEX_ARRAY, GL_COLOR_ARRAY, etc., except they are generic and can be used for anything. So, they are no longer referred-to by such symbolic constants, but rather are referred to by a GLuint index. The data for these arrays is set using glVertexAttribPointer, which is analogous to glVertexPointer, glColorPointer, etc., except that this one generic function is used for vertex attributes of all types. Because there is just one generic function for all vertex attribute arrays, you must provide information about the data type, size, stride, etc. so that it knows how to interpret the data.

[indent=1]5. My understanding is that, with #4, a VBO must be bound to GL_ARRAY_BUFFER and that supplying a direct pointer to the data (as with "Vertex Arrays") will not work.

[indent=1]6. While performing the steps alluded to in #4, a VAO object must be bound. Subsequent calls to glVertexAttribPointer and glEnableVertexAttribArray will affect that VAO. As such, the VBOs that are bound during calls to glVertexAttribPointer are indirectly associated with the VAO. When it is time to draw, one need only bind the VAO beforehand and there is no need to bind any VBOs or enable/disable specific arrays.

The above is basically what I've been able to come up with after reading the man pages, the OpenGL wiki, and some example source code here and there. I was a bit confused about the reuse of functions in each method, and the reuse of terms such as "vertex arrays" to describe (apparently) different things. There was also some ambiguity in the code samples that I examined. For instance, they would often call glEnableVertexAttribArray only once, when the VAO was first being set up. However, I couldn't tell if they were doing this because the VAO "remembers" which indices were enabled, or if they were just being efficient because the example never wanted those arrays to be disabled. Things like that. I'm hoping I have it straight now, or at least close.

Thank you.
Advertisement
glVertexAttribPointer and friends actually predate VAOs and even go back to a time before usage of VBOs was widespread. You don't need either for to use generic attribs, although you do need shaders of some description (with one exception - attrib 0 always maps to position and can even be used in the fixed pipeline). Doom 3 for example used generic attrib arrays and didn't have VAOs, with use of VBOs being optional.

Otherwise you have it broadly correct - a VAO encapsulates all of the various vertex attrib states and when bound the states that were set for that VAO are automatically applied.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Thanks very much!


glVertexAttribPointer and friends actually predate VAOs and even go back to a time before usage of VBOs was widespread. You don't need either for to use generic attribs, although you do need shaders of some description (with one exception - attrib 0 always maps to position and can even be used in the fixed pipeline).


That is interesting. So, in cases where there is no VBO and no VAO bound, is the pointer just assumed to be a direct pointer to data in system memory? Like with the gl*Pointer functions?
Yup, that should work.

There is also the - I guess - little-known glVertexAttrib function which can even be used with immediate mode (and which may come in handy if you need to quickly prototype something new).

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement