Преглед на файлове

WARNING: Redesigned structs

 - Mesh, Shader, Material structs have been reviewed to minimize size when passed by value, all required code has been reviewed.
 - GetCollisionRayModel() reviewed to avoid pointer, not required because model is not modified inside the function
 - UnloadMesh() reviewed, pointer not required
 - CheckCollisionRay*() parameters name reviewed
Ray преди 6 години
родител
ревизия
3d5fa81bf2
променени са 5 файла, в които са добавени 108 реда и са изтрити 84 реда
  1. 1 1
      examples/models/models_mesh_picking.c
  2. 1 1
      examples/models/models_obj_viewer.c
  3. 60 41
      src/models.c
  4. 9 13
      src/raylib.h
  5. 37 28
      src/rlgl.h

+ 1 - 1
examples/models/models_mesh_picking.c

@@ -105,7 +105,7 @@ int main(void)
 
             // Check ray collision against model
             // NOTE: It considers model.transform matrix!
-            meshHitInfo = GetCollisionRayModel(ray, &tower);
+            meshHitInfo = GetCollisionRayModel(ray, tower);
 
             if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance))
             {

+ 1 - 1
examples/models/models_obj_viewer.c

@@ -54,7 +54,7 @@ int main(void)
             {
                 if (IsFileExtension(droppedFiles[0], ".obj"))
                 {
-                    for (int i = 0; i < model.meshCount; i++) UnloadMesh(&model.meshes[i]);
+                    for (int i = 0; i < model.meshCount; i++) UnloadMesh(model.meshes[i]);
                     model.meshes = LoadMeshes(droppedFiles[0], &model.meshCount);
                     bounds = MeshBoundingBox(model.meshes[0]);
                 }

+ 60 - 41
src/models.c

@@ -71,7 +71,7 @@
 //----------------------------------------------------------------------------------
 // Defines and Macros
 //----------------------------------------------------------------------------------
-// ...
+#define MAX_MESH_VBO    7               // Maximum number of vbo per mesh 
 
 //----------------------------------------------------------------------------------
 // Types and Structures Definition
@@ -702,7 +702,7 @@ Model LoadModelFromMesh(Mesh mesh)
 // Unload model from memory (RAM and/or VRAM)
 void UnloadModel(Model model)
 {
-    for (int i = 0; i < model.meshCount; i++) UnloadMesh(&model.meshes[i]);
+    for (int i = 0; i < model.meshCount; i++) UnloadMesh(model.meshes[i]);
     for (int i = 0; i < model.materialCount; i++) UnloadMaterial(model.materials[i]);
 
     RL_FREE(model.meshes);
@@ -729,9 +729,10 @@ Mesh *LoadMeshes(const char *fileName, int *meshCount)
 }
 
 // Unload mesh from memory (RAM and/or VRAM)
-void UnloadMesh(Mesh *mesh)
+void UnloadMesh(Mesh mesh)
 {
     rlUnloadMesh(mesh);
+    RL_FREE(mesh.vboId);
 }
 
 // Export mesh data to file
@@ -824,6 +825,7 @@ Material *LoadMaterials(const char *fileName, int *materialCount)
 Material LoadMaterialDefault(void)
 {
     Material material = { 0 };
+    material.maps = (MaterialMap *)RL_CALLOC(MAX_MATERIAL_MAPS*sizeof(MaterialMap), 1);
 
     material.shader = GetShaderDefault();
     material.maps[MAP_DIFFUSE].texture = GetTextureDefault();   // White texture (1x1 pixel)
@@ -847,6 +849,8 @@ void UnloadMaterial(Material material)
     {
         if (material.maps[i].texture.id != GetTextureDefault().id) rlDeleteTextures(material.maps[i].texture.id);
     }
+    
+    RL_FREE(material.maps);
 }
 
 // Set texture for a material map type (MAP_DIFFUSE, MAP_SPECULAR...)
@@ -1173,6 +1177,7 @@ bool IsModelAnimationValid(Model model, ModelAnimation anim)
 Mesh GenMeshPoly(int sides, float radius)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
     int vertexCount = sides*3;
 
     // Vertices definition
@@ -1235,6 +1240,7 @@ Mesh GenMeshPoly(int sides, float radius)
 Mesh GenMeshPlane(float width, float length, int resX, int resZ)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
 #define CUSTOM_MESH_GEN_PLANE
 #if defined(CUSTOM_MESH_GEN_PLANE)
@@ -1337,6 +1343,7 @@ Mesh GenMeshPlane(float width, float length, int resX, int resZ)
     mesh.vertices = (float *)RL_MALLOC(plane->ntriangles*3*3*sizeof(float));
     mesh.texcoords = (float *)RL_MALLOC(plane->ntriangles*3*2*sizeof(float));
     mesh.normals = (float *)RL_MALLOC(plane->ntriangles*3*3*sizeof(float));
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int));
 
     mesh.vertexCount = plane->ntriangles*3;
     mesh.triangleCount = plane->ntriangles;
