From 696a73342ca646544d5fc4eab29f8c03b157ac31 Mon Sep 17 00:00:00 2001 From: devdad Date: Thu, 5 Dec 2024 11:58:58 +0100 Subject: [PATCH] Add LoadModelEx and UploadModel functions To enable custom model and mesh batching in projects that use the official raylib and instancing, it is essential to have control over whether or not meshes are automatically uploaded to the GPU. In my opinion, this is the cleanest solution for achieving that flexibility. New functions added: // Load model from files (mesh and material) without automatically uploading vertex data to the GPU Model LoadModelEx(const char *fileName, bool upload) // Upload model data to the GPU (RAM and/or VRAM) void UploadModel(const Model *model, bool dynamic) The existing LoadModel function now calls LoadModelEx with upload = true. Additionally, fixed LoadOBJ to match the behavior of other load functions by not automatically uploading meshes. --- src/raylib.h | 2 ++ src/rmodels.c | 30 +++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 641bd10e0b4f..b1c17857027d 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1552,8 +1552,10 @@ RLAPI void DrawGrid(int slices, float spacing); // Model management functions RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials) +RLAPI Model LoadModelEx(const char *fileName, bool upload); // Load model from files (meshes and materials) with option to auto uploading meshes to GPU or not RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material) RLAPI bool IsModelValid(Model model); // Check if a model is valid (loaded in GPU, VAO/VBOs) +RLAPI void UploadModel(const Model *model, bool dynamic); // Upload model data to GPU (VRAM) RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM) RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes) diff --git a/src/rmodels.c b/src/rmodels.c index 24f4a4fc9fc6..d8f3ecada855 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1088,6 +1088,12 @@ void DrawGrid(int slices, float spacing) // Load model from files (mesh and material) Model LoadModel(const char *fileName) +{ + return LoadModelEx(fileName, true); +} + +// Load model from files (mesh and material) without Uploading Vertex data to GPU +Model LoadModelEx(const char *fileName, bool upload) { Model model = { 0 }; @@ -1110,12 +1116,15 @@ Model LoadModel(const char *fileName) // Make sure model transform is set to identity matrix! model.transform = MatrixIdentity(); - if ((model.meshCount != 0) && (model.meshes != NULL)) + if(upload) { - // Upload vertex data to GPU (static meshes) - for (int i = 0; i < model.meshCount; i++) UploadMesh(&model.meshes[i], false); + if ((model.meshCount != 0) && (model.meshes != NULL)) + { + // Upload vertex data to GPU (static meshes) + for (int i = 0; i < model.meshCount; i++) UploadMesh(&model.meshes[i], false); + } + else TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load model mesh(es) data", fileName); } - else TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load model mesh(es) data", fileName); if (model.materialCount == 0) { @@ -1187,6 +1196,17 @@ bool IsModelValid(Model model) return result; } +// Upload model data to GPU (RAM and/or VRAM) +void UploadModel(const Model *model, bool dynamic) +{ + if ((model->meshCount != 0) && (model->meshes != NULL)) + { + // Upload vertex data to GPU (static meshes) + for (int i = 0; i < model->meshCount; i++) UploadMesh(&model->meshes[i], false); + } + else TRACELOG(LOG_WARNING, "Model: [%s] Failed to load model mesh(es) data"); +} + // Unload model (meshes/materials) from memory (RAM and/or VRAM) // NOTE: This function takes care of all model elements, for a detailed control // over them, use UnloadMesh() and UnloadMaterial() @@ -4407,7 +4427,7 @@ static Model LoadOBJ(const char *fileName) tinyobj_shapes_free(objShapes, objShapeCount); tinyobj_materials_free(objMaterials, objMaterialCount); - for (int i = 0; i < model.meshCount; i++) UploadMesh(model.meshes + i, true); + // Restore current working directory if (CHDIR(currentDir) != 0)