Notes

Thoughts, write-ups, and things worth remembering.

OpenGL handles and state machine

#graphics#opengl Updated Oct 13, 2026

GPU objects live in GPU memory. The CPU only holds a GLuint handle (an ID number) and asks the driver to act on “object N”. Treat it as a int number.

Handles

  • A handle is just an integer, like a door number. The real object is on the GPU.
  • Only gl calls hand out handles (glGenBuffers, glCreateShader). Never invent one.
  • 0 means “no object”.
  • Assigning a new handle to the same variable loses the old one; that GPU object still exists but can no longer be reached.
  • The type does not say what kind of object it is. A buffer handle and a shader handle are both GLuint.
TypeUsed for
GLuintObject handles; index data (std::vector<GLuint> idx)
GLintShader variable locations; -1 means not found

Common GPU objects

ObjectWhat it is
BufferRaw GPU memory (vertex data, indices)
ShaderOne compiled stage (vertex or fragment)
ProgramVertex + fragment shader linked together
VAORemembers how buffers are wired to shader inputs
TextureAn image
FramebufferA canvas to draw into

A single vertex is not an object. One buffer holds all vertices.

State machine

  • Context = the whole GL world: every object, every binding, the active program. One per window. No context, no gl calls.
  • Bind = select. glBind* / glUseProgram put an object into a slot (target).
  • Most calls take no “which object” argument. They act on whatever is bound to the slot they read, so binding the wrong object means the next call silently affects it.
  • Each slot holds one object at a time. Different slots can be filled at once.
  • Binding is CPU-side setup. One draw call still processes every vertex and pixel in parallel.

Core pattern

glGenBuffers(1, &buf);              // 1. allocate, get a handle
glBindBuffer(GL_ARRAY_BUFFER, buf); // 2. select it
glBufferData(GL_ARRAY_BUFFER, ...); // 3. operate on the selected object

OpenGL Hub · OpenGL buffers and targets · OpenGL API naming and call order