@@ -1368,6 +1375,7 @@ Mesh GenMeshPlane(float width, float length, int resX, int resZ)
 Mesh GenMeshCube(float width, float height, float length)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
 #define CUSTOM_MESH_GEN_CUBE
 #if defined(CUSTOM_MESH_GEN_CUBE)
@@ -1533,6 +1541,7 @@ par_shapes_mesh* par_shapes_create_icosahedron();       // 20 sides polyhedron
 RLAPI Mesh GenMeshSphere(float radius, int rings, int slices)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
     par_shapes_mesh *sphere = par_shapes_create_parametric_sphere(slices, rings);
     par_shapes_scale(sphere, radius, radius, radius);
@@ -1571,6 +1580,7 @@ RLAPI Mesh GenMeshSphere(float radius, int rings, int slices)
 RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
     par_shapes_mesh *sphere = par_shapes_create_hemisphere(slices, rings);
     par_shapes_scale(sphere, radius, radius, radius);
@@ -1609,6 +1619,7 @@ RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices)
 Mesh GenMeshCylinder(float radius, float height, int slices)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
     // Instance a cylinder that sits on the Z=0 plane using the given tessellation
     // levels across the UV domain.  Think of "slices" like a number of pizza
@@ -1667,6 +1678,7 @@ Mesh GenMeshCylinder(float radius, float height, int slices)
 Mesh GenMeshTorus(float radius, float size, int radSeg, int sides)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
     if (radius > 1.0f) radius = 1.0f;
     else if (radius < 0.1f) radius = 0.1f;
@@ -1709,6 +1721,7 @@ Mesh GenMeshTorus(float radius, float size, int radSeg, int sides)
 Mesh GenMeshKnot(float radius, float size, int radSeg, int sides)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
     if (radius > 3.0f) radius = 3.0f;
     else if (radius < 0.5f) radius = 0.5f;
@@ -1860,13 +1873,14 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
 Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
 {
     Mesh mesh = { 0 };
+    mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
     Color *cubicmapPixels = GetImageData(cubicmap);
 
     int mapWidth = cubicmap.width;
     int mapHeight = cubicmap.height;
 
-    // NOTE: Max possible number of triangles numCubes * (12 triangles by cube)
+    // NOTE: Max possible number of triangles numCubes*(12 triangles by cube)
     int maxTriangles = cubicmap.width*cubicmap.height*12;
 
     int vCounter = 0;       // Used to count vertices
@@ -2478,11 +2492,11 @@ bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, floa
     // Simple way to check for collision, just checking distance between two points
     // Unfortunately, sqrtf() is a costly operation, so we avoid it with following solution
     /*
-    float dx = centerA.x - centerB.x;      // X distance between centers
-    float dy = centerA.y - centerB.y;      // Y distance between centers
-    float dz = centerA.z - centerB.z;      // Z distance between centers
+    float dx = centerA.x - centerB.x;      // X distance between centers    
+    float dy = centerA.y - centerB.y;      // Y distance between centers    
+    float dz = centerA.z - centerB.z;      // Z distance between centers    
 
-    float distance = sqrtf(dx*dx + dy*dy + dz*dz);  // Distance between centers
+    float distance = sqrtf(dx*dx + dy*dy + dz*dz);  // Distance between centers    
 
     if (distance <= (radiusA + radiusB)) collision = true;
     */
@@ -2510,35 +2524,35 @@ bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2)
 }
 
 // Detect collision between box and sphere
-bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere)
+bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius)
 {
     bool collision = false;
 
     float dmin = 0;
 
-    if (centerSphere.x < box.min.x) dmin += powf(centerSphere.x - box.min.x, 2);
-    else if (centerSphere.x > box.max.x) dmin += powf(centerSphere.x - box.max.x, 2);
+    if (center.x < box.min.x) dmin += powf(center.x - box.min.x, 2);
+    else if (center.x > box.max.x) dmin += powf(center.x - box.max.x, 2);
 
-    if (centerSphere.y < box.min.y) dmin += powf(centerSphere.y - box.min.y, 2);
-    else if (centerSphere.y > box.max.y) dmin += powf(centerSphere.y - box.max.y, 2);
+    if (center.y < box.min.y) dmin += powf(center.y - box.min.y, 2);
+    else if (center.y > box.max.y) dmin += powf(center.y - box.max.y, 2);
 
-    if (centerSphere.z < box.min.z) dmin += powf(centerSphere.z - box.min.z, 2);
-    else if (centerSphere.z > box.max.z) dmin += powf(centerSphere.z - box.max.z, 2);
+    if (center.z < box.min.z) dmin += powf(center.z - box.min.z, 2);
+    else if (center.z > box.max.z) dmin += powf(center.z - box.max.z, 2);
 
-    if (dmin <= (radiusSphere*radiusSphere)) collision = true;
+    if (dmin <= (radius*radius)) collision = true;
 
     return collision;
 }
 
 // Detect collision between ray and sphere
-bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius)
+bool CheckCollisionRaySphere(Ray ray, Vector3 center, float radius)
 {
     bool collision = false;
 
-    Vector3 raySpherePos = Vector3Subtract(spherePosition, ray.position);
+    Vector3 raySpherePos = Vector3Subtract(center, ray.position);
     float distance = Vector3Length(raySpherePos);
     float vector = Vector3DotProduct(raySpherePos, ray.direction);
-    float d = sphereRadius*sphereRadius - (distance*distance - vector*vector);
+    float d = radius*radius - (distance*distance - vector*vector);
 
     if (d >= 0.0f) collision = true;
 
@@ -2546,21 +2560,21 @@ bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius
 }
 
 // Detect collision between ray and sphere with extended parameters and collision point detection
-bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint)
+bool CheckCollisionRaySphereEx(Ray ray, Vector3 center, float radius, Vector3 *collisionPoint)
 {
     bool collision = false;
 
-    Vector3 raySpherePos = Vector3Subtract(spherePosition, ray.position);
+    Vector3 raySpherePos = Vector3Subtract(center, ray.position);
     float distance = Vector3Length(raySpherePos);
     float vector = Vector3DotProduct(raySpherePos, ray.direction);
-    float d = sphereRadius*sphereRadius - (distance*distance - vector*vector);
+    float d = radius*radius - (distance*distance - vector*vector);
 
     if (d >= 0.0f) collision = true;
 
     // Check if ray origin is inside the sphere to calculate the correct collision point
     float collisionDistance = 0;
 
-    if (distance < sphereRadius) collisionDistance = vector + sqrtf(d);
+    if (distance < radius) collisionDistance = vector + sqrtf(d);
     else collisionDistance = vector - sqrtf(d);
 
     // Calculate collision point
@@ -2594,29 +2608,29 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box)
 }
 
 // Get collision info between ray and model
