Models and 3D rendering

rmodels.c loads geometry into Mesh CPU arrays, uploads to VAO/VBO via UploadMesh, and draws with per-material shaders through DrawMesh. The 2D render batch is flushed before entering 3D mode.

LoadModel flow

LoadModel("scene.gltf")
  ├─ extension dispatch:
  │     .obj  → LoadOBJ (tinyobj_loader_c)
  │     .gltf → LoadGLTF (cgltf)
  │     .iqm  → LoadIQM
  │     .m3d  → LoadM3D
  │
  ├─ model.transform = MatrixIdentity()
  ├─ for each mesh: UploadMesh(&mesh, false)  → GPU VAO/VBO
  └─ if no materials: create default white material + default shader

rmodels.c L1102–1137 — LoadModel

Draw path in one frame

BeginMode3D(camera)          // flush batch, set projection + view, depth on
DrawModel(model, pos, scale, tint)
  └─ DrawModelEx
       ├─ build scale × rotate × translate matrix
       ├─ model.transform = model.transform × matTransform  ⚠ mutates model
       └─ for each mesh:
            tint material diffuse color
            upload bone matrices if skeletal
            DrawMesh(mesh, material, model.transform)
EndMode3D()                  // flush, restore 2D ortho, depth off

rmodels.c — DrawModelEx

DrawMesh (GL 3.3 / ES2)
  1. rlEnableShader(material.shader.id)
  2. Set uniforms: colDiffuse, matModel, matView, matProjection, matNormal
  3. Bind material texture maps to texture slots 0…N
  4. Enable VAO / bind VBOs per attribute location
  5. rlDrawVertexArrayElements or indexed draw

rmodels.c L1478+ — DrawMesh

BeginMode3D matrix setup

Pushes projection matrix, sets frustum or ortho from camera.fovy and aspect ratio (currentFbo.width/height), loads view matrix from MatrixLookAt, enables depth test.

rcore.c — BeginMode3D / EndMode3D

Model data structures
  • Mesh — vertices, texcoords, normals, indices, bone weights, vaoId, vboId[]
  • Material — shader + maps[] (diffuse, normal, roughness, …)
  • Model — meshes[], materials[], meshMaterial[], skeleton, boneMatrices

raylib.h — Mesh, Material, Model

Skeletal animation

UpdateModelAnimation computes bone transforms; DrawModelEx uploads boneMatrices to shader when SHADER_LOC_MATRIX_BONETRANSFORMS is available. GPU skinning off by default (SUPPORT_GPU_SKINNING 0) — CPU skinning via mesh.animVertices.

Billboards

DrawBillboardPro builds a camera-facing quad in 3D space and draws via textured vertices (still uses rl immediate path, not mesh VAO).

Caution: DrawModelEx multiplies into model.transform each call. Reset with model.transform = MatrixIdentity() if you reuse the same model at multiple positions per frame.