🎮 Raylib 3D Introduction
Raylib is a simple, open‑source C library that lets you create games and graphical demos with just a few lines of code. While many tutorials focus on 2‑D, the same API also provides a clean, beginner‑friendly way to work with 3‑D graphics.
In this post we’ll:
- Set up Raylib for a C project.
- Create a window and a basic 3‑D camera.
- Draw simple primitives (cube, sphere, grid).
- Show how to load a model and texture.
Note
All code examples compile with the latest stable Raylib (≥5.0). If you’re on Windows, macOS, or Linux the same source works – only the build command differs slightly.
📦 Installing Raylib
macOS & Linux (Homebrew / apt)
Windows (vcpkg)
Tip – When using the bundled example folder from the Raylib repo, you can compile directly with
make(Linux/macOS) or the provided Visual Studio solution (Windows).
🛠️ Minimal 3‑D Boilerplate
Create a file called main.c:
#include "raylib.h"
int main(void)
{
// -------------------------------------------------------------------------
// 1️⃣ Initialise the window and a 3‑D camera
// -------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 600;
InitWindow(screenWidth, screenHeight, "Raylib 3D Introduction");
SetTargetFPS(60);
Camera3D camera = {
.position = (Vector3){ 4.0f, 2.0f, 4.0f }, // Where the camera is
.target = (Vector3){ 0.0f, 0.0f, 0.0f }, // What it looks at
.up = (Vector3){ 0.0f, 1.0f, 0.0f }, // Up direction
.fovy = 45.0f, // Field of view
.type = CAMERA_PERSPECTIVE
};
// -------------------------------------------------------------------------
// 2️⃣ Main game loop
// -------------------------------------------------------------------------
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// ---- Update camera (mouse orbit) ------------------------------------
UpdateCamera(&camera, CAMERA_ORBITAL);
// ---- Draw ------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
// Draw a simple grid (ground)
DrawGrid(10, 1.0f);
// Draw a rotating cube
static float rotation = 0.0f;
rotation += 0.5f; // degrees per frame
DrawCube((Vector3){0.0f, 1.0f, 0.0f}, 2.0f, 2.0f, 2.0f,
(Color){255, 100, 100, 255});
DrawCubeWires((Vector3){0.0f, 1.0f, 0.0f}, 2.0f, 2.0f, 2.0f,
(Color){0, 0, 0, 255});
DrawCubeWires((Vector3){0.0f, 1.0f, 0.0f}, 2.0f, 2.0f, 2.0f,
(Color){0, 0, 0, 255});
DrawCube((Vector3){-2.5f, 0.5f, 0.0f}, 1.0f, 1.0f, 1.0f,
BLUE);
DrawSphere((Vector3){2.5f, 0.5f, 0.0f}, 0.5f, GREEN);
EndMode3D();
// 2‑D UI overlay
DrawFPS(10, 10);
DrawText("Use mouse + right‑click to rotate the camera", 10, 40, 10, DARKGRAY);
EndDrawing();
}
// -------------------------------------------------------------------------
// 3️⃣ Clean up
// -------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
return 0;
}
How it works
| Section | What it does |
|---|---|
| InitWindow | Creates the OS window and OpenGL context. |
| Camera3D | Defines a perspective camera. The UpdateCamera helper gives us orbital controls out‑of‑the‑box. |
| BeginMode3D / EndMode3D | Anything drawn between them uses the 3‑D projection. |
| DrawGrid / DrawCube / DrawSphere | Raylib’s built‑in primitive helpers. |
| DrawFPS | Shows a small FPS counter – handy while testing. |
Compile the program:
# Linux/macOS
gcc -o ray3d main.c -lraylib -lm -lpthread -ldl -lrt -lX11
# Windows (vcpkg)
cl /EHsc main.c /Ipath\to\vcpkg\installed\x64-windows\include \
/link /LIBPATH:path\to\vcpkg\installed\x64-windows\lib raylib.lib
Run ./ray3d (or ray3d.exe) – you should see a rotating cube, a sphere, and a grid you can orbit around with the mouse.
📂 Loading Models & Textures
Raylib can import many formats (OBJ, GLTF, IQM). Here’s a quick example that loads a GLTF model and applies a texture:
// ... (initialisation code from above)
Model shipModel = LoadModel("resources/models/space_ship.glb");
Texture2D shipTex = LoadTexture("resources/textures/ship_diffuse.png");
shipModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = shipTex;
// In the drawing section (inside BeginMode3D):
DrawModel(shipModel, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
Tip – Keep assets in a
resources/folder inside your project and add it to the Git repo. The built‑in blog plugin copies assets automatically when you place images inside the same folder as the post (e.g.,docs/blog/posts/your‑post/image.png).
🎨 Why Raylib for 3‑D?
- Zero‑dependency on heavy engines – just a single static library.
- Immediate‑mode style: you describe what to draw each frame, no scene graph required.
- Cross‑platform: works on desktop, Raspberry Pi, and even the web via WebAssembly (
emscripten). - Extensible: you can plug in your own shaders, physics, or networking code without fighting an engine’s abstraction.
🚀 Next Steps
| Goal | Resource |
|---|---|
| Learn about custom shaders | https://www.raylib.com/cheatsheet/cheatsheet.html#shaders |
| Add physics with raylib‑physics (wrapper around Jolt) | https://github.com/raysan5/raylib/tree/master/examples/physics |
| Deploy to the Web (WebGL) | emcc -o ray3d.html main.c -sUSE_GLFW=3 -sUSE_WEBGL2=1 -lraylib |
| Build a first‑person controller | Example: examples/models/models_first_person in the Raylib repo |
📸 Screenshot
🙏 Acknowledgements
- Raylib – created by Romain “ray” Girault and the amazing open‑source community.
- Material for MkDocs – for the clean blog layout that lets us share these tutorials
