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
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
DrawMesh (GL 3.3 / ES2)
rlEnableShader(material.shader.id)- Set uniforms:
colDiffuse,matModel,matView,matProjection,matNormal - Bind material texture maps to texture slots 0…N
- Enable VAO / bind VBOs per attribute location
rlDrawVertexArrayElementsor indexed draw
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.
Model data structures
Mesh— vertices, texcoords, normals, indices, bone weights, vaoId, vboId[]Material— shader + maps[] (diffuse, normal, roughness, …)Model— meshes[], materials[], meshMaterial[], skeleton, boneMatrices
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.