Buffer Objects (BO)
Last updated
Last updated
Most of of OpenGL's data are stored inside of a Buffer Object (BO) . For example 3D Model data (Vertex data) are stored inside a Vertex Buffer Object (VBO). Or data that is indexing vertices called Index Buffer Object (IBO). Data that is exchanged between client and shader can use Uniform Buffer Objects (UBO) etc. Those BO are created, initialized and updated by the same functions we will discuss now.
To identify an BO we need an empty name (which is an identificier of that object). We get one using the glCreateBuffers function:
Until here we didn't allocate memory for the BO. We only got an valid name wich we will use to identify our BO. In the next section we will really allocate memory and initialize the BO with data.
We want to use our first BO as a VBO. Look at the following code snippet:
The first thing we did is to define a structure for our vertex. The structure will hold 3 position and 3 color data. Then we created 3 vertices and put it into an array called: vertices. Now we want to tell OpenGL that we like to upload the vertices and how we like to use the this BO later. To allocate memory and set the properties of the BO we use the function glNamedBufferStorage.
The 1. parameter should be a valid BO name. We got one when we used glCreateBuffers. See above. The 2. parameter as it says it the size of the buffer in bytes. The 3. parameter points to a buffer where the data to upload is hold. If we specify a nullptr nothing will be uploaded but memory allocated of the size we specified in the 2. parameter. The 4. parameter is the important one. It tells OpenGL how to deal with the buffer later when it is used with other OpenGL functions. The following bits can be combined with the OR operator.
If you look at our example above you will notice that we didn't set any flags for the usage. We use = 0. This means we don't want any of those features for this buffer. We just simply use it to draw and never touch it again. Later we will see how to use those flags in different scenarios. For now its sufficient.
There will be a time when you want to copy data from one VBO to another. This is done with glCopyNamedBufferSubData.
If we want to modify the values of the BO manually we can map the BO's memory into the clients memory space. We use for that glMapNamedBuffer. I hope you didn't forget that we can use this function only if the correct bits where set when we initialized the BO.
The 1. parameter is the name of the BO we have to specify. The 2. parameter is how we like to access the values of the BO. There are the following options:
If everything (mapping) was successful the function will return a valid pointer to the memory.
When we are finished with reading/writing to/from the BO we have to unmap it. This is done by the function glUnmapNamedBuffer.
glCreateBuffers
Parameter
Type
Description
1
GLsizei n
Number of buffer objects to create.
2
GLuint *buffers
An array in which names of the new buffer objects are stored.
glNamedBufferStorage
Parameter
Type
Description
1
GLuint buffer
Name of the buffer object.
2
GLsizei size
The size of the buffer in bytes.
3
const void *data
Data to upload into the buffer storage.
4
GLbitfield flags
Intented usage bits.
Bit
Description
GL_DYNAMIC_STORAGE_BIT
If this is set, we tell OpenGL that we will change the content of the buffer using glBufferSubData. If we don't specify this bit the client (our program) will not be able to change the data of this buffer directly.
GL_MAP_READ_BIT
If we want to map the address of the memory into the client space to read from it, we need to set this flag. If not set we can't use glMapNamedBuffer to read from it.
GL_MAP_WRITE_BIT
If we want to map the address of the memory into the client space to write to it, we need to set this flag. If not set we can't use glMapNamedBuffer to write to it.
GL_MAP_PERSISTENT_BIT
GL_MAP_COHERENT_BIT
GL_CLIENT_STORAGE_BIT
If this bit is set we tell OpenGL that we like the buffer to be managed inside the client memory.
glCopyNamedBuferSubData
Parameters
Type
Description
1
GLuint readBuffer
The buffer name from where we like to copy from.
2
GLuint writeBuffer
The buffer name where we like to copy to.
3
GLintptr readOffset
Offset we like to use from the buffer we like to read from.
4
GLintptr writeOffset
Offset we like to use inside the buffer we like to write to.
5
GLsizei size
Number of bytes to copy.
glMapNamedBuffer
Parameters
Type
Description
GL_bool
1
GLuint buffer
The VBO name.
2
GLenum access
Specifies the access policy.
Enum
Description
GL_READ_ONLY
We will only read from the buffer.
GL_WRITE_ONLY
We will only write into the buffer.
GL_READ_WRITE
We will read and write from and into the buffer.