diff --git a/build.zig b/build.zig
index 77681e0e6..0b086dc4d 100644
--- a/build.zig
+++ b/build.zig
@@ -256,6 +256,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.root_module.linkSystemLibrary("GLESv2", .{});
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
}
+ raylib.root_module.linkSystemLibrary("EGL", .{});
setDesktopPlatform(raylib, .android);
} else {
diff --git a/parser/output/raylib_api.json b/parser/output/raylib_api.json
index 567f9d980..e73e18fba 100644
--- a/parser/output/raylib_api.json
+++ b/parser/output/raylib_api.json
@@ -3139,7 +3139,7 @@
"name": "fileName"
},
{
- "type": "char *",
+ "type": "const char *",
"name": "text"
}
]
@@ -4409,7 +4409,7 @@
"name": "fileName"
},
{
- "type": "char *",
+ "type": "const char *",
"name": "text"
}
]
@@ -4707,7 +4707,7 @@
"returnType": "unsigned char *",
"params": [
{
- "type": "const unsigned char *",
+ "type": "const char *",
"name": "data"
},
{
diff --git a/parser/output/raylib_api.lua b/parser/output/raylib_api.lua
index 75c328da6..fa92cdea7 100644
--- a/parser/output/raylib_api.lua
+++ b/parser/output/raylib_api.lua
@@ -3108,7 +3108,7 @@ return {
returnType = "bool",
params = {
{type = "const char *", name = "fileName"},
- {type = "char *", name = "text"}
+ {type = "const char *", name = "text"}
}
},
{
@@ -4006,7 +4006,7 @@ return {
returnType = "bool",
params = {
{type = "const char *", name = "fileName"},
- {type = "char *", name = "text"}
+ {type = "const char *", name = "text"}
}
},
{
@@ -4211,7 +4211,7 @@ return {
description = "Decode Base64 string data, memory must be MemFree()",
returnType = "unsigned char *",
params = {
- {type = "const unsigned char *", name = "data"},
+ {type = "const char *", name = "data"},
{type = "int *", name = "outputSize"}
}
},
diff --git a/parser/output/raylib_api.txt b/parser/output/raylib_api.txt
index 0b0bf86c1..4aa682d78 100644
--- a/parser/output/raylib_api.txt
+++ b/parser/output/raylib_api.txt
@@ -985,7 +985,7 @@ Callback 005: SaveFileTextCallback() (2 input parameters)
Return type: bool
Description: FileIO: Save text data
Param[1]: fileName (type: const char *)
- Param[2]: text (type: char *)
+ Param[2]: text (type: const char *)
Callback 006: AudioCallback() (2 input parameters)
Name: AudioCallback
Return type: void
@@ -1656,7 +1656,7 @@ Function 123: SaveFileText() (2 input parameters)
Return type: bool
Description: Save text data to file (write), string must be '\0' terminated, returns true on success
Param[1]: fileName (type: const char *)
- Param[2]: text (type: char *)
+ Param[2]: text (type: const char *)
Function 124: FileExists() (1 input parameters)
Name: FileExists
Return type: bool
@@ -1795,7 +1795,7 @@ Function 149: DecodeDataBase64() (2 input parameters)
Name: DecodeDataBase64
Return type: unsigned char *
Description: Decode Base64 string data, memory must be MemFree()
- Param[1]: data (type: const unsigned char *)
+ Param[1]: data (type: const char *)
Param[2]: outputSize (type: int *)
Function 150: ComputeCRC32() (2 input parameters)
Name: ComputeCRC32
diff --git a/parser/output/raylib_api.xml b/parser/output/raylib_api.xml
index ed6880dec..c88a20bd1 100644
--- a/parser/output/raylib_api.xml
+++ b/parser/output/raylib_api.xml
@@ -672,7 +672,7 @@
-
+
@@ -1046,7 +1046,7 @@
-
+
@@ -1129,7 +1129,7 @@
-
+
diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c
index 94c780ca3..675d09f22 100644
--- a/src/platforms/rcore_desktop_glfw.c
+++ b/src/platforms/rcore_desktop_glfw.c
@@ -1752,6 +1752,10 @@ static void ErrorCallback(int error, const char *description)
// NOTE: Window resizing not enabled by default, use SetConfigFlags()
static void WindowSizeCallback(GLFWwindow *window, int width, int height)
{
+ // WARNING: On window minimization, callback is called,
+ // but we don't want to change internal screen values, it breaks things
+ if ((width == 0) || (height == 0)) return;
+
// Reset viewport and projection matrix for new size
SetupViewport(width, height);
diff --git a/src/raylib.h b/src/raylib.h
index fc949a02d..0cffa4272 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -954,7 +954,7 @@ typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args);
typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data
typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data
typedef char *(*LoadFileTextCallback)(const char *fileName); // FileIO: Load text data
-typedef bool (*SaveFileTextCallback)(const char *fileName, char *text); // FileIO: Save text data
+typedef bool (*SaveFileTextCallback)(const char *fileName, const char *text); // FileIO: Save text data
//------------------------------------------------------------------------------------
// Global Variables Definition
@@ -1123,7 +1123,7 @@ RLAPI bool SaveFileData(const char *fileName, void *data, int dataSize); // Save
RLAPI bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); // Export data to code (.h), returns true on success
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText()
-RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
+RLAPI bool SaveFileText(const char *fileName, const char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
//------------------------------------------------------------------
// File system functions
@@ -1154,7 +1154,7 @@ RLAPI long GetFileModTime(const char *fileName); // Get file mo
RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree()
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
-RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
+RLAPI unsigned char *DecodeDataBase64(const char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
diff --git a/src/rcore.c b/src/rcore.c
index fdc4b54be..207e112a4 100644
--- a/src/rcore.c
+++ b/src/rcore.c
@@ -523,25 +523,25 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
#define PLATFORM_DESKTOP_GLFW
#endif
-// We're using `#pragma message` because `#warning` is not adopted by MSVC.
+// We're using '#pragma message' because '#warning' is not adopted by MSVC
#if defined(SUPPORT_CLIPBOARD_IMAGE)
#if !defined(SUPPORT_MODULE_RTEXTURES)
- #pragma message ("Warning: Enabling SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly")
+ #pragma message ("WARNING: Enabling SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly")
#endif
// It's nice to have support Bitmap on Linux as well, but not as necessary as Windows
#if !defined(SUPPORT_FILEFORMAT_BMP) && defined(_WIN32)
- #pragma message ("Warning: Enabling SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_FILEFORMAT_BMP, specially on Windows")
+ #pragma message ("WARNING: Enabling SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_FILEFORMAT_BMP, specially on Windows")
#endif
- // From what I've tested applications on Wayland saves images on clipboard as PNG.
+ // From what I've tested applications on Wayland saves images on clipboard as PNG
#if (!defined(SUPPORT_FILEFORMAT_PNG) || !defined(SUPPORT_FILEFORMAT_JPG)) && !defined(_WIN32)
- #pragma message ("Warning: Getting image from the clipboard might not work without SUPPORT_FILEFORMAT_PNG or SUPPORT_FILEFORMAT_JPG")
+ #pragma message ("WARNING: Getting image from the clipboard might not work without SUPPORT_FILEFORMAT_PNG or SUPPORT_FILEFORMAT_JPG")
#endif
- // Not needed because `rtexture.c` will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined.
+ // Not needed because `rtexture.c` will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
// #if !defined(STBI_REQUIRED)
- // #pragma message ("Warning: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
+ // #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
// #endif
#endif // SUPPORT_CLIPBOARD_IMAGE
@@ -2575,7 +2575,7 @@ char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize)
}
// Decode Base64 string data
-unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize)
+unsigned char *DecodeDataBase64(const char *data, int *outputSize)
{
static const unsigned char base64decodeTable[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
diff --git a/src/rmodels.c b/src/rmodels.c
index 61ac9504d..d927f4099 100644
--- a/src/rmodels.c
+++ b/src/rmodels.c
@@ -1429,16 +1429,12 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
rlEnableTexture(material.maps[MATERIAL_MAP_DIFFUSE].texture.id);
- if (mesh.animVertices)
- rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.animVertices);
- else
- rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.vertices);
+ if (mesh.animVertices) rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.animVertices);
+ else rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.vertices);
rlEnableStatePointer(GL_TEXTURE_COORD_ARRAY, mesh.texcoords);
- if (mesh.normals)
- rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.animNormalss);
- else
- rlEnableStatePointer(GL_NORMAL_ARRAY, mesh.normals);
+ if (mesh.normals) rlEnableStatePointer(GL_VERTEX_ARRAY, mesh.animNormalss);
+ else rlEnableStatePointer(GL_NORMAL_ARRAY, mesh.normals);
rlEnableStatePointer(GL_COLOR_ARRAY, mesh.colors);
@@ -3612,16 +3608,16 @@ BoundingBox GetMeshBoundingBox(Mesh mesh)
}
// Compute mesh tangents
-// NOTE: To calculate mesh tangents and binormals we need mesh vertex positions and texture coordinates
-// Implementation based on: https://answers.unity.com/questions/7789/calculating-tangents-vector4.html
void GenMeshTangents(Mesh *mesh)
{
- if ((mesh->vertices == NULL) || (mesh->texcoords == NULL))
+ // Check if input mesh data is useful
+ if ((mesh == NULL) || (mesh->vertices == NULL) || (mesh->texcoords == NULL) || (mesh->normals == NULL))
{
- TRACELOG(LOG_WARNING, "MESH: Tangents generation requires texcoord vertex attribute data");
+ TRACELOG(LOG_WARNING, "MESH: Tangents generation requires vertices, texcoords and normals vertex attribute data");
return;
}
+ // Allocate or reallocate tangents data
if (mesh->tangents == NULL) mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
else
{
@@ -3629,26 +3625,51 @@ void GenMeshTangents(Mesh *mesh)
mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
}
- Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
- Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
+ // Allocate temporary arrays for tangents calculation
+ Vector3 *tan1 = (Vector3 *)RL_CALLOC(mesh->vertexCount, sizeof(Vector3));
+ Vector3 *tan2 = (Vector3 *)RL_CALLOC(mesh->vertexCount, sizeof(Vector3));
- if (mesh->vertexCount % 3 != 0)
+ if (tan1 == NULL || tan2 == NULL)
{
- TRACELOG(LOG_WARNING, "MESH: vertexCount expected to be a multiple of 3. Expect uninitialized values.");
+ TRACELOG(LOG_WARNING, "MESH: Failed to allocate temporary memory for tangent calculation");
+ if (tan1) RL_FREE(tan1);
+ if (tan2) RL_FREE(tan2);
+ return;
}
- for (int i = 0; i <= mesh->vertexCount - 3; i += 3)
+ // Process all triangles of the mesh
+ // 'triangleCount' must be always valid
+ for (int t = 0; t < mesh->triangleCount; t++)
{
- // Get triangle vertices
- Vector3 v1 = { mesh->vertices[(i + 0)*3 + 0], mesh->vertices[(i + 0)*3 + 1], mesh->vertices[(i + 0)*3 + 2] };
- Vector3 v2 = { mesh->vertices[(i + 1)*3 + 0], mesh->vertices[(i + 1)*3 + 1], mesh->vertices[(i + 1)*3 + 2] };
- Vector3 v3 = { mesh->vertices[(i + 2)*3 + 0], mesh->vertices[(i + 2)*3 + 1], mesh->vertices[(i + 2)*3 + 2] };
+ // Get triangle vertex indices
+ int i0, i1, i2;
+
+ if (mesh->indices != NULL)
+ {
+ // Use indices if available
+ i0 = mesh->indices[t*3 + 0];
+ i1 = mesh->indices[t*3 + 1];
+ i2 = mesh->indices[t*3 + 2];
+ }
+ else
+ {
+ // Sequential access for non-indexed mesh
+ i0 = t*3 + 0;
+ i1 = t*3 + 1;
+ i2 = t*3 + 2;
+ }
+
+ // Get triangle vertices position
+ Vector3 v1 = { mesh->vertices[i0*3 + 0], mesh->vertices[i0*3 + 1], mesh->vertices[i0*3 + 2] };
+ Vector3 v2 = { mesh->vertices[i1*3 + 0], mesh->vertices[i1*3 + 1], mesh->vertices[i1*3 + 2] };
+ Vector3 v3 = { mesh->vertices[i2*3 + 0], mesh->vertices[i2*3 + 1], mesh->vertices[i2*3 + 2] };
// Get triangle texcoords
- Vector2 uv1 = { mesh->texcoords[(i + 0)*2 + 0], mesh->texcoords[(i + 0)*2 + 1] };
- Vector2 uv2 = { mesh->texcoords[(i + 1)*2 + 0], mesh->texcoords[(i + 1)*2 + 1] };
- Vector2 uv3 = { mesh->texcoords[(i + 2)*2 + 0], mesh->texcoords[(i + 2)*2 + 1] };
+ Vector2 uv1 = { mesh->texcoords[i0*2 + 0], mesh->texcoords[i0*2 + 1] };
+ Vector2 uv2 = { mesh->texcoords[i1*2 + 0], mesh->texcoords[i1*2 + 1] };
+ Vector2 uv3 = { mesh->texcoords[i2*2 + 0], mesh->texcoords[i2*2 + 1] };
+ // Calculate triangle edges
float x1 = v2.x - v1.x;
float y1 = v2.y - v1.y;
float z1 = v2.z - v1.z;
@@ -3656,65 +3677,95 @@ void GenMeshTangents(Mesh *mesh)
float y2 = v3.y - v1.y;
float z2 = v3.z - v1.z;
+ // Calculate texture coordinate differences
float s1 = uv2.x - uv1.x;
float t1 = uv2.y - uv1.y;
float s2 = uv3.x - uv1.x;
float t2 = uv3.y - uv1.y;
+ // Calculate denominator and check for degenerate UV
float div = s1*t2 - s2*t1;
- float r = (div == 0.0f)? 0.0f : 1.0f/div;
+ float r = (fabsf(div) < 0.0001f)? 0.0f : 1.0f/div;
+ // Calculate tangent and bitangent directions
Vector3 sdir = { (t2*x1 - t1*x2)*r, (t2*y1 - t1*y2)*r, (t2*z1 - t1*z2)*r };
Vector3 tdir = { (s1*x2 - s2*x1)*r, (s1*y2 - s2*y1)*r, (s1*z2 - s2*z1)*r };
- tan1[i + 0] = sdir;
- tan1[i + 1] = sdir;
- tan1[i + 2] = sdir;
+ // Accumulate tangents and bitangents for each vertex of the triangle
+ tan1[i0] = Vector3Add(tan1[i0], sdir);
+ tan1[i1] = Vector3Add(tan1[i1], sdir);
+ tan1[i2] = Vector3Add(tan1[i2], sdir);
- tan2[i + 0] = tdir;
- tan2[i + 1] = tdir;
- tan2[i + 2] = tdir;
+ tan2[i0] = Vector3Add(tan2[i0], tdir);
+ tan2[i1] = Vector3Add(tan2[i1], tdir);
+ tan2[i2] = Vector3Add(tan2[i2], tdir);
}
- // Compute tangents considering normals
+ // Calculate final tangents for each vertex
for (int i = 0; i < mesh->vertexCount; i++)
{
Vector3 normal = { mesh->normals[i*3 + 0], mesh->normals[i*3 + 1], mesh->normals[i*3 + 2] };
Vector3 tangent = tan1[i];
- // TODO: Review, not sure if tangent computation is right, just used reference proposed maths...
-#if defined(COMPUTE_TANGENTS_METHOD_01)
- Vector3 tmp = Vector3Subtract(tangent, Vector3Scale(normal, Vector3DotProduct(normal, tangent)));
- tmp = Vector3Normalize(tmp);
- mesh->tangents[i*4 + 0] = tmp.x;
- mesh->tangents[i*4 + 1] = tmp.y;
- mesh->tangents[i*4 + 2] = tmp.z;
- mesh->tangents[i*4 + 3] = 1.0f;
-#else
- Vector3OrthoNormalize(&normal, &tangent);
- mesh->tangents[i*4 + 0] = tangent.x;
- mesh->tangents[i*4 + 1] = tangent.y;
- mesh->tangents[i*4 + 2] = tangent.z;
- mesh->tangents[i*4 + 3] = (Vector3DotProduct(Vector3CrossProduct(normal, tangent), tan2[i]) < 0.0f)? -1.0f : 1.0f;
-#endif
+ // Handle zero tangent (can happen with degenerate UVs)
+ if (Vector3Length(tangent) < 0.0001f)
+ {
+ // Create a tangent perpendicular to the normal
+ if (fabsf(normal.z) > 0.707f) tangent = (Vector3){ 1.0f, 0.0f, 0.0f };
+ else tangent = Vector3Normalize((Vector3){ -normal.y, normal.x, 0.0f });
+
+ mesh->tangents[i*4 + 0] = tangent.x;
+ mesh->tangents[i*4 + 1] = tangent.y;
+ mesh->tangents[i*4 + 2] = tangent.z;
+ mesh->tangents[i*4 + 3] = 1.0f;
+ continue;
+ }
+
+ // Gram-Schmidt orthogonalization to make tangent orthogonal to normal
+ // T_prime = T - N * dot(N, T)
+ Vector3 orthogonalized = Vector3Subtract(tangent, Vector3Scale(normal, Vector3DotProduct(normal, tangent)));
+
+ // Handle cases where orthogonalized vector is too small
+ if (Vector3Length(orthogonalized) < 0.0001f)
+ {
+ // Create a tangent perpendicular to the normal
+ if (fabsf(normal.z) > 0.707f) orthogonalized = (Vector3){ 1.0f, 0.0f, 0.0f };
+ else orthogonalized = Vector3Normalize((Vector3){ -normal.y, normal.x, 0.0f });
+ }
+ else
+ {
+ // Normalize the orthogonalized tangent
+ orthogonalized = Vector3Normalize(orthogonalized);
+ }
+
+ // Store the calculated tangent
+ mesh->tangents[i*4 + 0] = orthogonalized.x;
+ mesh->tangents[i*4 + 1] = orthogonalized.y;
+ mesh->tangents[i*4 + 2] = orthogonalized.z;
+
+ // Calculate the handedness (w component)
+ mesh->tangents[i*4 + 3] = (Vector3DotProduct(Vector3CrossProduct(normal, orthogonalized), tan2[i]) < 0.0f)? -1.0f : 1.0f;
}
+ // Free temporary arrays
RL_FREE(tan1);
RL_FREE(tan2);
+ // Update vertex buffers if available
if (mesh->vboId != NULL)
{
if (mesh->vboId[SHADER_LOC_VERTEX_TANGENT] != 0)
{
- // Update existing vertex buffer
+ // Update existing tangent vertex buffer
rlUpdateVertexBuffer(mesh->vboId[SHADER_LOC_VERTEX_TANGENT], mesh->tangents, mesh->vertexCount*4*sizeof(float), 0);
}
else
{
- // Load a new tangent attributes buffer
+ // Create new tangent vertex buffer
mesh->vboId[SHADER_LOC_VERTEX_TANGENT] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
}
+ // Set up vertex attributes for shader
rlEnableVertexArray(mesh->vaoId);
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, 4, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT);
@@ -5215,7 +5266,7 @@ static Model LoadGLTF(const char *fileName)
/*********************************************************************************************
Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend)
- Transform handling implemented by Paul Melis (@paulmelis).
+ Transform handling implemented by Paul Melis (@paulmelis)
Reviewed by Ramon Santamaria (@raysan5)
FEATURES:
@@ -5225,10 +5276,10 @@ static Model LoadGLTF(const char *fileName)
PBR specular/glossiness flow and extended texture flows not supported
- Supports multiple meshes per model (every primitives is loaded as a separate mesh)
- Supports basic animations
- - Transforms, including parent-child relations, are applied on the mesh data, but the
- hierarchy is not kept (as it can't be represented).
+ - Transforms, including parent-child relations, are applied on the mesh data,
+ but the hierarchy is not kept (as it can't be represented)
- Mesh instances in the glTF file (i.e. same mesh linked from multiple nodes)
- are turned into separate raylib Meshes.
+ are turned into separate raylib Meshes
RESTRICTIONS:
- Only triangle meshes supported
@@ -5444,7 +5495,7 @@ static Model LoadGLTF(const char *fileName)
// Any glTF mesh linked from more than one Node (i.e. instancing)
// is turned into multiple Mesh's, as each Node will have its own
// transform applied.
- // Note: the code below disregards the scenes defined in the file, all nodes are used.
+ // NOTE: The code below disregards the scenes defined in the file, all nodes are used.
//----------------------------------------------------------------------------------------------------
int meshIndex = 0;
for (unsigned int i = 0; i < data->nodes_count; i++)
@@ -5894,7 +5945,6 @@ static Model LoadGLTF(const char *fileName)
if (attribute->type == cgltf_type_vec4)
{
- // TODO: Support component types: u8, u16?
if (attribute->component_type == cgltf_component_type_r_8u)
{
// Init raylib mesh bone weight to copy glTF attribute data
@@ -5930,6 +5980,7 @@ static Model LoadGLTF(const char *fileName)
// Load 4 components of float data type into mesh.boneWeights
// for cgltf_attribute_type_weights we have:
+
// - data.meshes[0] (256 vertices)
// - 256 values, provided as cgltf_type_vec4 of float (4 byte per joint, stride 16)
LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].boneWeights)
@@ -5940,8 +5991,8 @@ static Model LoadGLTF(const char *fileName)
}
}
- // check if we are animated, and the mesh was not given any bone assignments, but is the child of a bone node
- // in this case we need to fully attach all the verts to the parent bone so it will animate with the bone.
+ // Check if we are animated, and the mesh was not given any bone assignments, but is the child of a bone node
+ // in this case we need to fully attach all the verts to the parent bone so it will animate with the bone
if (data->skins_count > 0 && !hasJoints && node->parent != NULL && node->parent->mesh == NULL)
{
int parentBoneId = -1;
@@ -5956,16 +6007,15 @@ static Model LoadGLTF(const char *fileName)
if (parentBoneId >= 0)
{
- model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount * 4, sizeof(unsigned char));
- model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount * 4, sizeof(float));
+ model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char));
+ model.meshes[meshIndex].boneWeights = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float));
- for (int vertexIndex = 0; vertexIndex < model.meshes[meshIndex].vertexCount * 4; vertexIndex += 4)
+ for (int vertexIndex = 0; vertexIndex < model.meshes[meshIndex].vertexCount*4; vertexIndex += 4)
{
model.meshes[meshIndex].boneIds[vertexIndex] = (unsigned char)parentBoneId;
model.meshes[meshIndex].boneWeights[vertexIndex] = 1.0f;
}
}
-
}
// Animated vertex data
@@ -5986,9 +6036,8 @@ static Model LoadGLTF(const char *fileName)
model.meshes[meshIndex].boneMatrices[j] = MatrixIdentity();
}
- meshIndex++; // Move to next mesh
+ meshIndex++; // Move to next mesh
}
-
}
// Free all cgltf loaded data
diff --git a/src/rtext.c b/src/rtext.c
index 4ee9b34b6..70dcfc38c 100644
--- a/src/rtext.c
+++ b/src/rtext.c
@@ -331,6 +331,9 @@ extern void UnloadFontDefault(void)
if (isGpuReady) UnloadTexture(defaultFont.texture);
RL_FREE(defaultFont.glyphs);
RL_FREE(defaultFont.recs);
+ defaultFont.glyphCount = 0;
+ defaultFont.glyphs = NULL;
+ defaultFont.recs = NULL;
}
#endif // SUPPORT_DEFAULT_FONT
@@ -1575,7 +1578,7 @@ const char *TextSubtext(const char *text, int position, int length)
}
// Replace text string
-// REQUIRES: strlen(), strstr(), strncpy(), strcpy()
+// REQUIRES: strstr(), strncpy(), strcpy()
// WARNING: Allocated memory must be manually freed
char *TextReplace(const char *text, const char *replace, const char *by)
{
diff --git a/src/rtextures.c b/src/rtextures.c
index ee116b0e5..2f5aaa871 100644
--- a/src/rtextures.c
+++ b/src/rtextures.c
@@ -832,10 +832,11 @@ Image GenImageGradientLinear(int width, int height, int direction, Color start,
// Calculate how far the top-left pixel is along the gradient direction from the center of said gradient
float startingPos = 0.5f - (cosDir*width/2) - (sinDir*height/2);
+
// With directions that lie in the first or third quadrant (i.e. from top-left to
// bottom-right or vice-versa), pixel (0, 0) is the farthest point on the gradient
// (i.e. the pixel which should become one of the gradient's ends color); while for
- // directions that lie in the second or fourth quadrant, that point is pixel (width, 0).
+ // directions that lie in the second or fourth quadrant, that point is pixel (width, 0)
float maxPosValue = ((signbit(sinDir) != 0) == (signbit(cosDir) != 0))? fabsf(startingPos) : fabsf(startingPos + width*cosDir);
for (int i = 0; i < width; i++)
{
@@ -3835,7 +3836,7 @@ void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c
// Calculate the inverse of the sum of the barycentric coordinates for normalization
// NOTE 1: Here, we act as if we multiply by 255 the reciprocal, which avoids additional
- // calculations in the loop. This is acceptable because we are only interpolating colors.
+ // calculations in the loop. This is acceptable because we are only interpolating colors
// NOTE 2: This sum remains constant throughout the triangle
float wInvSum = 255.0f/(w1Row + w2Row + w3Row);
diff --git a/src/utils.c b/src/utils.c
index 5c189845b..26e7a1bab 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -405,7 +405,7 @@ void UnloadFileText(char *text)
}
// Save text data to file (write), string must be '\0' terminated
-bool SaveFileText(const char *fileName, char *text)
+bool SaveFileText(const char *fileName, const char *text)
{
bool success = false;