-RayHitInfo GetCollisionRayModel(Ray ray, Model *model)
+RayHitInfo GetCollisionRayModel(Ray ray, Model model)
 {
     RayHitInfo result = { 0 };
 
-    for (int m = 0; m < model->meshCount; m++)
+    for (int m = 0; m < model.meshCount; m++)
     {
         // Check if meshhas vertex data on CPU for testing
-        if (model->meshes[m].vertices != NULL)
+        if (model.meshes[m].vertices != NULL)
         {
             // model->mesh.triangleCount may not be set, vertexCount is more reliable
-            int triangleCount = model->meshes[m].vertexCount/3;
+            int triangleCount = model.meshes[m].vertexCount/3;
 
             // Test against all triangles in mesh
             for (int i = 0; i < triangleCount; i++)
             {
                 Vector3 a, b, c;
-                Vector3 *vertdata = (Vector3 *)model->meshes[m].vertices;
+                Vector3 *vertdata = (Vector3 *)model.meshes[m].vertices;
 
-                if (model->meshes[m].indices)
+                if (model.meshes[m].indices)
                 {
-                    a = vertdata[model->meshes[m].indices[i*3 + 0]];
-                    b = vertdata[model->meshes[m].indices[i*3 + 1]];
-                    c = vertdata[model->meshes[m].indices[i*3 + 2]];
+                    a = vertdata[model.meshes[m].indices[i*3 + 0]];
+                    b = vertdata[model.meshes[m].indices[i*3 + 1]];
+                    c = vertdata[model.meshes[m].indices[i*3 + 2]];
                 }
                 else
                 {
@@ -2625,9 +2639,9 @@ RayHitInfo GetCollisionRayModel(Ray ray, Model *model)
                     c = vertdata[i*3 + 2];
                 }
 
-                a = Vector3Transform(a, model->transform);
-                b = Vector3Transform(b, model->transform);
-                c = Vector3Transform(c, model->transform);
+                a = Vector3Transform(a, model.transform);
+                b = Vector3Transform(b, model.transform);
+                c = Vector3Transform(c, model.transform);
 
                 RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, a, b, c);
 
@@ -2800,6 +2814,7 @@ static Model LoadOBJ(const char *fileName)
             mesh.vertices = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
             mesh.texcoords = (float *)RL_MALLOC(mesh.vertexCount*2*sizeof(float));
             mesh.normals = (float *)RL_MALLOC(mesh.vertexCount*3*sizeof(float));
+            mesh.vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
             int vCount = 0;
             int vtCount = 0;
@@ -3068,6 +3083,8 @@ static Model LoadIQM(const char *fileName)
         // NOTE: Animated vertex should be re-uploaded to GPU (if not using GPU skinning)
         model.meshes[i].animVertices = RL_MALLOC(sizeof(float)*model.meshes[i].vertexCount*3);
         model.meshes[i].animNormals = RL_MALLOC(sizeof(float)*model.meshes[i].vertexCount*3);
+        
+        model.meshes[i].vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
     }
 
     // Triangles data processing
@@ -3386,8 +3403,10 @@ static Model LoadGLTF(const char *fileName)
         model.meshCount = primitivesCount;
         model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh));
         model.materialCount = data->materials_count + 1;
-        model.materials = RL_MALLOC(model.materialCount * sizeof(Material));
-        model.meshMaterial = RL_MALLOC(model.meshCount * sizeof(int)); 
+        model.materials = RL_MALLOC(model.materialCount*sizeof(Material));
+        model.meshMaterial = RL_MALLOC(model.meshCount*sizeof(int));
+        
+        for (int i = 0; i < model.meshCount; i++) model.meshes[i].vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VBO*sizeof(unsigned int), 1);
 
         for (int i = 0; i < model.materialCount - 1; i++)
         {
@@ -3397,10 +3416,10 @@ static Model LoadGLTF(const char *fileName)
             
             if (data->materials[i].pbr_metallic_roughness.base_color_factor)
             {
-                tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0] * 255.99f);
-                tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1] * 255.99f);
-                tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2] * 255.99f);
-                tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3] * 255.99f);
+                tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0]*255.99f);
+                tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1]*255.99f);
+                tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2]*255.99f);
+                tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3]*255.99f);
             }
             else
             {

+ 9 - 13
src/raylib.h

@@ -96,10 +96,6 @@
 
 #define MAX_TOUCH_POINTS        10      // Maximum number of touch points supported
 
-// Shader and material limits
-#define MAX_SHADER_LOCATIONS    32      // Maximum number of predefined locations stored in shader struct
-#define MAX_MATERIAL_MAPS       12      // Maximum number of texture maps stored in shader struct
-
 // Allow custom memory allocators
 #ifndef RL_MALLOC
     #define RL_MALLOC(sz)       malloc(sz)
@@ -322,13 +318,13 @@ typedef struct Mesh {
 
     // OpenGL identifiers
     unsigned int vaoId;     // OpenGL Vertex Array Object id
-    unsigned int vboId[7];  // OpenGL Vertex Buffer Objects id (default vertex data)
+    unsigned int *vboId;    // OpenGL Vertex Buffer Objects id (default vertex data)
 } Mesh;
 
 // Shader type (generic)
 typedef struct Shader {
-    unsigned int id;                // Shader program id
-    int locs[MAX_SHADER_LOCATIONS]; // Shader locations array
+    unsigned int id;        // Shader program id
+    int *locs;              // Shader locations array (MAX_SHADER_LOCATIONS)
 } Shader;
 
 // Material texture map
@@ -341,7 +337,7 @@ typedef struct MaterialMap {
 // Material type (generic)
 typedef struct Material {
     Shader shader;          // Material shader
-    MaterialMap maps[MAX_MATERIAL_MAPS]; // Material maps
+    MaterialMap *maps;      // Material maps array (MAX_MATERIAL_MAPS)
     float *params;          // Material generic parameters (if required)
 } Material;
 
@@ -1240,7 +1236,7 @@ RLAPI void UnloadModel(Model model);
 // Mesh loading/unloading functions
 RLAPI Mesh *LoadMeshes(const char *fileName, int *meshCount);                                           // Load meshes from model file
 RLAPI void ExportMesh(Mesh mesh, const char *fileName);                                                 // Export mesh data to file
-RLAPI void UnloadMesh(Mesh *mesh);                                                                      // Unload mesh from memory (RAM and/or VRAM)
+RLAPI void UnloadMesh(Mesh mesh);                                                                       // Unload mesh from memory (RAM and/or VRAM)
 
 // Material loading/unloading functions
 RLAPI Material *LoadMaterials(const char *fileName, int *materialCount);                                // Load materials from model file
@@ -1284,11 +1280,11 @@ RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRe
 // Collision detection functions
 RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB);       // Detect collision between two spheres
 RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2);                                     // Detect collision between two bounding boxes
-RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere);          // Detect collision between box and sphere
-RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius);                // Detect collision between ray and sphere
-RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point
+RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius);                      // Detect collision between box and sphere
+RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 center, float radius);                              // Detect collision between ray and sphere
+RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 center, float radius, Vector3 *collisionPoint);   // Detect collision between ray and sphere, returns collision point
 RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box);                                              // Detect collision between ray and box
-RLAPI RayHitInfo GetCollisionRayModel(Ray ray, Model *model);                                           // Get collision info between ray and model
+RLAPI RayHitInfo GetCollisionRayModel(Ray ray, Model model);                                            // Get collision info between ray and model
 RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3);                  // Get collision info between ray and triangle
 RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight);                                    // Get collision info between ray and ground plane (Y-normal plane)
 

+ 37 - 28
src/rlgl.h

@@ -131,6 +131,10 @@
 #define MAX_MATRIX_STACK_SIZE               32      // Max size of Matrix stack
 #define MAX_DRAWCALL_REGISTERED            256      // Max draws by state changes (mode, texture)
 
+// Shader and material limits
+#define MAX_SHADER_LOCATIONS                32      // Maximum number of predefined locations stored in shader struct
+#define MAX_MATERIAL_MAPS                   12      // Maximum number of texture maps stored in shader struct
+
 // Texture parameters (equivalent to OpenGL defines)
 #define RL_TEXTURE_WRAP_S               0x2802      // GL_TEXTURE_WRAP_S
 #define RL_TEXTURE_WRAP_T               0x2803      // GL_TEXTURE_WRAP_T
@@ -228,7 +232,7 @@ typedef unsigned char byte;
 
         // OpenGL identifiers
         unsigned int vaoId;     // OpenGL Vertex Array Object id
-        unsigned int vboId[7];  // OpenGL Vertex Buffer Objects id (7 types of vertex data)
+        unsigned int *vboId;    // OpenGL Vertex Buffer Objects id (7 types of vertex data)
     } Mesh;
 
     // Shader and material limits
@@ -237,8 +241,8 @@ typedef unsigned char byte;
 
     // Shader type (generic)
     typedef struct Shader {
-        unsigned int id;                // Shader program id
-        int locs[MAX_SHADER_LOCATIONS]; // Shader locations array
+        unsigned int id;        // Shader program id
+        int *locs;              // Shader locations array (MAX_SHADER_LOCATIONS)
     } Shader;
 
     // Material texture map
@@ -251,7 +255,7 @@ typedef unsigned char byte;
     // Material type (generic)
     typedef struct Material {
         Shader shader;          // Material shader
-        MaterialMap maps[MAX_MATERIAL_MAPS]; // Material maps
+        MaterialMap *maps;      // Material maps (MAX_MATERIAL_MAPS)
         float *params;          // Material generic parameters (if required)
     } Material;
 
@@ -499,7 +503,7 @@ RLAPI bool rlRenderTextureComplete(RenderTexture target);                 // Ver
 RLAPI void rlLoadMesh(Mesh *mesh, bool dynamic);                          // Upload vertex data into GPU and provided VAO/VBO ids
 RLAPI void rlUpdateMesh(Mesh mesh, int buffer, int numVertex);            // Update vertex data on GPU (upload new data to one buffer)
 RLAPI void rlDrawMesh(Mesh mesh, Material material, Matrix transform);    // Draw a 3d mesh with material and transform
