Skip to content

🎮 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:

  1. Set up Raylib for a C project.
  2. Create a window and a basic 3‑D camera.
  3. Draw simple primitives (cube, sphere, grid).
  4. 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)

# macOS
brew install raylib

# Ubuntu/Debian
sudo apt-get install libraylib-dev

Windows (vcpkg)

vcpkg install raylib

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

Simple Raylib 3D scene


🙏 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