1
votes

To use Vertex Array Object in OpenGL 3.0, we use following steps to create the name of vertex array object and then bind it to the Context.

  • glGenVertexArrays(1,&VAO) = generates the name of vertex array
  • glBindVertexArrays(&VAO) = binds the name with vertex array.

Unlike, when we create and use a Vertex Buffer, we generate the name, bind it, allocate memory and then fill data in the buffer.

  • glGenBuffers( 1, &VBO ) = generate the name for vertex buffer
  • glBindBuffer( GL_ARRAY_BUFFER, VBO ) = bind the name to the GL_ARRAY_BUFFER
  • glBufferData(....) = Allocate memory and fill data

As we have not allocated the memory for Vertex Array Object in these lines, does this mean that memory for Vertex Array Object is already allocated as a part of Context and using glBindVertexArrays() we reference a pointer to the allocated memory for vertex array object?

1

1 Answers

4
votes

glBufferData(....) = Allocate memory and fill data

You are indeed allocating memory for the buffer. But that is different from allocating memory for the buffer object.

Let's put this in C++ terms. A buffer object is like a vector<char>. Doing glGenBuffers/glBindBuffer is like allocating a vector<char> object (and let's do it on the heap):

auto buffer = new vector<char>;

buffer points to a real, live object. sizeof(*buffer) will return a number of bytes of memory, which how much memory the object pointed to by buffer requires. You can request buffer->size() and it will return a legitimate and well-defined value.

glGetBufferParameteri64v(target, GL_BUFFER_SIZE) would be the equivalent of calling buffer->size(). You can call this function after creating the object, before you call glBufferData.

In both cases, buffer->size() and GL_BUFFER_SIZE, the size returned will be 0. Because you haven't put anything into the object yet. In both cases, the object now exists, but it is empty.

glBufferData is like calling buffer->resize. You are now telling the object you allocated to itself allocate some storage of a certain size and (optionally) fill it with certain data.

A vertex array object is different only its purpose. The purpose of a buffer object is to contain storage. The purpose of a vertex array object is to define the association between storage (stored in buffers) and vertex arrays that feed rendering operations.

A VAO in our C++ analogy is more like a regular struct:

struct VAO
{
  int elementBuffer;
  VertexFormat vf[16];
  VertexBufferBinding vb[16];
};

This VAO struct doesn't need allocated storage beyond sizeof(VAO). Just like many C++ objects don't need to allocate storage besides themselves. Therefore, it doesn't have the equivalent of glBufferData.

So to answer your question, the memory for all OpenGL objects is owned by the OpenGL context that created them. It's just that some OpenGL objects can have additional storage beyond that for their basic object. vector<char> has an internal array of bytes. And buffer objects have an internal array of bytes.

VAOs don't have internal arrays of storage beyond the object itself.