glDrawElementArrays and Vertex Array Objects
Hello. (This question pertains to the OpenGL 3.2 Core Context.)
I am having some confusion about how Vertex Array Objects work with glDrawElements. The OpenGL docs say that the indices are referenced come "sequential elements" (is that whatever is bound to GL_ELEMENT_ARRAY_BUFFER ?), the documentation continues to state that this comes from "an enabled array" (is that the currently bound Vertex Array Object ?) Why is the use of Vertex Array Objects required? I played around with OpenGL ES 2 and I recall using glDrawElements without a Vertex Array Object -- so why is it required here? I guess I'm still not understanding what Vertex Array Objects have to do with anything... all I know is that you must generate one and bind one. But why? I've read several things across the web about Vertex Array Objects and I'm just not getting. I decided to post here so I could have more dynamic feedback with my questions.
I would greatly appreciate it if someone would care to enlighten me!
Have you tried reading the Wiki? That should be your first stop for questions on desktop GL.
Thanks for the link, that's one that I haven't seen before. Even after reading through it, I still don't understand the purpose of the Vertex Array Object. If all that needs to be done is generate a vertex array and bind said array; then why doesn't OpenGL do this "under the hood". Why would the designers of the API make the developer do it? Is there an instance where I might need more than one array?
Originally Posted by Alfonse Reinheart
Your questions make it clear that you don't really understand how rendering works, since you keep calling VAO's an "array" (they're not).
You have the ability, with glVertexAttribPointer and glEnable/DisableVertexAttribArray, to define a number of arrays which feed attribute values to Vertex Shader inputs. So a single rendering call can pull from multiple arrays. Each element of each array defines a vertex. So a vertex might have a position, normal, texture coordinate, etc. Each of those comes from a separate array.
All of the buffer objects that define the storage for these arrays, the format information for these array, and which arrays are enabled, all of that information is a Vertex Array Object. It is, as the page states, "all of the state needed to specify vertex data".
Separate objects may have different vertex needs. Some models don't have texture coordinates. Some models don't have normals. Some models may have per-vertex colors and others don't. Etc. Also, different models often are stored in different buffer objects. So even if they have the exact same format of vertex data, the source of that data is different.
Each different object can be represented as a separate VAO. So to render an object, you bind the VAO and render. Rather than calling a half-dozen glEnableVertexAttribArray and glVertexAttribPointer functions, then rendering.
If you want, you can just bind a VAO at the beginning and do lots of glEnable/DisableVertexAttribArray and glVertexAttribPointer calls when you render your lists of objects. VAOs are mutable objects, so you don't have to ever unbind one. You can just make it, bind it, and constantly change it. If you want to do that, that's up to you.
I see.. that makes sense. Thanks for your assistance!