The mental model in one paragraph
raylib is a modular C library built around two mandatory pieces — rcore (window, input, timing) and rlgl (OpenGL abstraction) — plus optional modules for shapes, textures, text, 3D models, and audio. You call InitWindow(), which boots a platform backend (GLFW by default), creates an OpenGL context, and initializes rlgl's default shader and render batch. Each frame you call BeginDrawing(), issue draw calls that accumulate geometry into a batch, then EndDrawing() flushes the batch, swaps buffers, limits FPS, and polls input. There is no built-in scene graph or entity system — just functions.
Interactive architecture map
Tap a module to see what it does and how it fits. Mandatory modules are marked.
Module
Select a module above.
Frame loop simulator
What EndDrawing() does each frame on desktop (when SUPPORT_CUSTOM_FRAME_CONTROL is off). Use Step or Play on mobile.
Layer diagram
YOUR CODE RAYLIB MODULES PLATFORM / GPU
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ main() │ InitWindow│ rcore.c │InitPlatform│ rcore_desktop_ │
│ while loop │───────────►│ CORE global │───────────►│ glfw.c │
│ Draw*() │ │ BeginDrawing │ │ GLFW window │
└─────────────┘ │ EndDrawing │ │ GL context │
│ └────────┬─────────┘ └────────┬────────┘
│ │ rlglInit / rlBegin │ glfwSwapBuffers
▼ ▼ ▼
DrawRectangle ──► rshapes ──► rlgl batch ──► glDrawElements ──► framebuffer
DrawTexture ──► rtextures ──► rlLoadTexture
DrawModel ──► rmodels ──► DrawMesh (VAO, bypasses batch)
PlaySound ──► raudio ──► miniaudio callback (separate thread)
One frame, end to end
Tap a step to jump to its explanation below.
0. Startup: InitWindow
InitWindow in rcore.c initializes CORE.Window and CORE.Input, calls platform InitPlatform() (e.g. GLFW window + GL context), then rlglInit(width, height) which creates the 1×1 default texture, default shader, and render batch.
Full detail: Frame lifecycle.
1. BeginDrawing resets the frame
BeginDrawing captures update-phase delta time and resets the modelview matrix, applying CORE.Window.screenScale for HiDPI displays. It does not clear the screen — call ClearBackground yourself.
2. Draw calls batch 2D geometry
Even solid rectangles bind a shared white texture and emit quads via rlBegin(RL_QUADS). Text draws each glyph with DrawTexturePro. State changes (new texture/shader) or buffer overflow trigger a batch flush mid-frame.
rshapes.c L738–795 — DrawRectanglePro
Full detail: rlgl & batching.
3. EndDrawing flushes the batch
The first line of EndDrawing is rlDrawRenderBatchActive(), which uploads accumulated vertices and draws with the active shader (default MVP + texture0).
4. Buffer swap and frame pacing
Unless custom frame control is enabled, EndDrawing calls SwapScreenBuffer() (platform), measures draw time, WaitTime() to hit SetTargetFPS, then PollInputEvents().
5. Input is edge-detected per frame
IsKeyPressed returns true when a key transitioned from up to down since the last poll. Window close is tracked in CORE.Window.shouldClose, updated from GLFW each frame.
Core objects
| Object | Role | Defined in |
|---|---|---|
CORE | Global window, input, timing state | rcore.c |
RLGL | Render batch, shaders, GL state | rlgl.h |
Image | CPU pixel buffer (RAM) | raylib.h |
Texture2D | GPU texture handle + metadata | raylib.h |
Font | Glyph atlas texture + metrics | raylib.h |
Mesh / Model | 3D geometry + materials on GPU | raylib.h |
Sound | Static audio buffer in mixer list | raudio.c |
Component pages
- Frame lifecycle — InitWindow, loop, EndDrawing, CloseWindow
- rlgl & batching — immediate mode, flush rules, interactive batch demo
- Platform backends — compile-time selection, GLFW boot
- Textures & images — LoadFileData → stb → rlLoadTexture
- Models & 3D — LoadModel, DrawMesh, BeginMode3D
- Audio system — miniaudio callback mixing
- Modules & build — config.h, Make, CMake, Zig
External references
- raysan5/raylib — source repository
- raylib cheatsheet
- raylib architecture wiki
- Live examples