18

Would someone care to explain the difference to be between a VertexBuffer, a VertexArray, a VertexBufferObject, and a VertexArrayObject? I'm not even sure if these are all terms for different things, but I've seen all of them appear in the OpenGL spec.

I know that a VertexBuffer simply contains vertices and nothing else, once bound, and once I've set the vertex pointers, I can use DrawArrays to draw it. I've done it this way many times.

I am using what I think is a VertexArray, which stores the state of any vertex buffers that are set, and also any vertex pointers. Binding a VertexArray automatically binds the vertex buffer and sets the vertex pointers. I have used this (mostly) successfully too.

But what is a VertexBufferObject, and a VertexArrayObject? Are they better? Doesn't VertexArray give me everything I need?

Hannesh
  • 7,256
  • 7
  • 46
  • 80

2 Answers2

18

A vertex array is simply some data in your program (inside your address space) that you tell OpenGL about by providing a pointer to it.
While more efficient than specifying every single vertex individually, they still have performance issues. The GL must make a copy at the time you call DrawElements (or a similar function), because that is the only time it can be certain that the data is valid (after all, nothing prevents you from overwriting the data right away). This means that there is a significant hindrance to parallelism, and thus a performance issue.

Vertex buffer objects ("vertex buffers") are raw blocks of data that you do not own, i.e. they are not in your address space. You can either copy data into the buffer object with Copy(Sub)Data or by temporarily mapping it to your address space. Once you unmap the buffer, it does no longer belong to you. The huge advantage is that now the GL can decide what to do with it, and when to upload it. It knows that the data will be valid, because you cannot access it. This makes CPU/GPU parallelism a lot easier.

Vertex array abjects are a bit of a misnomer. There are no vertices or arrays in them. They are merely a kind of "state description block" which encapsulate the bindings of one or several vertex buffer objects (including any VertexAttribPointer calls). As such, they are both a convenience function and somewhat more efficient (fewer function calls), but not strictly necessary. You could do anything that a VAO does by hand, too.

Damon
  • 67,688
  • 20
  • 135
  • 185
  • So what I mentioned in my third paragraph was most likely a vertex array object, which is the best for normal applications. Thanks for clearing this up for me. – Hannesh Apr 09 '11 at 20:00
  • Regarding _VAO are a convenience and not strictly necessary_: If I understand it correctly, this is wrong when using an OpenGL 3.1+ core profile. Working with a VBO now requires to have a VAO. For instance, `glEnableVertexAttribArray` [fails](http://www.opengl.org/wiki/GLAPI/glEnableVertexAttribArray#Errors) if there is no VAO bound. It is possible though to just introduce a "global" VAO, [as suggested in this answer](http://stackoverflow.com/a/13405205/1804173). – bluenote10 Aug 28 '14 at 11:28
  • 1
    @bluenote10: Yes, for version 3.1 and higher core profile contexts, you are required to bind at least one VAO (you are not required to use several to switch, though). But that's not what I meant. VAO is _"a convenience thing that is not strictly necessary"_ insofar as it does not do anything "special" that you couldn't do otherwise. It only makes switching the combined state faster and easier. You couldn't possibly do what a texture does or what a vertex buffer does without a texture or without a vertex buffer. But you _could_ do what you do with a VAO without a VAO (just more function calls). – Damon Aug 29 '14 at 18:45
7
  • BufferObject: a GPU allocated memory buffer
    • Vertex Buffer Object: a BufferObject containing vertices informations (colors, position, custom data used by a shader, ...)
    • Pixel Buffer Object: a BufferObject containing pixel or texel informations. Mainly used to upload textures.
    • Element Buffer Object: a BufferObject containing indices (used by glDrawElements).
  • Vertex Array: memory used by gl*Pointer call. Might be host memory or a Vertex Buffer Object if it is bound using glBindBuffer command with GL_ARRAY_BUFFER.
  • Element Array: memory used by glDrawElements call. Might be host memory or an Element Buffer Object if it is bound using glBindBuffer command with GL_ELEMENT_ARRAY_BUFFER.
tibur
  • 11,531
  • 2
  • 37
  • 39