-RLAPI void rlUnloadMesh(Mesh *mesh);                                      // Unload mesh data from CPU and GPU
+RLAPI void rlUnloadMesh(Mesh mesh);                                       // Unload mesh data from CPU and GPU
 
 // NOTE: There is a set of shader related functions that are available to end user,
 // to avoid creating function wrappers through core module, they have been directly declared in raylib.h
@@ -2757,30 +2761,30 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
 }
 
 // Unload mesh data from CPU and GPU
-void rlUnloadMesh(Mesh *mesh)
+void rlUnloadMesh(Mesh mesh)
 {
-    RL_FREE(mesh->vertices);
-    RL_FREE(mesh->texcoords);
-    RL_FREE(mesh->normals);
-    RL_FREE(mesh->colors);
-    RL_FREE(mesh->tangents);
-    RL_FREE(mesh->texcoords2);
-    RL_FREE(mesh->indices);
-
-    RL_FREE(mesh->animVertices);
-    RL_FREE(mesh->animNormals);
-    RL_FREE(mesh->boneWeights);
-    RL_FREE(mesh->boneIds);
-
-    rlDeleteBuffers(mesh->vboId[0]);   // vertex
-    rlDeleteBuffers(mesh->vboId[1]);   // texcoords
-    rlDeleteBuffers(mesh->vboId[2]);   // normals
-    rlDeleteBuffers(mesh->vboId[3]);   // colors
-    rlDeleteBuffers(mesh->vboId[4]);   // tangents
-    rlDeleteBuffers(mesh->vboId[5]);   // texcoords2
-    rlDeleteBuffers(mesh->vboId[6]);   // indices
-
-    rlDeleteVertexArrays(mesh->vaoId);
+    RL_FREE(mesh.vertices);
+    RL_FREE(mesh.texcoords);
+    RL_FREE(mesh.normals);
+    RL_FREE(mesh.colors);
+    RL_FREE(mesh.tangents);
+    RL_FREE(mesh.texcoords2);
+    RL_FREE(mesh.indices);
+
+    RL_FREE(mesh.animVertices);
+    RL_FREE(mesh.animNormals);
+    RL_FREE(mesh.boneWeights);
+    RL_FREE(mesh.boneIds);
+
+    rlDeleteBuffers(mesh.vboId[0]);   // vertex
+    rlDeleteBuffers(mesh.vboId[1]);   // texcoords
+    rlDeleteBuffers(mesh.vboId[2]);   // normals
+    rlDeleteBuffers(mesh.vboId[3]);   // colors
+    rlDeleteBuffers(mesh.vboId[4]);   // tangents
+    rlDeleteBuffers(mesh.vboId[5]);   // texcoords2
+    rlDeleteBuffers(mesh.vboId[6]);   // indices
+
+    rlDeleteVertexArrays(mesh.vaoId);
 }
 
 // Read screen pixel data (color buffer)
@@ -2953,6 +2957,7 @@ char *LoadText(const char *fileName)
 Shader LoadShader(const char *vsFileName, const char *fsFileName)
 {
     Shader shader = { 0 };
+    shader.locs = (int *)RL_CALLOC(MAX_SHADER_LOCATIONS*sizeof(int), 1);
 
     char *vShaderStr = NULL;
     char *fShaderStr = NULL;
@@ -2973,6 +2978,7 @@ Shader LoadShader(const char *vsFileName, const char *fsFileName)
 Shader LoadShaderCode(char *vsCode, char *fsCode)
 {
     Shader shader = { 0 };
+    shader.locs = (int *)RL_CALLOC(MAX_SHADER_LOCATIONS*sizeof(int), 1);
 
     // NOTE: All locations must be reseted to -1 (no location)
     for (int i = 0; i < MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1;
@@ -3038,6 +3044,8 @@ void UnloadShader(Shader shader)
         rlDeleteShader(shader.id);
         TraceLog(LOG_INFO, "[SHDR ID %i] Unloaded shader program data", shader.id);
     }
+    
+    RL_FREE(shader.locs);
 }
 
 // Begin custom shader mode
@@ -3861,6 +3869,7 @@ static unsigned int LoadShaderProgram(unsigned int vShaderId, unsigned int fShad
 static Shader LoadShaderDefault(void)
 {
     Shader shader = { 0 };
+    shader.locs = (int *)RL_CALLOC(MAX_SHADER_LOCATIONS*sizeof(int), 1);
 
     // NOTE: All locations must be reseted to -1 (no location)
     for (int i = 0; i < MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1;