glBufferData
Allocates GPU memory for the bound buffer and optionally copies data into it.
Signature
void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
How it works
This is how data leaves your C++ arrays and reaches the GPU. It (re)allocates the storage of the buffer bound to target with exactly size bytes, and copies size bytes from data into it.
Calling it again on the same buffer throws the old storage away and allocates a new one — useful to resize, but expensive if done every frame. To update part of an existing buffer, use glBufferSubData.
Parameters
Slot whose bound buffer receives the data (e.g. GL_ARRAY_BUFFER).
Size in BYTES. Use sizeof(array) for static arrays or count * sizeof(T) for vectors.
Pointer to the source data, or nullptr to only allocate (contents undefined).
A hint about how often you will change and use the data. The driver uses it to decide where to place the memory.
Common values
- GL_STATIC_DRAW
- Set once, drawn many times (meshes).
- GL_DYNAMIC_DRAW
- Changed often, drawn many times.
- GL_STREAM_DRAW
- Set once, drawn a few times (per-frame data).
Tips & pitfalls
Classic bug: sizeof(pointer) or sizeof(std::vector) instead of the data size. For a vector use v.size() * sizeof(v[0]).
The data is copied during the call, so your CPU array can be freed right after.
Errors
When the call is invalid it does nothing and sets an error, which glGetError returns:
- GL_INVALID_OPERATION
- No buffer is bound to target.
- GL_OUT_OF_MEMORY
- The GPU could not allocate size bytes.
Example
1float vertices[] = {
2 -0.5f, -0.5f, 0.0f,
3 0.5f, -0.5f, 0.0f,
4 0.0f, 0.5f, 0.0f,
5};
6glBindBuffer(GL_ARRAY_BUFFER, vbo);
7glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);