diff --git a/examples/models/models_mesh_picking.c b/examples/models/models_mesh_picking.c index 0bf95dd10..f600aae84 100644 --- a/examples/models/models_mesh_picking.c +++ b/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)) { diff --git a/examples/models/models_obj_viewer.c b/examples/models/models_obj_viewer.c index 83c8f2f1c..3f43e1c89 100644 --- a/examples/models/models_obj_viewer.c +++ b/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]); } diff --git a/src/models.c b/src/models.c index 8b5fb472b..e30eb5472 100644 --- a/src/models.c +++ b/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 { diff --git a/src/raylib.h b/src/raylib.h index dd3ef86c9..04740def8 100644 --- a/src/raylib.h +++ b/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) diff --git a/src/rlgl.h b/src/rlgl.h index 797ea9c06..aa0c5e144 100644 --- a/src/rlgl.h +++ b/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.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); + 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 + 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); + 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;