rlgl: OpenGL abstraction and render batching

rlgl.h is a header-only OpenGL wrapper included with #define RLGL_IMPLEMENTATION from rcore.c. It exposes an immediate-mode API (rlBegin, rlVertex2f, rlEnd) that on modern GL accumulates vertices into CPU buffers and draws in few GPU calls.

Interactive batch demo

Add rectangles to the batch, then flush. Changing texture forces a flush (like rlSetTexture in real code).

0 vertsIn batch
0Draw calls
0Texture swaps

rlglInit creates GPU defaults

rlglInit(width, height)
  ├─ 1×1 white RGBA texture (rlLoadTexture)
  ├─ rlLoadShaderDefault() — MVP + texture0 shader
  └─ rlLoadRenderBatch(RL_DEFAULT_BATCH_BUFFERS,
                       RL_DEFAULT_BATCH_BUFFER_ELEMENTS)  // 4096 elements

rlgl.h L2285–2324 — rlglInit

How DrawRectangle reaches the batch

DrawRectanglePro calls rlSetTexture(GetShapesTexture().id), then rlBegin(RL_QUADS), four rlVertex2f + texcoords, rlEnd. Solid colors still use a 1×1 white texture so shapes batch with text.

rshapes.c L777–795

When the batch flushes automatically
  • rlDrawRenderBatchActive() — explicit (EndDrawing, mode changes)
  • rlCheckRenderBatchLimit(vCount) — buffer would overflow
  • Texture or shader change mid-batch
  • Switching draw mode in rlBegin

rlgl.h L3231–3254 — rlCheckRenderBatchLimit

Graphics API selection (compile time)

Preprocessor flags: GRAPHICS_API_OPENGL_33 (default desktop), GRAPHICS_API_OPENGL_ES2 (mobile/web), GRAPHICS_API_OPENGL_11, GRAPHICS_API_OPENGL_SOFTWARE (rlsw).

CMake: -DOPENGL_VERSION="ES 2.0". Makefile: GRAPHICS=GRAPHICS_API_OPENGL_33 in CFLAGS.

Default shader contract

Attribute/uniform names are conventional so custom shaders can opt in:

  • vertexPosition, vertexTexCoord, vertexColor
  • mvp matrix, texture0 sampler

Defined in config.h / rlgl.h as RL_DEFAULT_SHADER_* macros.

3D meshes bypass the batch

DrawMesh binds material shader, sets uniforms, enables VAO/VBOs, and calls glDrawElements directly. Only 2D-style rlBegin paths use the default batch.

See Models & 3D.

rlglData structure (simplified)

rlglData RLGL {
  rlRenderBatch defaultBatch;   // vertex buffers, draw call list
  rlRenderBatch *currentBatch;
  State {
    currentTextureId, currentShaderId,
    matrix stack, blend mode, viewport
  }
  ExtSupported { texCompDXT, texCompETC2, ... }
}