merge upstream master into feature branch

This commit is contained in:
Cry dsch 2021-06-01 22:10:04 +02:00
commit eface0dc00
39 changed files with 3457 additions and 2695 deletions

View File

@ -8,7 +8,7 @@ Here it is a list with the ones I'm aware of:
|:------------------:|:-------------: | :--------:|----------------------------------------------------------------------| |:------------------:|:-------------: | :--------:|----------------------------------------------------------------------|
| raylib | **3.7** | [C](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib | | raylib | **3.7** | [C](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib |
| raylib-cpp | 3.7 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp | | raylib-cpp | 3.7 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp |
| Raylib-cs | 3.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs | | Raylib-cs | 3.7 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs |
| raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp | | raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp |
| raylib-boo | 3.7 | [Boo](http://boo-language.github.io/) | https://github.com/Rabios/raylib-boo | | raylib-boo | 3.7 | [Boo](http://boo-language.github.io/) | https://github.com/Rabios/raylib-boo |
| RaylibFS | 2.5 | [F#](https://fsharp.org/) | https://github.com/dallinbeutler/RaylibFS | | RaylibFS | 2.5 | [F#](https://fsharp.org/) | https://github.com/dallinbeutler/RaylibFS |
@ -16,7 +16,7 @@ Here it is a list with the ones I'm aware of:
| raylib-d | 3.0 | [D](https://dlang.org/) | https://github.com/onroundit/raylib-d | | raylib-d | 3.0 | [D](https://dlang.org/) | https://github.com/onroundit/raylib-d |
| bindbc-raylib | 3.0 | [D](https://dlang.org/) | https://github.com/o3o/bindbc-raylib | | bindbc-raylib | 3.0 | [D](https://dlang.org/) | https://github.com/o3o/bindbc-raylib |
| dray | 3.5 | [D](https://dlang.org/) | https://github.com/xdrie/dray | | dray | 3.5 | [D](https://dlang.org/) | https://github.com/xdrie/dray |
| raylib-go | 3.0 | [Go](https://golang.org/) | https://github.com/gen2brain/raylib-go | | raylib-go | 3.8-dev | [Go](https://golang.org/) | https://github.com/gen2brain/raylib-go |
| raylib-goplus | 2.6-dev | [Go](https://golang.org/) | https://github.com/Lachee/raylib-goplus | | raylib-goplus | 2.6-dev | [Go](https://golang.org/) | https://github.com/Lachee/raylib-goplus |
| ray-go | 2.6-dev | [Go](https://golang.org/) | https://github.com/hecate-tech/ray-go | | ray-go | 2.6-dev | [Go](https://golang.org/) | https://github.com/hecate-tech/ray-go |
| go-raylib | 3.5 | [Go](https://golang.org/) | https://github.com/chunqian/go-raylib | | go-raylib | 3.5 | [Go](https://golang.org/) | https://github.com/chunqian/go-raylib |

View File

@ -1,8 +1,8 @@
if(USE_EXTERNAL_GLFW STREQUAL "ON") if(USE_EXTERNAL_GLFW STREQUAL "ON")
find_package(glfw3 3.2.1 REQUIRED) find_package(glfw3 3.3.3 REQUIRED)
elseif(USE_EXTERNAL_GLFW STREQUAL "IF_POSSIBLE") elseif(USE_EXTERNAL_GLFW STREQUAL "IF_POSSIBLE")
find_package(glfw3 3.2.1 QUIET) find_package(glfw3 3.3.3 QUIET)
endif() endif()
if (glfw3_FOUND) if (glfw3_FOUND)
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw) set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)

View File

@ -257,8 +257,8 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
endif endif
# Define include paths for required headers # Define include paths for required headers
# NOTE: Several external required libraries (stb and others) # NOTE: Some external/extras libraries could be required (stb, physac, easings...)
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external -I$(RAYLIB_PATH)/src/extras
# Define additional directories containing required header files # Define additional directories containing required header files
ifeq ($(PLATFORM),PLATFORM_RPI) ifeq ($(PLATFORM),PLATFORM_RPI)
@ -277,7 +277,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
INCLUDE_PATHS += -I/usr/local/include INCLUDE_PATHS += -I/usr/local/include
endif endif
ifeq ($(PLATFORM_OS),LINUX) ifeq ($(PLATFORM_OS),LINUX)
INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external INCLUDE_PATHS += -I$(RAYLIB_H_INSTALL_PATH)
endif endif
endif endif

View File

@ -21,7 +21,7 @@
#include <stdlib.h> #include <stdlib.h>
#define MAX_MODELS 6 #define MAX_MODELS 7
int main(void) int main(void)
{ {
@ -30,7 +30,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation"); InitWindow(screenWidth, screenHeight, "raylib [models] example - model");
// Define the camera to look into our 3d world // Define the camera to look into our 3d world
Camera camera = { 0 }; Camera camera = { 0 };
@ -48,6 +48,7 @@ int main(void)
model[3] = LoadModel("resources/gltf/BoxAnimated.glb"); model[3] = LoadModel("resources/gltf/BoxAnimated.glb");
model[4] = LoadModel("resources/gltf/AnimatedTriangle.gltf"); model[4] = LoadModel("resources/gltf/AnimatedTriangle.gltf");
model[5] = LoadModel("resources/gltf/AnimatedMorphCube.glb"); model[5] = LoadModel("resources/gltf/AnimatedMorphCube.glb");
model[6] = LoadModel("resources/gltf/vertex_colored_object.glb");
int currentModel = 0; int currentModel = 0;

View File

@ -71,22 +71,22 @@ int main(void)
UpdateCamera(&camera); // Update camera UpdateCamera(&camera); // Update camera
// Display information about closest hit // Display information about closest hit
RayCollision nearestHit = { 0 }; RayCollision collision = { 0 };
char *hitObjectName = "None"; char *hitObjectName = "None";
nearestHit.distance = FLT_MAX; collision.distance = FLT_MAX;
nearestHit.hit = false; collision.hit = false;
Color cursorColor = WHITE; Color cursorColor = WHITE;
// Get ray and test against objects // Get ray and test against objects
ray = GetMouseRay(GetMousePosition(), camera); ray = GetMouseRay(GetMousePosition(), camera);
// Check ray collision against ground plane // Check ray collision against ground quad
RayCollision groundHitInfo = GetRayCollisionQuad(ray, g0, g1, g2, g3); RayCollision collision = GetRayCollisionQuad(ray, g0, g1, g2, g3);
DrawPoint3D(g0, RED); DrawPoint3D(g0, RED);
if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance)) if ((groundHitInfo.hit) && (groundHitInfo.distance < collision.distance))
{ {
nearestHit = groundHitInfo; collision = groundHitInfo;
cursorColor = GREEN; cursorColor = GREEN;
hitObjectName = "Ground"; hitObjectName = "Ground";
} }
@ -94,13 +94,13 @@ int main(void)
// Check ray collision against test triangle // Check ray collision against test triangle
RayCollision triHitInfo = GetRayCollisionTriangle(ray, ta, tb, tc); RayCollision triHitInfo = GetRayCollisionTriangle(ray, ta, tb, tc);
if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance)) if ((triHitInfo.hit) && (triHitInfo.distance < collision.distance))
{ {
nearestHit = triHitInfo; collision = triHitInfo;
cursorColor = ORANGE; cursorColor = PURPLE;
hitObjectName = "Triangle"; hitObjectName = "Triangle";
bary = Vector3Barycenter(nearestHit.point, ta, tb, tc); bary = Vector3Barycenter(collision.point, ta, tb, tc);
} }
// Check ray collision against test sphere // Check ray collision against test sphere
@ -117,7 +117,7 @@ int main(void)
if ((boxHitInfo.hit) && (boxHitInfo.distance < nearestHit.distance)) if ((boxHitInfo.hit) && (boxHitInfo.distance < nearestHit.distance))
{ {
nearestHit = boxHitInfo; collision = boxHitInfo;
cursorColor = ORANGE; cursorColor = ORANGE;
hitObjectName = "Box"; hitObjectName = "Box";
@ -127,7 +127,7 @@ int main(void)
if (meshHitInfo.hit) if (meshHitInfo.hit)
{ {
nearestHit = meshHitInfo; collision = meshHitInfo;
cursorColor = ORANGE; cursorColor = ORANGE;
hitObjectName = "Mesh"; hitObjectName = "Mesh";
} }
@ -144,7 +144,7 @@ int main(void)
// Draw the tower // Draw the tower
// WARNING: If scale is different than 1.0f, // WARNING: If scale is different than 1.0f,
// not considered by GetCollisionRayModel() // not considered by GetRayCollisionModel()
DrawModel(tower, towerPos, 1.0f, WHITE); DrawModel(tower, towerPos, 1.0f, WHITE);
// Draw the test triangle // Draw the test triangle
@ -159,17 +159,17 @@ int main(void)
if (boxHitInfo.hit) DrawBoundingBox(towerBBox, LIME); if (boxHitInfo.hit) DrawBoundingBox(towerBBox, LIME);
// If we hit something, draw the cursor at the hit point // If we hit something, draw the cursor at the hit point
if (nearestHit.hit) if (collision.hit)
{ {
DrawCube(nearestHit.point, 0.3f, 0.3f, 0.3f, cursorColor); DrawCube(collision.point, 0.3f, 0.3f, 0.3f, cursorColor);
DrawCubeWires(nearestHit.point, 0.3f, 0.3f, 0.3f, RED); DrawCubeWires(collision.point, 0.3f, 0.3f, 0.3f, RED);
Vector3 normalEnd; Vector3 normalEnd;
normalEnd.x = nearestHit.point.x + nearestHit.normal.x; normalEnd.x = collision.point.x + collision.normal.x;
normalEnd.y = nearestHit.point.y + nearestHit.normal.y; normalEnd.y = collision.point.y + collision.normal.y;
normalEnd.z = nearestHit.point.z + nearestHit.normal.z; normalEnd.z = collision.point.z + collision.normal.z;
DrawLine3D(nearestHit.point, normalEnd, RED); DrawLine3D(collision.point, normalEnd, RED);
} }
DrawRay(ray, MAROON); DrawRay(ray, MAROON);
@ -181,21 +181,21 @@ int main(void)
// Draw some debug GUI text // Draw some debug GUI text
DrawText(TextFormat("Hit Object: %s", hitObjectName), 10, 50, 10, BLACK); DrawText(TextFormat("Hit Object: %s", hitObjectName), 10, 50, 10, BLACK);
if (nearestHit.hit) if (collision.hit)
{ {
int ypos = 70; int ypos = 70;
DrawText(TextFormat("Distance: %3.2f", nearestHit.distance), 10, ypos, 10, BLACK); DrawText(TextFormat("Distance: %3.2f", collision.distance), 10, ypos, 10, BLACK);
DrawText(TextFormat("Hit Pos: %3.2f %3.2f %3.2f", DrawText(TextFormat("Hit Pos: %3.2f %3.2f %3.2f",
nearestHit.point.x, collision.point.x,
nearestHit.point.y, collision.point.y,
nearestHit.point.z), 10, ypos + 15, 10, BLACK); collision.point.z), 10, ypos + 15, 10, BLACK);
DrawText(TextFormat("Hit Norm: %3.2f %3.2f %3.2f", DrawText(TextFormat("Hit Norm: %3.2f %3.2f %3.2f",
nearestHit.normal.x, collision.normal.x,
nearestHit.normal.y, collision.normal.y,
nearestHit.normal.z), 10, ypos + 30, 10, BLACK); collision.normal.z), 10, ypos + 30, 10, BLACK);
if (triHitInfo.hit && strcmp(hitObjectName, "Triangle") == 0) if (triHitInfo.hit && strcmp(hitObjectName, "Triangle") == 0)
DrawText(TextFormat("Barycenter: %3.2f %3.2f %3.2f", bary.x, bary.y, bary.z), 10, ypos + 45, 10, BLACK); DrawText(TextFormat("Barycenter: %3.2f %3.2f %3.2f", bary.x, bary.y, bary.z), 10, ypos + 45, 10, BLACK);

View File

@ -37,7 +37,7 @@ int main(void)
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f); Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
Model skybox = LoadModelFromMesh(cube); Model skybox = LoadModelFromMesh(cube);
bool useHDR = false; bool useHDR = true;
// Load skybox shader and set required locations // Load skybox shader and set required locations
// NOTE: Some locations are automatically set at shader loading // NOTE: Some locations are automatically set at shader loading
@ -56,12 +56,14 @@ int main(void)
char skyboxFileName[256] = { 0 }; char skyboxFileName[256] = { 0 };
Texture2D panorama;
if (useHDR) if (useHDR)
{ {
TextCopy(skyboxFileName, "resources/dresden_square_2k.hdr"); TextCopy(skyboxFileName, "resources/dresden_square_2k.hdr");
// Load HDR panorama (sphere) texture // Load HDR panorama (sphere) texture
Texture2D panorama = panorama = LoadTexture(skyboxFileName); panorama = LoadTexture(skyboxFileName);
// Generate cubemap (texture with 6 quads-cube-mapping) from panorama HDR texture // Generate cubemap (texture with 6 quads-cube-mapping) from panorama HDR texture
// NOTE 1: New texture is generated rendering to texture, shader calculates the sphere->cube coordinates mapping // NOTE 1: New texture is generated rendering to texture, shader calculates the sphere->cube coordinates mapping
@ -69,7 +71,7 @@ int main(void)
// despite texture can be successfully created.. so using PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 instead of PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 // despite texture can be successfully created.. so using PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 instead of PIXELFORMAT_UNCOMPRESSED_R32G32B32A32
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8); skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = GenTextureCubemap(shdrCubemap, panorama, 1024, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8);
UnloadTexture(panorama); // Texture not required anymore, cubemap already generated //UnloadTexture(panorama); // Texture not required anymore, cubemap already generated
} }
else else
{ {
@ -144,10 +146,10 @@ int main(void)
EndMode3D(); EndMode3D();
if (useHDR) //DrawTextureEx(panorama, (Vector2){ 0, 0 }, 0.0f, 0.5f, WHITE);
DrawText(TextFormat("Panorama image from hdrihaven.com: %s", GetFileName(skyboxFileName)), 10, GetScreenHeight() - 20, 10, BLACK);
else if (useHDR) DrawText(TextFormat("Panorama image from hdrihaven.com: %s", GetFileName(skyboxFileName)), 10, GetScreenHeight() - 20, 10, BLACK);
DrawText(TextFormat(": %s", GetFileName(skyboxFileName)), 10, GetScreenHeight() - 20, 10, BLACK); else DrawText(TextFormat(": %s", GetFileName(skyboxFileName)), 10, GetScreenHeight() - 20, 10, BLACK);
DrawFPS(10, 10); DrawFPS(10, 10);
@ -209,17 +211,31 @@ static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int s
rlViewport(0, 0, size, size); // Set viewport to current fbo dimensions rlViewport(0, 0, size, size); // Set viewport to current fbo dimensions
// Activate and enable texture for drawing to cubemap faces
rlActiveTextureSlot(0);
rlEnableTexture(panorama.id);
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
// Set the view matrix for the current cube face
rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]); rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]);
// Select the current cubemap face attachment for the fbo
// WARNING: This function by default enables->attach->disables fbo!!!
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i, 0); rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i, 0);
rlEnableFramebuffer(fbo); rlEnableFramebuffer(fbo);
rlSetTexture(panorama.id); // WARNING: It must be called after enabling current framebuffer if using internal batch system!
// Load and draw a cube, it uses the current enabled texture
rlClearScreenBuffers(); rlClearScreenBuffers();
DrawCubeV(Vector3Zero(), Vector3One(), WHITE); rlLoadDrawCube();
rlDrawRenderBatchActive();
// ALTERNATIVE: Try to use internal batch system to draw the cube instead of rlLoadDrawCube
// for some reason this method does not work, maybe due to cube triangles definition? normals pointing out?
// TODO: Investigate this issue...
//rlSetTexture(panorama.id); // WARNING: It must be called after enabling current framebuffer if using internal batch system!
//rlClearScreenBuffers();
//DrawCubeV(Vector3Zero(), Vector3One(), WHITE);
//rlDrawRenderBatchActive();
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -238,7 +254,7 @@ static TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int s
cubemap.width = size; cubemap.width = size;
cubemap.height = size; cubemap.height = size;
cubemap.mipmaps = 1; cubemap.mipmaps = 1;
cubemap.format = PIXELFORMAT_UNCOMPRESSED_R32G32B32; cubemap.format = format;
return cubemap; return cubemap;
} }

View File

@ -1,16 +1,5 @@
/*******************************************************************************************
*
* BRDF LUT Generation - Bidirectional reflectance distribution function fragment shader
*
* REF: https://github.com/HectorMF/BRDFGenerator
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
in vec2 fragTexCoord; in vec2 fragTexCoord;
@ -86,6 +75,8 @@ float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
return ggx1*ggx2; return ggx1*ggx2;
} }
// Bidirectional reflectance distribution function
// Ref: https://github.com/HectorMF/BRDFGenerator
vec2 IntegrateBRDF(float NdotV, float roughness) vec2 IntegrateBRDF(float NdotV, float roughness)
{ {
float A = 0.0; float A = 0.0;

View File

@ -1,11 +1,3 @@
/*******************************************************************************************
*
* rPBR [shader] - Bidirectional reflectance distribution function vertex shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
// Input vertex attributes // Input vertex attributes

View File

@ -1,11 +1,3 @@
/*******************************************************************************************
*
* rPBR [shader] - Equirectangular to cubemap vertex shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
// Input vertex attributes // Input vertex attributes

View File

@ -1,11 +1,3 @@
/*******************************************************************************************
*
* rPBR [shader] - Irradiance cubemap fragment shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)

View File

@ -1,11 +1,3 @@
/*******************************************************************************************
*
* rPBR [shader] - Physically based rendering fragment shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
#define MAX_REFLECTION_LOD 4.0 #define MAX_REFLECTION_LOD 4.0

View File

@ -1,11 +1,3 @@
/*******************************************************************************************
*
* rPBR [shader] - Physically based rendering vertex shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
// Input vertex attributes // Input vertex attributes

View File

@ -1,14 +1,7 @@
/*******************************************************************************************
*
* rPBR [shader] - Prefiltered environment for reflections fragment shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
#define MAX_SAMPLES 1024u
#define CUBEMAP_RESOLUTION 1024.0 #define MAX_SAMPLES 1024u
#define CUBEMAP_RESOLUTION 1024.0
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)
in vec3 fragPosition; in vec3 fragPosition;

View File

@ -1,13 +1,3 @@
/*******************************************************************************************
*
* rPBR [shader] - Background skybox fragment shader
*
* Copyright (c) 2017 Victor Fisac
*
* 19-Jun-2020 - modified by Giuseppe Mastrangelo (@peppemas) - VFlip Support
*
**********************************************************************************************/
#version 330 #version 330
// Input vertex attributes (from vertex shader) // Input vertex attributes (from vertex shader)

View File

@ -1,11 +1,3 @@
/*******************************************************************************************
*
* rPBR [shader] - Background skybox vertex shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
// Input vertex attributes // Input vertex attributes

View File

@ -191,10 +191,10 @@ int main(void)
Ray ray = GetMouseRay(GetMousePosition(), camera); Ray ray = GetMouseRay(GetMousePosition(), camera);
// Check collision between ray and box // Check collision between ray and box
bool collision = CheckCollisionRayBox(ray, RayCollision collision = GetRayCollisionBox(ray,
(BoundingBox){(Vector3){ cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2 }, (BoundingBox){(Vector3){ cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2 },
(Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }}); (Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }});
if (collision) if (collision.hit)
{ {
// Generate new random colors // Generate new random colors
light = GenerateRandomColor(0.5f, 0.78f); light = GenerateRandomColor(0.5f, 0.78f);

58
parser/README.md Normal file
View File

@ -0,0 +1,58 @@
## raylib parser
This parser scans [`raylib.h`](../src/raylib.h) to get information about `structs`, `enums` and `functions`.
All data is separated into parts, usually as strings. The following types are used for data:
- `struct FunctionInfo`
- `struct StructInfo`
- `struct EnumInfo`
Check `raylib_parser.c` for details about those structs.
## Constraints
This parser is specifically designed to work with raylib.h, so, it has some constraints:
- Functions are expected as a single line with the following structure:
```
<retType> <name>(<paramType[0]> <paramName[0]>, <paramType[1]> <paramName[1]>); <desc>
```
Be careful with functions broken into several lines, it breaks the process!
- Structures are expected as several lines with the following form:
```
<desc>
typedef struct <name> {
<fieldType[0]> <fieldName[0]>; <fieldDesc[0]>
<fieldType[1]> <fieldName[1]>; <fieldDesc[1]>
<fieldType[2]> <fieldName[2]>; <fieldDesc[2]>
} <name>;
```
- Enums are expected as several lines with the following form:
```
<desc>
typedef enum {
<valueName[0]> = <valueInteger[0]>, <valueDesc[0]>
<valueName[1]>,
<valueName[2]>, <valueDesc[2]>
<valueName[3]> <valueDesc[3]>
} <name>;
```
_NOTE: For enums, multiple options are supported:_
- If value is not provided, (<valueInteger[i -1]> + 1) is assigned
- Value description can be provided or not
## Additional notes
This parser _could_ work with other C header files if mentioned constraints are followed.
This parser **does not require `<string.h>` library**, all data is parsed directly from char buffers.
### LICENSE: zlib/libpng
raylib-parser is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
BSD-like license that allows static linking with closed source software:
Copyright (c) 2021 Ramon Santamaria (@raysan5)

684
parser/raylib_parser.c Normal file
View File

@ -0,0 +1,684 @@
/**********************************************************************************************
raylib parser - raylib header parser
This parser scans raylib.h to get information about structs, enums and functions.
All data is separated into parts, usually as strings. The following types are used for data:
- struct FunctionInfo
- struct StructInfo
- struct EnumInfo
CONSTRAINTS:
This parser is specifically designed to work with raylib.h, so, it has some constraints:
- Functions are expected as a single line with the following structure:
<retType> <name>(<paramType[0]> <paramName[0]>, <paramType[1]> <paramName[1]>); <desc>
Be careful with functions broken into several lines, it breaks the process!
- Structures are expected as several lines with the following form:
<desc>
typedef struct <name> {
<fieldType[0]> <fieldName[0]>; <fieldDesc[0]>
<fieldType[1]> <fieldName[1]>; <fieldDesc[1]>
<fieldType[2]> <fieldName[2]>; <fieldDesc[2]>
} <name>;
- Enums are expected as several lines with the following form:
<desc>
typedef enum {
<valueName[0]> = <valueInteger[0]>, <valueDesc[0]>
<valueName[1]>,
<valueName[2]>, <valueDesc[2]>
<valueName[3]> <valueDesc[3]>
} <name>;
NOTE: Multiple options are supported:
- If value is not provided, (<valueInteger[i -1]> + 1) is assigned
- Value description can be provided or not
This parser could work with other C header files if mentioned constraints are followed.
This parser does not require <string.h> library, all data is parsed directly from char buffers.
LICENSE: zlib/libpng
raylib-parser is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
BSD-like license that allows static linking with closed source software:
Copyright (c) 2021 Ramon Santamaria (@raysan5)
**********************************************************************************************/
#include <stdlib.h> // Required for: malloc(), calloc(), realloc(), free(), atoi(), strtol()
#include <stdio.h> // Required for: printf(), fopen(), fseek(), ftell(), fread(), fclose()
#include <stdbool.h> // Required for: bool
#define MAX_FUNCS_TO_PARSE 512 // Maximum number of functions to parse
#define MAX_STRUCTS_TO_PARSE 64 // Maximum number of structures to parse
#define MAX_ENUMS_TO_PARSE 64 // Maximum number of enums to parse
#define MAX_LINE_LENGTH 512 // Maximum length of one line (including comments)
#define MAX_STRUCT_LINE_LENGTH 2048 // Maximum length of one struct (multiple lines)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Function info data
typedef struct FunctionInfo {
char name[64]; // Function name
char desc[128]; // Function description (comment at the end)
char retType[32]; // Return value type
int paramCount; // Number of function parameters
char paramType[12][32]; // Parameters type (max: 12 parameters)
char paramName[12][32]; // Parameters name (max: 12 parameters)
} FunctionInfo;
// Struct info data
typedef struct StructInfo {
char name[64]; // Struct name
char desc[64]; // Struct type description
int fieldCount; // Number of fields in the struct
char fieldType[16][32]; // Field type (max: 16 fields)
char fieldName[16][32]; // Field name (max: 16 fields)
char fieldDesc[16][128]; // Field description (max: 16 fields)
} StructInfo;
// Enum info data
typedef struct EnumInfo {
char name[64]; // Enum name
char desc[64]; // Enum description
int valueCount; // Number of values in enumerator
char valueName[128][64]; // Value name definition (max: 128 values)
int valueInteger[128]; // Value integer (max: 128 values)
char valueDesc[128][64]; // Value description (max: 128 values)
} EnumInfo;
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
char *LoadFileText(const char *fileName, int *length);
char **GetTextLines(const char *buffer, int length, int *linesCount);
void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name);
bool IsTextEqual(const char *text1, const char *text2, unsigned int count);
void MemoryCopy(void *dest, const void *src, unsigned int count);
// Main entry point
int main()
{
int length = 0;
char *buffer = LoadFileText("../src/raylib.h", &length);
// Preprocess buffer to get separate lines
// NOTE: GetTextLines() also removes leading spaces/tabs
int linesCount = 0;
char **lines = GetTextLines(buffer, length, &linesCount);
// Print buffer lines
//for (int i = 0; i < linesCount; i++) printf("_%s_\n", lines[i]);
// Function lines pointers, selected from buffer "lines"
int funcCount = 0;
char **funcLines = (char **)malloc(MAX_FUNCS_TO_PARSE*sizeof(char *));
// Structs data (multiple lines), selected from "buffer"
int structCount = 0;
char **structLines = (char **)malloc(MAX_STRUCTS_TO_PARSE*sizeof(char *));
for (int i = 0; i < MAX_STRUCTS_TO_PARSE; i++) structLines[i] = (char *)calloc(MAX_STRUCT_LINE_LENGTH, sizeof(char));
// Enums lines pointers, selected from buffer "lines"
int enumCount = 0;
int *enumLines = (int *)malloc(MAX_ENUMS_TO_PARSE*sizeof(int));
// Prepare required lines for parsing
//--------------------------------------------------------------------------------------------------
// Read function lines
for (int i = 0; i < linesCount; i++)
{
// Read function line (starting with "RLAPI")
if (IsTextEqual(lines[i], "RLAPI", 5))
{
// Keep a pointer to the function line
funcLines[funcCount] = lines[i];
funcCount++;
}
}
// Print function lines
//for (int i = 0; i < funcCount; i++) printf("%s\n", funcLines[i]);
// Read structs data (multiple lines, read directly from buffer)
// TODO: Parse structs data from "lines" instead of "buffer" -> Easier to get struct definition
for (int i = 0; i < length; i++)
{
// Read struct data (starting with "typedef struct", ending with '} ... ;')
// NOTE: We read it directly from buffer
if (IsTextEqual(buffer + i, "typedef struct", 14))
{
int j = 0;
bool validStruct = false;
// WARNING: Typedefs between types: typedef Vector4 Quaternion;
for (int c = 0; c < 128; c++)
{
if (buffer[i + c] == '{')
{
validStruct = true;
break;
}
else if (buffer[i + j] == ';')
{
// Not valid struct:
// i.e typedef struct rAudioBuffer rAudioBuffer; -> Typedef and forward declaration
i += c;
break;
}
}
if (validStruct)
{
while (buffer[i + j] != '}')
{
structLines[structCount][j] = buffer[i + j];
j++;
}
while (buffer[i + j] != '}')
{
structLines[structCount][j] = buffer[i + j];
j++;
}
while (buffer[i + j] != '\n')
{
structLines[structCount][j] = buffer[i + j];
j++;
}
i += j;
structCount++;
}
}
}
// Read enum lines
for (int i = 0; i < linesCount; i++)
{
// Read function line (starting with "RLAPI")
if (IsTextEqual(lines[i], "typedef enum {", 14))
{
// Keep the line position in the array of lines,
// so, we can scan that position and following lines
enumLines[enumCount] = i;
enumCount++;
}
}
// At this point we have all raylib structs, enums, functions lines data to start parsing
free(buffer); // Unload text buffer
// Parsing raylib data
//--------------------------------------------------------------------------------------------------
// Structs info data
StructInfo *structs = (StructInfo *)calloc(MAX_STRUCTS_TO_PARSE, sizeof(StructInfo));
for (int i = 0; i < structCount; i++)
{
int structLineOffset = 0;
// Get struct name: typedef struct name {
for (int c = 15; c < 64 + 15; c++)
{
if (structLines[i][c] == '{')
{
structLineOffset = c + 2;
MemoryCopy(structs[i].name, &structLines[i][15], c - 15 - 1);
break;
}
}
// Get struct fields and count them -> fields finish with ;
int j = 0;
while (structLines[i][structLineOffset + j] != '}')
{
// WARNING: Some structs have empty spaces and comments -> OK, processed
int fieldStart = 0;
if ((structLines[i][structLineOffset + j] != ' ') && (structLines[i][structLineOffset + j] != '\n')) fieldStart = structLineOffset + j;
if (fieldStart != 0)
{
// Scan one field line
int c = 0;
int fieldEndPos = 0;
char fieldLine[256] = { 0 };
while (structLines[i][structLineOffset + j] != '\n')
{
if (structLines[i][structLineOffset + j] == ';') fieldEndPos = c;
fieldLine[c] = structLines[i][structLineOffset + j];
c++; j++;
}
if (fieldLine[0] != '/') // Field line is not a comment
{
//printf("Struct field: %s_\n", fieldLine); // OK!
// Get struct field type and name
GetDataTypeAndName(fieldLine, fieldEndPos, structs[i].fieldType[structs[i].fieldCount], structs[i].fieldName[structs[i].fieldCount]);
// Get the field description
// We start skipping spaces in front of description comment
int descStart = fieldEndPos;
while ((fieldLine[descStart] != '/') && (fieldLine[descStart] != '\0')) descStart++;
int k = 0;
while ((fieldLine[descStart + k] != '\0') && (fieldLine[descStart + k] != '\n'))
{
structs[i].fieldDesc[structs[i].fieldCount][k] = fieldLine[descStart + k];
k++;
}
structs[i].fieldCount++;
}
}
j++;
}
}
for (int i = 0; i < MAX_STRUCTS_TO_PARSE; i++) free(structLines[i]);
free(structLines);
// Enum info data
EnumInfo *enums = (EnumInfo *)calloc(MAX_ENUMS_TO_PARSE, sizeof(EnumInfo));
for (int i = 0; i < enumCount; i++)
{
// TODO: Get enum description from lines[enumLines[i] - 1]
for (int j = 1; j < 256; j++) // Maximum number of lines following enum first line
{
char *linePtr = lines[enumLines[i] + j];
if ((linePtr[0] >= 'A') && (linePtr[0] <= 'Z'))
{
// Parse enum value line, possible options:
//ENUM_VALUE_NAME,
//ENUM_VALUE_NAME
//ENUM_VALUE_NAME = 99
//ENUM_VALUE_NAME = 99,
//ENUM_VALUE_NAME = 0x00000040, // Value description
// We start reading the value name
int c = 0;
while ((linePtr[c] != ',') &&
(linePtr[c] != ' ') &&
(linePtr[c] != '=') &&
(linePtr[c] != '\0')) { enums[i].valueName[enums[i].valueCount][c] = linePtr[c]; c++; }
// After the name we can have:
// '=' -> value is provided
// ',' -> value is equal to previous + 1, there could be a description if not '\0'
// ' ' -> value is equal to previous + 1, there could be a description if not '\0'
// '\0' -> value is equal to previous + 1
// Let's start checking if the line is not finished
if ((linePtr[c] != ',') && (linePtr[c] != '\0'))
{
// Two options:
// '=' -> value is provided
// ' ' -> value is equal to previous + 1, there could be a description if not '\0'
bool foundValue = false;
while (linePtr[c] != '\0')
{
if (linePtr[c] == '=') { foundValue = true; break; }
c++;
}
if (foundValue)
{
if (linePtr[c + 1] == ' ') c += 2;
else c++;
// Parse integer value
int n = 0;
char integer[16] = { 0 };
while ((linePtr[c] != ',') && (linePtr[c] != ' ') && (linePtr[c] != '\0'))
{
integer[n] = linePtr[c];
c++; n++;
}
if (integer[1] == 'x') enums[i].valueInteger[enums[i].valueCount] = (int)strtol(integer, NULL, 16);
else enums[i].valueInteger[enums[i].valueCount] = atoi(integer);
}
else enums[i].valueInteger[enums[i].valueCount] = (enums[i].valueInteger[enums[i].valueCount - 1] + 1);
// TODO: Parse value description if any
}
else enums[i].valueInteger[enums[i].valueCount] = (enums[i].valueInteger[enums[i].valueCount - 1] + 1);
enums[i].valueCount++;
}
else if (linePtr[0] == '}')
{
// Get enum name from typedef
int c = 0;
while (linePtr[2 + c] != ';') { enums[i].name[c] = linePtr[2 + c]; c++; }
break; // Enum ended, break for() loop
}
}
}
// Functions info data
FunctionInfo *funcs = (FunctionInfo *)calloc(MAX_FUNCS_TO_PARSE, sizeof(FunctionInfo));
for (int i = 0; i < funcCount; i++)
{
int funcParamsStart = 0;
int funcEnd = 0;
// Get return type and function name from func line
for (int c = 0; (c < MAX_LINE_LENGTH) && (funcLines[i][c] != '\n'); c++)
{
if (funcLines[i][c] == '(') // Starts function parameters
{
funcParamsStart = c + 1;
// At this point we have function return type and function name
char funcRetTypeName[128] = { 0 };
int funcRetTypeNameLen = c - 6; // Substract "RLAPI "
MemoryCopy(funcRetTypeName, &funcLines[i][6], funcRetTypeNameLen);
GetDataTypeAndName(funcRetTypeName, funcRetTypeNameLen, funcs[i].retType, funcs[i].name);
break;
}
}
// Get parameters from func line
for (int c = funcParamsStart; c < MAX_LINE_LENGTH; c++)
{
if (funcLines[i][c] == ',') // Starts function parameters
{
// Get parameter type + name, extract info
char funcParamTypeName[128] = { 0 };
int funcParamTypeNameLen = c - funcParamsStart;
MemoryCopy(funcParamTypeName, &funcLines[i][funcParamsStart], funcParamTypeNameLen);
GetDataTypeAndName(funcParamTypeName, funcParamTypeNameLen, funcs[i].paramType[funcs[i].paramCount], funcs[i].paramName[funcs[i].paramCount]);
funcParamsStart = c + 1;
if (funcLines[i][c + 1] == ' ') funcParamsStart += 1;
funcs[i].paramCount++; // Move to next parameter
}
else if (funcLines[i][c] == ')')
{
funcEnd = c + 2;
// Check if previous word is void
if ((funcLines[i][c - 4] == 'v') && (funcLines[i][c - 3] == 'o') && (funcLines[i][c - 2] == 'i') && (funcLines[i][c - 1] == 'd')) break;
// Get parameter type + name, extract info
char funcParamTypeName[128] = { 0 };
int funcParamTypeNameLen = c - funcParamsStart;
MemoryCopy(funcParamTypeName, &funcLines[i][funcParamsStart], funcParamTypeNameLen);
GetDataTypeAndName(funcParamTypeName, funcParamTypeNameLen, funcs[i].paramType[funcs[i].paramCount], funcs[i].paramName[funcs[i].paramCount]);
funcs[i].paramCount++; // Move to next parameter
break;
}
}
// Get function description
for (int c = funcEnd; c < MAX_LINE_LENGTH; c++)
{
if (funcLines[i][c] == '/')
{
MemoryCopy(funcs[i].desc, &funcLines[i][c], 127); // WARNING: Size could be too long for funcLines[i][c]?
break;
}
}
}
for (int i = 0; i < linesCount; i++) free(lines[i]);
free(lines);
free(funcLines);
// At this point, all raylib data has been parsed!
//-----------------------------------------------------------------------------------------
// structs[] -> We have all the structs decomposed into pieces for further analysis
// enums[] -> We have all the enums decomposed into pieces for further analysis
// funcs[] -> We have all the functions decomposed into pieces for further analysis
// Print structs info
printf("\nStructures found: %i\n\n", structCount);
for (int i = 0; i < structCount; i++)
{
printf("Struct %02i: %s (%i fields)\n", i + 1, structs[i].name, structs[i].fieldCount);
//printf("Description: %s\n", structs[i].desc);
for (int f = 0; f < structs[i].fieldCount; f++) printf(" Fields %i: %s %s %s\n", f + 1, structs[i].fieldType[f], structs[i].fieldName[f], structs[i].fieldDesc[f]);
}
// Print enums info
printf("\nEnums found: %i\n\n", enumCount);
for (int i = 0; i < enumCount; i++)
{
printf("Enum %02i: %s (%i values)\n", i + 1, enums[i].name, enums[i].valueCount);
//printf("Description: %s\n", enums[i].desc);
for (int e = 0; e < enums[i].valueCount; e++) printf(" Value %s: %i\n", enums[i].valueName[e], enums[i].valueInteger[e]);
}
// Print function info
printf("\nFunctions found: %i\n\n", funcCount);
for (int i = 0; i < funcCount; i++)
{
printf("Function %03i: %s() (%i input parameters)\n", i + 1, funcs[i].name, funcs[i].paramCount);
printf(" Description: %s\n", funcs[i].desc);
printf(" Return type: %s\n", funcs[i].retType);
for (int p = 0; p < funcs[i].paramCount; p++) printf(" Param %i: %s (type: %s)\n", p + 1, funcs[i].paramName[p], funcs[i].paramType[p]);
if (funcs[i].paramCount == 0) printf(" No input parameters\n");
}
free(funcs);
free(structs);
free(enums);
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Load text data from file, returns a '\0' terminated string
// NOTE: text chars array should be freed manually
char *LoadFileText(const char *fileName, int *length)
{
char *text = NULL;
if (fileName != NULL)
{
FILE *file = fopen(fileName, "rt");
if (file != NULL)
{
// WARNING: When reading a file as 'text' file,
// text mode causes carriage return-linefeed translation...
// ...but using fseek() should return correct byte-offset
fseek(file, 0, SEEK_END);
int size = ftell(file);
fseek(file, 0, SEEK_SET);
if (size > 0)
{
*length = size;
text = (char *)calloc((size + 1), sizeof(char));
unsigned int count = (unsigned int)fread(text, sizeof(char), size, file);
// WARNING: \r\n is converted to \n on reading, so,
// read bytes count gets reduced by the number of lines
if (count < (unsigned int)size) text = realloc(text, count + 1);
// Zero-terminate the string
text[count] = '\0';
}
fclose(file);
}
}
return text;
}
// Get all lines from a text buffer (expecting lines ending with '\n')
char **GetTextLines(const char *buffer, int length, int *linesCount)
{
//#define MAX_LINE_LENGTH 512
// Get the number of lines in the text
int count = 0;
for (int i = 0; i < length; i++) if (buffer[i] == '\n') count++;
//printf("Number of text lines in buffer: %i\n", count);
// Allocate as many pointers as lines
char **lines = (char **)malloc(count*sizeof(char **));
char *bufferPtr = (char *)buffer;
for (int i = 0; (i < count) || (bufferPtr[0] != '\0'); i++)
{
lines[i] = (char *)calloc(MAX_LINE_LENGTH, sizeof(char));
// Remove line leading spaces
// Find last index of space/tab character
int index = 0;
while ((bufferPtr[index] == ' ') || (bufferPtr[index] == '\t')) index++;
int j = 0;
while (bufferPtr[index + j] != '\n')
{
lines[i][j] = bufferPtr[index + j];
j++;
}
bufferPtr += (index + j + 1);
}
*linesCount = count;
return lines;
}
// Get data type and name from a string containing both
// NOTE: Useful to parse function parameters and struct fields
void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type, char *name)
{
for (int k = typeNameLen; k > 0; k--)
{
if (typeName[k] == ' ')
{
// Function name starts at this point (and ret type finishes at this point)
MemoryCopy(type, typeName, k);
MemoryCopy(name, typeName + k + 1, typeNameLen - k - 1);
break;
}
else if (typeName[k] == '*')
{
MemoryCopy(type, typeName, k + 1);
MemoryCopy(name, typeName + k + 1, typeNameLen - k - 1);
break;
}
}
}
// Custom memcpy() to avoid <string.h>
void MemoryCopy(void *dest, const void *src, unsigned int count)
{
char *srcPtr = (char *)src;
char *destPtr = (char *)dest;
for (unsigned int i = 0; i < count; i++) destPtr[i] = srcPtr[i];
}
// Compare two text strings, requires number of characters to compare
bool IsTextEqual(const char *text1, const char *text2, unsigned int count)
{
bool result = true;
for (unsigned int i = 0; i < count; i++)
{
if (text1[i] != text2[i])
{
result = false;
break;
}
}
return result;
}
/*
// Replace text string
// REQUIRES: strlen(), strstr(), strncpy(), strcpy() -> TODO: Replace by custom implementations!
// WARNING: Returned buffer must be freed by the user (if return != NULL)
char *TextReplace(char *text, const char *replace, const char *by)
{
// Sanity checks and initialization
if (!text || !replace || !by) return NULL;
char *result;
char *insertPoint; // Next insert point
char *temp; // Temp pointer
int replaceLen; // Replace string length of (the string to remove)
int byLen; // Replacement length (the string to replace replace by)
int lastReplacePos; // Distance between replace and end of last replace
int count; // Number of replacements
replaceLen = strlen(replace);
if (replaceLen == 0) return NULL; // Empty replace causes infinite loop during count
byLen = strlen(by);
// Count the number of replacements needed
insertPoint = text;
for (count = 0; (temp = strstr(insertPoint, replace)); count++) insertPoint = temp + replaceLen;
// Allocate returning string and point temp to it
temp = result = (char *)malloc(strlen(text) + (byLen - replaceLen)*count + 1);
if (!result) return NULL; // Memory could not be allocated
// First time through the loop, all the variable are set correctly from here on,
// - 'temp' points to the end of the result string
// - 'insertPoint' points to the next occurrence of replace in text
// - 'text' points to the remainder of text after "end of replace"
while (count--)
{
insertPoint = strstr(text, replace);
lastReplacePos = (int)(insertPoint - text);
temp = strncpy(temp, text, lastReplacePos) + lastReplacePos;
temp = strcpy(temp, by) + byLen;
text += lastReplacePos + replaceLen; // Move to next "end of replace"
}
// Copy remaind text part after replacement to result (pointed by moving temp)
strcpy(temp, text);
return result;
}
*/

View File

@ -34,4 +34,11 @@ add_executable(${PROJECT_NAME} core_basic_window.c)
#set(raylib_VERBOSE 1) #set(raylib_VERBOSE 1)
target_link_libraries(${PROJECT_NAME} raylib) target_link_libraries(${PROJECT_NAME} raylib)
# Checks if OSX and links appropriate frameworks (Only required on MacOS)
if (APPLE)
target_link_libraries(${PROJECT_NAME} "-framework IOKit")
target_link_libraries(${PROJECT_NAME} "-framework Cocoa")
target_link_libraries(${PROJECT_NAME} "-framework OpenGL")
endif()
# That's it! You should have an example executable that you can run. Have fun! # That's it! You should have an example executable that you can run. Have fun!

View File

@ -252,6 +252,7 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\external\glfw\include</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\external\glfw\include</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<DebugInformationFormat />
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -291,6 +292,7 @@
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\external\glfw\include</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\external\glfw\include</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DebugInformationFormat />
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -252,6 +252,7 @@
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\external\glfw\include</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\external\glfw\include</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<DebugInformationFormat />
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -291,6 +292,7 @@
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\external\glfw\include</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\external\glfw\include</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DebugInformationFormat />
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -24,7 +24,6 @@ endif()
set(raylib_public_headers set(raylib_public_headers
raylib.h raylib.h
rlgl.h rlgl.h
physac.h
raymath.h raymath.h
raudio.h raudio.h
) )

View File

@ -43,8 +43,8 @@
.PHONY: all clean install uninstall .PHONY: all clean install uninstall
# Define required raylib variables # Define required raylib variables
RAYLIB_VERSION = 3.7.0 RAYLIB_VERSION = 3.7.1
RAYLIB_API_VERSION = 370 RAYLIB_API_VERSION = 371
# Define raylib source code path # Define raylib source code path
RAYLIB_SRC_PATH ?= ../src RAYLIB_SRC_PATH ?= ../src

View File

@ -270,12 +270,6 @@
#include <emscripten/html5.h> // Emscripten HTML5 library #include <emscripten/html5.h> // Emscripten HTML5 library
#endif #endif
#if defined(SUPPORT_COMPRESSION_API)
// NOTE: Those declarations require stb_image and stb_image_write definitions, included in textures module
unsigned char *stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality);
char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen);
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -652,7 +646,7 @@ void InitWindow(int width, int height, const char *title)
#if defined(PLATFORM_UWP) #if defined(PLATFORM_UWP)
if (!UWPIsConfigured()) if (!UWPIsConfigured())
{ {
TRACELOG(LOG_ERROR, "UWP Functions have not been set yet, please set these before initializing raylib!"); TRACELOG(LOG_FATAL, "UWP Functions have not been set yet, please set these before initializing raylib!");
return; return;
} }
#endif #endif
@ -736,7 +730,12 @@ void InitWindow(int width, int height, const char *title)
// NOTE: returns true if window and graphic device has been initialized successfully // NOTE: returns true if window and graphic device has been initialized successfully
CORE.Window.ready = InitGraphicsDevice(width, height); CORE.Window.ready = InitGraphicsDevice(width, height);
if (!CORE.Window.ready) return; // If graphic device is no properly initialized, we end program
if (!CORE.Window.ready)
{
TRACELOG(LOG_FATAL, "Failed to initialize Graphic Device");
return;
}
// Init hi-res timer // Init hi-res timer
InitTimer(); InitTimer();
@ -2035,8 +2034,8 @@ void EndShaderMode(void)
rlSetShader(rlGetShaderDefault()); rlSetShader(rlGetShaderDefault());
} }
// Begin blending mode (alpha, additive, multiplied) // Begin blending mode (alpha, additive, multiplied, subtract, custom)
// NOTE: Only 3 blending modes supported, default blend mode is alpha // NOTE: Blend modes supported are enumerated in BlendMode enum
void BeginBlendMode(int mode) void BeginBlendMode(int mode)
{ {
rlSetBlendMode(mode); rlSetBlendMode(mode);
@ -2179,8 +2178,8 @@ Shader LoadShader(const char *vsFileName, const char *fsFileName)
shader.id = rlLoadShaderCode(vShaderStr, fShaderStr); shader.id = rlLoadShaderCode(vShaderStr, fShaderStr);
if (vShaderStr != NULL) RL_FREE(vShaderStr); if (vShaderStr != NULL) UnloadFileText(vShaderStr);
if (fShaderStr != NULL) RL_FREE(fShaderStr); if (fShaderStr != NULL) UnloadFileText(fShaderStr);
// After shader loading, we TRY to set default location names // After shader loading, we TRY to set default location names
if (shader.id > 0) if (shader.id > 0)
@ -2801,8 +2800,8 @@ char **GetDirectoryFiles(const char *dirPath, int *fileCount)
ClearDirectoryFiles(); ClearDirectoryFiles();
// Memory allocation for MAX_DIRECTORY_FILES // Memory allocation for MAX_DIRECTORY_FILES
dirFilesPath = (char **)RL_MALLOC(sizeof(char *)*MAX_DIRECTORY_FILES); dirFilesPath = (char **)RL_MALLOC(MAX_DIRECTORY_FILES*sizeof(char *));
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) dirFilesPath[i] = (char *)RL_MALLOC(sizeof(char)*MAX_FILEPATH_LENGTH); for (int i = 0; i < MAX_DIRECTORY_FILES; i++) dirFilesPath[i] = (char *)RL_MALLOC(MAX_FILEPATH_LENGTH*sizeof(char));
int counter = 0; int counter = 0;
struct dirent *entity; struct dirent *entity;
@ -3543,7 +3542,7 @@ static bool InitGraphicsDevice(int width, int height)
CORE.Window.display.width = mode->width; CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height; CORE.Window.display.height = mode->height;
// Screen size security check // Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width; if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height; if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
#endif // PLATFORM_DESKTOP #endif // PLATFORM_DESKTOP
@ -4914,6 +4913,7 @@ static void SwapBuffers(void)
{ {
gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO); gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
} }
CORE.Window.prevBO = bo; CORE.Window.prevBO = bo;
#endif // PLATFORM_DRM #endif // PLATFORM_DRM
#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_UWP #endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_UWP
@ -5151,11 +5151,11 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
{ {
ClearDroppedFiles(); ClearDroppedFiles();
CORE.Window.dropFilesPath = (char **)RL_MALLOC(sizeof(char *)*count); CORE.Window.dropFilesPath = (char **)RL_MALLOC(count*sizeof(char *));
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
CORE.Window.dropFilesPath[i] = (char *)RL_MALLOC(sizeof(char)*MAX_FILEPATH_LENGTH); CORE.Window.dropFilesPath[i] = (char *)RL_MALLOC(MAX_FILEPATH_LENGTH*sizeof(char));
strcpy(CORE.Window.dropFilesPath[i], paths[i]); strcpy(CORE.Window.dropFilesPath[i], paths[i]);
} }
@ -6268,15 +6268,15 @@ bool UWPIsConfigured()
{ {
bool pass = true; bool pass = true;
if (uwpQueryTimeFunc == NULL) { TRACELOG(LOG_ERROR, "UWP: UWPSetQueryTimeFunc() must be called with a valid function before InitWindow()"); pass = false; } if (uwpQueryTimeFunc == NULL) { TRACELOG(LOG_WARNING, "UWP: UWPSetQueryTimeFunc() must be called with a valid function before InitWindow()"); pass = false; }
if (uwpSleepFunc == NULL) { TRACELOG(LOG_ERROR, "UWP: UWPSetSleepFunc() must be called with a valid function before InitWindow()"); pass = false; } if (uwpSleepFunc == NULL) { TRACELOG(LOG_WARNING, "UWP: UWPSetSleepFunc() must be called with a valid function before InitWindow()"); pass = false; }
if (uwpDisplaySizeFunc == NULL) { TRACELOG(LOG_ERROR, "UWP: UWPSetDisplaySizeFunc() must be called with a valid function before InitWindow()"); pass = false; } if (uwpDisplaySizeFunc == NULL) { TRACELOG(LOG_WARNING, "UWP: UWPSetDisplaySizeFunc() must be called with a valid function before InitWindow()"); pass = false; }
if (uwpMouseLockFunc == NULL) { TRACELOG(LOG_ERROR, "UWP: UWPSetMouseLockFunc() must be called with a valid function before InitWindow()"); pass = false; } if (uwpMouseLockFunc == NULL) { TRACELOG(LOG_WARNING, "UWP: UWPSetMouseLockFunc() must be called with a valid function before InitWindow()"); pass = false; }
if (uwpMouseUnlockFunc == NULL) { TRACELOG(LOG_ERROR, "UWP: UWPSetMouseUnlockFunc() must be called with a valid function before InitWindow()"); pass = false; } if (uwpMouseUnlockFunc == NULL) { TRACELOG(LOG_WARNING, "UWP: UWPSetMouseUnlockFunc() must be called with a valid function before InitWindow()"); pass = false; }
if (uwpMouseShowFunc == NULL) { TRACELOG(LOG_ERROR, "UWP: UWPSetMouseShowFunc() must be called with a valid function before InitWindow()"); pass = false; } if (uwpMouseShowFunc == NULL) { TRACELOG(LOG_WARNING, "UWP: UWPSetMouseShowFunc() must be called with a valid function before InitWindow()"); pass = false; }
if (uwpMouseHideFunc == NULL) { TRACELOG(LOG_ERROR, "UWP: UWPSetMouseHideFunc() must be called with a valid function before InitWindow()"); pass = false; } if (uwpMouseHideFunc == NULL) { TRACELOG(LOG_WARNING, "UWP: UWPSetMouseHideFunc() must be called with a valid function before InitWindow()"); pass = false; }
if (uwpMouseSetPosFunc == NULL) { TRACELOG(LOG_ERROR, "UWP: UWPSetMouseSetPosFunc() must be called with a valid function before InitWindow()"); pass = false; } if (uwpMouseSetPosFunc == NULL) { TRACELOG(LOG_WARNING, "UWP: UWPSetMouseSetPosFunc() must be called with a valid function before InitWindow()"); pass = false; }
if (uwpCoreWindow == NULL) { TRACELOG(LOG_ERROR, "UWP: A pointer to the UWP core window must be set before InitWindow()"); pass = false; } if (uwpCoreWindow == NULL) { TRACELOG(LOG_WARNING, "UWP: A pointer to the UWP core window must be set before InitWindow()"); pass = false; }
return pass; return pass;
} }

View File

@ -1027,7 +1027,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
if (instancing) if (instancing)
{ {
// Create instances buffer // Create instances buffer
instanceTransforms = RL_MALLOC(instances*sizeof(float16)); instanceTransforms = (float16 *)RL_MALLOC(instances*sizeof(float16));
// Fill buffer with instances transformations as float16 arrays // Fill buffer with instances transformations as float16 arrays
for (int i = 0; i < instances; i++) instanceTransforms[i] = MatrixToFloatV(transforms[i]); for (int i = 0; i < instances; i++) instanceTransforms[i] = MatrixToFloatV(transforms[i]);
@ -1461,9 +1461,9 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
animVertex = Vector3Subtract(animVertex, inTranslation); animVertex = Vector3Subtract(animVertex, inTranslation);
animVertex = Vector3RotateByQuaternion(animVertex, QuaternionMultiply(outRotation, QuaternionInvert(inRotation))); animVertex = Vector3RotateByQuaternion(animVertex, QuaternionMultiply(outRotation, QuaternionInvert(inRotation)));
animVertex = Vector3Add(animVertex, outTranslation); animVertex = Vector3Add(animVertex, outTranslation);
model.meshes[m].animVertices[vCounter] += animVertex.x * boneWeight; model.meshes[m].animVertices[vCounter] += animVertex.x*boneWeight;
model.meshes[m].animVertices[vCounter + 1] += animVertex.y * boneWeight; model.meshes[m].animVertices[vCounter + 1] += animVertex.y*boneWeight;
model.meshes[m].animVertices[vCounter + 2] += animVertex.z * boneWeight; model.meshes[m].animVertices[vCounter + 2] += animVertex.z*boneWeight;
// Normals processing // Normals processing
// NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals) // NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
@ -1471,9 +1471,9 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
{ {
animNormal = (Vector3){ model.meshes[m].normals[vCounter], model.meshes[m].normals[vCounter + 1], model.meshes[m].normals[vCounter + 2] }; animNormal = (Vector3){ model.meshes[m].normals[vCounter], model.meshes[m].normals[vCounter + 1], model.meshes[m].normals[vCounter + 2] };
animNormal = Vector3RotateByQuaternion(animNormal, QuaternionMultiply(outRotation, QuaternionInvert(inRotation))); animNormal = Vector3RotateByQuaternion(animNormal, QuaternionMultiply(outRotation, QuaternionInvert(inRotation)));
model.meshes[m].animNormals[vCounter] += animNormal.x * boneWeight; model.meshes[m].animNormals[vCounter] += animNormal.x*boneWeight;
model.meshes[m].animNormals[vCounter + 1] += animNormal.y * boneWeight; model.meshes[m].animNormals[vCounter + 1] += animNormal.y*boneWeight;
model.meshes[m].animNormals[vCounter + 2] += animNormal.z * boneWeight; model.meshes[m].animNormals[vCounter + 2] += animNormal.z*boneWeight;
} }
boneCounter += 1; boneCounter += 1;
} }
@ -2982,41 +2982,41 @@ bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius)
// Get collision info between ray and sphere // Get collision info between ray and sphere
RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius) RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius)
{ {
RayCollision result = { 0 }; RayCollision collision = { 0 };
Vector3 raySpherePos = Vector3Subtract(center, ray.position); Vector3 raySpherePos = Vector3Subtract(center, ray.position);
float vector = Vector3DotProduct(raySpherePos, ray.direction); float vector = Vector3DotProduct(raySpherePos, ray.direction);
float distance = Vector3Length(raySpherePos); float distance = Vector3Length(raySpherePos);
float d = radius*radius - (distance * distance - vector*vector); float d = radius*radius - (distance * distance - vector*vector);
result.hit = d >= 0.0f; collision.hit = d >= 0.0f;
// Check if ray origin is inside the sphere to calculate the correct collision point // Check if ray origin is inside the sphere to calculate the correct collision point
if (distance < radius) { // inside if (distance < radius) { // inside
result.distance = vector + sqrtf(d); collision.distance = vector + sqrtf(d);
// Calculate collision point // Calculate collision point
result.point = Vector3Add(ray.position, Vector3Scale(ray.direction, result.distance)); collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, collision.distance));
// Calculate collision normal (pointing outwards) // Calculate collision normal (pointing outwards)
result.normal = Vector3Negate(Vector3Normalize(Vector3Subtract(result.point, center))); collision.normal = Vector3Negate(Vector3Normalize(Vector3Subtract(collision.point, center)));
} else { // outside } else { // outside
result.distance = vector - sqrtf(d); collision.distance = vector - sqrtf(d);
// Calculate collision point // Calculate collision point
result.point = Vector3Add(ray.position, Vector3Scale(ray.direction, result.distance)); collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, collision.distance));
// Calculate collision normal (pointing inwards) // Calculate collision normal (pointing inwards)
result.normal = Vector3Normalize(Vector3Subtract(result.point, center)); collision.normal = Vector3Normalize(Vector3Subtract(collision.point, center));
} }
return result; return collision;
} }
// Get collision info between ray and bounding box // Get collision info between ray and box
RayCollision GetRayCollisionBox(Ray ray, BoundingBox box) RayCollision GetRayCollisionBox(Ray ray, BoundingBox box)
{ {
RayCollision result = { 0 }; RayCollision collision = { 0 };
// Note: If ray.position is inside the box, the distance is negative (as if the ray was reversed) // Note: If ray.position is inside the box, the distance is negative (as if the ray was reversed)
// Reversing ray.direction will give use the correct result. // Reversing ray.direction will give use the correct result.
@ -3044,42 +3044,42 @@ RayCollision GetRayCollisionBox(Ray ray, BoundingBox box)
t[6] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); t[6] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5]));
t[7] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); t[7] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5]));
result.hit = !(t[7] < 0 || t[6] > t[7]); collision.hit = !(t[7] < 0 || t[6] > t[7]);
result.distance = t[6]; collision.distance = t[6];
result.point = Vector3Add(ray.position, Vector3Scale(ray.direction, result.distance)); collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, collision.distance));
// Get box center point // Get box center point
result.normal = Vector3Lerp(box.min, box.max, 0.5f); collision.normal = Vector3Lerp(box.min, box.max, 0.5f);
// Get vector center point->hit point // Get vector center point->hit point
result.normal = Vector3Subtract(result.point, result.normal); collision.normal = Vector3Subtract(collision.point, collision.normal);
// Scale vector to unit cube // Scale vector to unit cube
// we use an additional .01 to fix numerical errors // we use an additional .01 to fix numerical errors
result.normal = Vector3Scale(result.normal, 2.01f); collision.normal = Vector3Scale(collision.normal, 2.01f);
result.normal = Vector3Divide(result.normal, Vector3Subtract(box.max, box.min)); collision.normal = Vector3Divide(collision.normal, Vector3Subtract(box.max, box.min));
// the relevant elemets of the vector are now slightly larger than 1.0f (or smaller than -1.0f) // the relevant elemets of the vector are now slightly larger than 1.0f (or smaller than -1.0f)
// and the others are somewhere between -1.0 and 1.0 // and the others are somewhere between -1.0 and 1.0
// casting to int is exactly our wanted normal! // casting to int is exactly our wanted normal!
result.normal.x = (int)result.normal.x; collision.normal.x = (int)collision.normal.x;
result.normal.y = (int)result.normal.y; collision.normal.y = (int)collision.normal.y;
result.normal.z = (int)result.normal.z; collision.normal.z = (int)collision.normal.z;
result.normal = Vector3Normalize(result.normal); collision.normal = Vector3Normalize(collision.normal);
if (insideBox) { if (insideBox) {
// Reset ray.direction // Reset ray.direction
ray.direction = Vector3Negate(ray.direction); ray.direction = Vector3Negate(ray.direction);
// Fix result // Fix result
result.distance *= -1.0f; collision.distance *= -1.0f;
result.normal = Vector3Negate(result.normal); collision.normal = Vector3Negate(collision.normal);
} }
return result; return collision;
} }
// Get collision info between ray and mesh // Get collision info between ray and mesh
RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform) RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform)
{ {
RayCollision result = { 0 }; RayCollision collision = { 0 };
// Check if mesh vertex data on CPU for testing // Check if mesh vertex data on CPU for testing
if (mesh.vertices != NULL) if (mesh.vertices != NULL)
@ -3114,17 +3114,18 @@ RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform)
if (triHitInfo.hit) if (triHitInfo.hit)
{ {
// Save the closest hit triangle // Save the closest hit triangle
if ((!result.hit) || (result.distance > triHitInfo.distance)) result = triHitInfo; if ((!collision.hit) || (collision.distance > triHitInfo.distance)) collision = triHitInfo;
} }
} }
} }
return result;
return collision;
} }
// Get collision info between ray and model // Get collision info between ray and model
RayCollision GetRayCollisionModel(Ray ray, Model model) RayCollision GetRayCollisionModel(Ray ray, Model model)
{ {
RayCollision result = { 0 }; RayCollision collision = { 0 };
for (int m = 0; m < model.meshCount; m++) for (int m = 0; m < model.meshCount; m++)
{ {
@ -3133,11 +3134,11 @@ RayCollision GetRayCollisionModel(Ray ray, Model model)
if (meshHitInfo.hit) if (meshHitInfo.hit)
{ {
// Save the closest hit mesh // Save the closest hit mesh
if ((!result.hit) || (result.distance > meshHitInfo.distance)) result = meshHitInfo; if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo;
} }
} }
return result; return collision;
} }
// Get collision info between ray and triangle // Get collision info between ray and triangle
@ -3147,10 +3148,11 @@ RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3
{ {
#define EPSILON 0.000001 // A small number #define EPSILON 0.000001 // A small number
Vector3 edge1, edge2; RayCollision collision = { 0 };
Vector3 edge1 = { 0 };
Vector3 edge2 = { 0 };
Vector3 p, q, tv; Vector3 p, q, tv;
float det, invDet, u, v, t; float det, invDet, u, v, t;
RayCollision result = {0};
// Find vectors for two edges sharing V1 // Find vectors for two edges sharing V1
edge1 = Vector3Subtract(p2, p1); edge1 = Vector3Subtract(p2, p1);
@ -3163,7 +3165,7 @@ RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3
det = Vector3DotProduct(edge1, p); det = Vector3DotProduct(edge1, p);
// Avoid culling! // Avoid culling!
if ((det > -EPSILON) && (det < EPSILON)) return result; if ((det > -EPSILON) && (det < EPSILON)) return collision;
invDet = 1.0f/det; invDet = 1.0f/det;
@ -3174,7 +3176,7 @@ RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3
u = Vector3DotProduct(tv, p)*invDet; u = Vector3DotProduct(tv, p)*invDet;
// The intersection lies outside of the triangle // The intersection lies outside of the triangle
if ((u < 0.0f) || (u > 1.0f)) return result; if ((u < 0.0f) || (u > 1.0f)) return collision;
// Prepare to test v parameter // Prepare to test v parameter
q = Vector3CrossProduct(tv, edge1); q = Vector3CrossProduct(tv, edge1);
@ -3183,20 +3185,20 @@ RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3
v = Vector3DotProduct(ray.direction, q)*invDet; v = Vector3DotProduct(ray.direction, q)*invDet;
// The intersection lies outside of the triangle // The intersection lies outside of the triangle
if ((v < 0.0f) || ((u + v) > 1.0f)) return result; if ((v < 0.0f) || ((u + v) > 1.0f)) return collision;
t = Vector3DotProduct(edge2, q)*invDet; t = Vector3DotProduct(edge2, q)*invDet;
if (t > EPSILON) if (t > EPSILON)
{ {
// Ray hit, get hit point and normal // Ray hit, get hit point and normal
result.hit = true; collision.hit = true;
result.distance = t; collision.distance = t;
result.normal = Vector3Normalize(Vector3CrossProduct(edge1, edge2)); collision.normal = Vector3Normalize(Vector3CrossProduct(edge1, edge2));
result.point = Vector3Add(ray.position, Vector3Scale(ray.direction, t)); collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, t));
} }
return result; return collision;
} }
// Get collision info between ray and quad // Get collision info between ray and quad
@ -3208,7 +3210,7 @@ RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Ve
if (!result.hit) result = GetRayCollisionTriangle(ray, p2, p3, p4); if (!result.hit) result = GetRayCollisionTriangle(ray, p2, p3, p4);
return result; return collision;
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -3228,11 +3230,11 @@ static Model LoadOBJ(const char *fileName)
tinyobj_material_t *materials = NULL; tinyobj_material_t *materials = NULL;
unsigned int materialCount = 0; unsigned int materialCount = 0;
char *fileData = LoadFileText(fileName); char *fileText = LoadFileText(fileName);
if (fileData != NULL) if (fileText != NULL)
{ {
unsigned int dataSize = (unsigned int)strlen(fileData); unsigned int dataSize = (unsigned int)strlen(fileText);
char currentDir[1024] = { 0 }; char currentDir[1024] = { 0 };
strcpy(currentDir, GetWorkingDirectory()); strcpy(currentDir, GetWorkingDirectory());
const char *workingDir = GetDirectoryPath(fileName); const char *workingDir = GetDirectoryPath(fileName);
@ -3242,7 +3244,7 @@ static Model LoadOBJ(const char *fileName)
} }
unsigned int flags = TINYOBJ_FLAG_TRIANGULATE; unsigned int flags = TINYOBJ_FLAG_TRIANGULATE;
int ret = tinyobj_parse_obj(&attrib, &meshes, &meshCount, &materials, &materialCount, fileData, dataSize, flags); int ret = tinyobj_parse_obj(&attrib, &meshes, &meshCount, &materials, &materialCount, fileText, dataSize, flags);
if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load OBJ data", fileName); if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load OBJ data", fileName);
else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount); else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount);
@ -3369,9 +3371,9 @@ static Model LoadOBJ(const char *fileName)
tinyobj_shapes_free(meshes, meshCount); tinyobj_shapes_free(meshes, meshCount);
tinyobj_materials_free(materials, materialCount); tinyobj_materials_free(materials, materialCount);
RL_FREE(fileData); UnloadFileText(fileText);
RL_FREE(matFaces);
RL_FREE(matFaces);
RL_FREE(vCount); RL_FREE(vCount);
RL_FREE(vtCount); RL_FREE(vtCount);
RL_FREE(vnCount); RL_FREE(vnCount);
@ -3481,7 +3483,7 @@ static Model LoadIQM(const char *fileName)
IQM_TANGENT = 3, // NOTE: Tangents unused by default IQM_TANGENT = 3, // NOTE: Tangents unused by default
IQM_BLENDINDEXES = 4, IQM_BLENDINDEXES = 4,
IQM_BLENDWEIGHTS = 5, IQM_BLENDWEIGHTS = 5,
IQM_COLOR = 6, // NOTE: Vertex colors unused by default IQM_COLOR = 6,
IQM_CUSTOM = 0x10 // NOTE: Custom vertex values unused by default IQM_CUSTOM = 0x10 // NOTE: Custom vertex values unused by default
}; };
@ -3497,6 +3499,7 @@ static Model LoadIQM(const char *fileName)
float *text = NULL; float *text = NULL;
char *blendi = NULL; char *blendi = NULL;
unsigned char *blendw = NULL; unsigned char *blendw = NULL;
unsigned char *color = NULL;
// In case file can not be read, return an empty model // In case file can not be read, return an empty model
if (fileDataPtr == NULL) return model; if (fileDataPtr == NULL) return model;
@ -3519,7 +3522,7 @@ static Model LoadIQM(const char *fileName)
//fileDataPtr += sizeof(IQMHeader); // Move file data pointer //fileDataPtr += sizeof(IQMHeader); // Move file data pointer
// Meshes data processing // Meshes data processing
imesh = RL_MALLOC(sizeof(IQMMesh)*iqmHeader->num_meshes); imesh = RL_MALLOC(iqmHeader->num_meshes*sizeof(IQMMesh));
//fseek(iqmFile, iqmHeader->ofs_meshes, SEEK_SET); //fseek(iqmFile, iqmHeader->ofs_meshes, SEEK_SET);
//fread(imesh, sizeof(IQMMesh)*iqmHeader->num_meshes, 1, iqmFile); //fread(imesh, sizeof(IQMMesh)*iqmHeader->num_meshes, 1, iqmFile);
memcpy(imesh, fileDataPtr + iqmHeader->ofs_meshes, iqmHeader->num_meshes*sizeof(IQMMesh)); memcpy(imesh, fileDataPtr + iqmHeader->ofs_meshes, iqmHeader->num_meshes*sizeof(IQMMesh));
@ -3685,6 +3688,25 @@ static Model LoadIQM(const char *fileName)
} }
} }
} break; } break;
case IQM_COLOR:
{
color = RL_MALLOC(iqmHeader->num_vertexes*4*sizeof(unsigned char));
//fseek(iqmFile, va[i].offset, SEEK_SET);
//fread(blendw, iqmHeader->num_vertexes*4*sizeof(unsigned char), 1, iqmFile);
memcpy(color, fileDataPtr + va[i].offset, iqmHeader->num_vertexes*4*sizeof(unsigned char));
for (unsigned int m = 0; m < iqmHeader->num_meshes; m++)
{
model.meshes[m].colors = RL_CALLOC(model.meshes[m].vertexCount*4, sizeof(unsigned char));
int vCounter = 0;
for (unsigned int i = imesh[m].first_vertex*4; i < (imesh[m].first_vertex + imesh[m].num_vertexes)*4; i++)
{
model.meshes[m].colors[vCounter] = color[i];
vCounter++;
}
}
} break;
} }
} }
@ -4324,6 +4346,40 @@ static Model LoadGLTF(const char *fileName)
TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName); TRACELOG(LOG_WARNING, "MODEL: [%s] glTF normals must be float or int", fileName);
} }
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color)
{
cgltf_accessor *acc = data->meshes[i].primitives[p].attributes[j].data;
model.meshes[primitiveIndex].colors = RL_MALLOC(acc->count*4*sizeof(unsigned char));
if (acc->component_type == cgltf_component_type_r_8u)
{
for (int a = 0; a < acc->count; a++)
{
GLTFReadValue(acc, a, model.meshes[primitiveIndex].colors + (a*4), 4, sizeof(unsigned char));
}
}
if (acc->component_type == cgltf_component_type_r_16u)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] converting glTF colors to unsigned char", fileName);
for (int a = 0; a < acc->count; a++)
{
unsigned short readValue[4];
for (int a = 0; a < acc->count; a++)
{
GLTFReadValue(acc, a, readValue, 4, sizeof(unsigned short));
// 257 = 65535/255
model.meshes[primitiveIndex].colors[(a*4) + 0] = (unsigned char)(readValue[0] / 257);
model.meshes[primitiveIndex].colors[(a*4) + 1] = (unsigned char)(readValue[1] / 257);
model.meshes[primitiveIndex].colors[(a*4) + 2] = (unsigned char)(readValue[2] / 257);
model.meshes[primitiveIndex].colors[(a*4) + 3] = (unsigned char)(readValue[3] / 257);
}
}
}
else
{
TRACELOG(LOG_WARNING, "MODEL: [%s] glTF colors must be uchar or ushort", fileName);
}
}
} }
cgltf_accessor *acc = data->meshes[i].primitives[p].indices; cgltf_accessor *acc = data->meshes[i].primitives[p].indices;
@ -4489,8 +4545,8 @@ static void LoadGLTFBoneAttribute(Model* model, cgltf_accessor* jointsAccessor,
{ {
if (jointsAccessor->component_type == cgltf_component_type_r_16u) if (jointsAccessor->component_type == cgltf_component_type_r_16u)
{ {
model->meshes[primitiveIndex].boneIds = RL_MALLOC(sizeof(int)*jointsAccessor->count*4); model->meshes[primitiveIndex].boneIds = RL_MALLOC(jointsAccessor->count*4*sizeof(int));
short* bones = RL_MALLOC(sizeof(short)*jointsAccessor->count*4); short* bones = RL_MALLOC(jointsAccessor->count*4*sizeof(short));
for (unsigned int a = 0; a < jointsAccessor->count; a++) for (unsigned int a = 0; a < jointsAccessor->count; a++)
{ {
@ -4514,8 +4570,8 @@ static void LoadGLTFBoneAttribute(Model* model, cgltf_accessor* jointsAccessor,
} }
else if (jointsAccessor->component_type == cgltf_component_type_r_8u) else if (jointsAccessor->component_type == cgltf_component_type_r_8u)
{ {
model->meshes[primitiveIndex].boneIds = RL_MALLOC(sizeof(int)*jointsAccessor->count*4); model->meshes[primitiveIndex].boneIds = RL_MALLOC(jointsAccessor->count*4*sizeof(int));
unsigned char* bones = RL_MALLOC(sizeof(unsigned char)*jointsAccessor->count*4); unsigned char* bones = RL_MALLOC(jointsAccessor->count*4*sizeof(unsigned char));
for (unsigned int a = 0; a < jointsAccessor->count; a++) for (unsigned int a = 0; a < jointsAccessor->count; a++)
{ {

View File

@ -276,25 +276,27 @@ typedef struct tagBITMAPINFOHEADER {
// NOTE: Depends on data structure provided by the library // NOTE: Depends on data structure provided by the library
// in charge of reading the different file types // in charge of reading the different file types
typedef enum { typedef enum {
MUSIC_AUDIO_NONE = 0, MUSIC_AUDIO_NONE = 0, // No audio context loaded
MUSIC_AUDIO_WAV, MUSIC_AUDIO_WAV, // WAV audio context
MUSIC_AUDIO_OGG, MUSIC_AUDIO_OGG, // OGG audio context
MUSIC_AUDIO_FLAC, MUSIC_AUDIO_FLAC, // FLAC audio context
MUSIC_AUDIO_MP3, MUSIC_AUDIO_MP3, // MP3 audio context
MUSIC_MODULE_XM, MUSIC_MODULE_XM, // XM module audio context
MUSIC_MODULE_MOD MUSIC_MODULE_MOD // MOD module audio context
} MusicContextType; } MusicContextType;
#if defined(RAUDIO_STANDALONE) #if defined(RAUDIO_STANDALONE)
// Trace log level
// NOTE: Organized by priority level
typedef enum { typedef enum {
LOG_ALL, LOG_ALL = 0, // Display all logs
LOG_TRACE, LOG_TRACE, // Trace logging, intended for internal use only
LOG_DEBUG, LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds
LOG_INFO, LOG_INFO, // Info logging, used for program execution info
LOG_WARNING, LOG_WARNING, // Warning logging, used on recoverable failures
LOG_ERROR, LOG_ERROR, // Error logging, used on unrecoverable failures
LOG_FATAL, LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE)
LOG_NONE LOG_NONE // Disable logging
} TraceLogLevel; } TraceLogLevel;
#endif #endif
@ -476,7 +478,7 @@ void InitAudioDevice(void)
// Init dummy audio buffers pool for multichannel sound playing // Init dummy audio buffers pool for multichannel sound playing
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++) for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
{ {
// WARNING: An empty audioBuffer is created (data = 0) // WARNING: An empty audio buffer is created (data = 0)
// AudioBuffer data just points to loaded sound data // AudioBuffer data just points to loaded sound data
AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC); AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
} }
@ -1428,13 +1430,13 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char* data, int d
#if defined(SUPPORT_FILEFORMAT_MOD) #if defined(SUPPORT_FILEFORMAT_MOD)
else if (TextIsEqual(fileExtLower, ".mod")) else if (TextIsEqual(fileExtLower, ".mod"))
{ {
jar_mod_context_t *ctxMod = RL_MALLOC(sizeof(jar_mod_context_t)); jar_mod_context_t *ctxMod = (jar_mod_context_t *)RL_MALLOC(sizeof(jar_mod_context_t));
int result = 0; int result = 0;
jar_mod_init(ctxMod); jar_mod_init(ctxMod);
// copy data to allocated memory for default UnloadMusicStream // Copy data to allocated memory for default UnloadMusicStream
unsigned char *newData = RL_MALLOC(dataSize); unsigned char *newData = (unsigned char *)RL_MALLOC(dataSize);
int it = dataSize/sizeof(unsigned char); int it = dataSize/sizeof(unsigned char);
for (int i = 0; i < it; i++){ for (int i = 0; i < it; i++){
newData[i] = data[i]; newData[i] = data[i];
@ -2073,6 +2075,7 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
// Sending audio data to device callback function // Sending audio data to device callback function
// This function will be called when miniaudio needs more data
// NOTE: All the mixing takes place here // NOTE: All the mixing takes place here
static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount) static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount)
{ {

View File

@ -81,7 +81,7 @@
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback #include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
#define RAYLIB_VERSION "3.7.0" #define RAYLIB_VERSION "3.8-dev"
#if defined(_WIN32) #if defined(_WIN32)
// Microsoft attibutes to tell compiler that symbols are imported/exported from a .dll // Microsoft attibutes to tell compiler that symbols are imported/exported from a .dll
@ -160,13 +160,14 @@
// Temporal hacks to avoid breaking old codebases using // Temporal hacks to avoid breaking old codebases using
// deprecated raylib implementation or definitions // deprecated raylib implementation or definitions
#define FormatText TextFormat #define SpriteFont Font
#define LoadText LoadFileText #define FormatText TextFormat
#define GetExtension GetFileExtension #define LoadText LoadFileText
#define GetImageData LoadImageColors #define GetExtension GetFileExtension
#define FILTER_POINT TEXTURE_FILTER_POINT #define GetImageData LoadImageColors
#define FILTER_BILINEAR TEXTURE_FILTER_BILINEAR #define FILTER_POINT TEXTURE_FILTER_POINT
#define MAP_DIFFUSE MATERIAL_MAP_DIFFUSE #define FILTER_BILINEAR TEXTURE_FILTER_BILINEAR
#define MAP_DIFFUSE MATERIAL_MAP_DIFFUSE
#define UNCOMPRESSED_R8G8B8A8 PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 #define UNCOMPRESSED_R8G8B8A8 PIXELFORMAT_UNCOMPRESSED_R8G8B8A8
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -176,59 +177,58 @@
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L #if defined(__STDC__) && __STDC_VERSION__ >= 199901L
#include <stdbool.h> #include <stdbool.h>
#elif !defined(__cplusplus) && !defined(bool) #elif !defined(__cplusplus) && !defined(bool)
typedef enum { false, true } bool; typedef enum bool { false, true } bool;
#endif #endif
// Vector2 type // Vector2, 2 components
typedef struct Vector2 { typedef struct Vector2 {
float x; float x; // Vector x component
float y; float y; // Vector y component
} Vector2; } Vector2;
// Vector3 type // Vector3, 3 components
typedef struct Vector3 { typedef struct Vector3 {
float x; float x; // Vector x component
float y; float y; // Vector y component
float z; float z; // Vector z component
} Vector3; } Vector3;
// Vector4 type // Vector4, 4 components
typedef struct Vector4 { typedef struct Vector4 {
float x; float x; // Vector x component
float y; float y; // Vector y component
float z; float z; // Vector z component
float w; float w; // Vector w component
} Vector4; } Vector4;
// Quaternion type, same as Vector4 // Quaternion, 4 components (Vector4 alias)
typedef Vector4 Quaternion; typedef Vector4 Quaternion;
// Matrix type (OpenGL style 4x4 - right handed, column major) // Matrix, 4x4 components, column major, OpenGL style, right handed
typedef struct Matrix { typedef struct Matrix {
float m0, m4, m8, m12; float m0, m4, m8, m12; // Matrix first row (4 components)
float m1, m5, m9, m13; float m1, m5, m9, m13; // Matrix second row (4 components)
float m2, m6, m10, m14; float m2, m6, m10, m14; // Matrix third row (4 components)
float m3, m7, m11, m15; float m3, m7, m11, m15; // Matrix fourth row (4 components)
} Matrix; } Matrix;
// Color type, RGBA (32bit) // Color, 4 components, R8G8B8A8 (32bit)
typedef struct Color { typedef struct Color {
unsigned char r; unsigned char r; // Color red value
unsigned char g; unsigned char g; // Color green value
unsigned char b; unsigned char b; // Color blue value
unsigned char a; unsigned char a; // Color alpha value
} Color; } Color;
// Rectangle type // Rectangle, 4 components
typedef struct Rectangle { typedef struct Rectangle {
float x; float x; // Rectangle top-left corner position x
float y; float y; // Rectangle top-left corner position y
float width; float width; // Rectangle width
float height; float height; // Rectangle height
} Rectangle; } Rectangle;
// Image type, bpp always RGBA (32bit) // Image, pixel data stored in CPU memory (RAM)
// NOTE: Data stored in CPU memory (RAM)
typedef struct Image { typedef struct Image {
void *data; // Image raw data void *data; // Image raw data
int width; // Image base width int width; // Image base width
@ -237,8 +237,7 @@ typedef struct Image {
int format; // Data format (PixelFormat type) int format; // Data format (PixelFormat type)
} Image; } Image;
// Texture type // Texture, tex data stored in GPU memory (VRAM)
// NOTE: Data stored in GPU memory
typedef struct Texture { typedef struct Texture {
unsigned int id; // OpenGL texture id unsigned int id; // OpenGL texture id
int width; // Texture base width int width; // Texture base width
@ -247,23 +246,23 @@ typedef struct Texture {
int format; // Data format (PixelFormat type) int format; // Data format (PixelFormat type)
} Texture; } Texture;
// Texture2D type, same as Texture // Texture2D, same as Texture
typedef Texture Texture2D; typedef Texture Texture2D;
// TextureCubemap type, actually, same as Texture // TextureCubemap, same as Texture
typedef Texture TextureCubemap; typedef Texture TextureCubemap;
// RenderTexture type, for texture rendering // RenderTexture, fbo for texture rendering
typedef struct RenderTexture { typedef struct RenderTexture {
unsigned int id; // OpenGL framebuffer object id unsigned int id; // OpenGL framebuffer object id
Texture texture; // Color buffer attachment texture Texture texture; // Color buffer attachment texture
Texture depth; // Depth buffer attachment texture Texture depth; // Depth buffer attachment texture
} RenderTexture; } RenderTexture;
// RenderTexture2D type, same as RenderTexture // RenderTexture2D, same as RenderTexture
typedef RenderTexture RenderTexture2D; typedef RenderTexture RenderTexture2D;
// N-Patch layout info // NPatchInfo, n-patch layout info
typedef struct NPatchInfo { typedef struct NPatchInfo {
Rectangle source; // Texture source rectangle Rectangle source; // Texture source rectangle
int left; // Left border offset int left; // Left border offset
@ -273,7 +272,7 @@ typedef struct NPatchInfo {
int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1 int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1
} NPatchInfo; } NPatchInfo;
// Font character info // CharInfo, font character info
typedef struct CharInfo { typedef struct CharInfo {
int value; // Character value (Unicode) int value; // Character value (Unicode)
int offsetX; // Character offset X when drawing int offsetX; // Character offset X when drawing
@ -282,7 +281,7 @@ typedef struct CharInfo {
Image image; // Character image data Image image; // Character image data
} CharInfo; } CharInfo;
// Font type, includes texture and charSet array data // Font, font texture and CharInfo array data
typedef struct Font { typedef struct Font {
int baseSize; // Base size (default chars height) int baseSize; // Base size (default chars height)
int charsCount; // Number of characters int charsCount; // Number of characters
@ -292,9 +291,7 @@ typedef struct Font {
CharInfo *chars; // Characters info data CharInfo *chars; // Characters info data
} Font; } Font;
#define SpriteFont Font // SpriteFont type fallback, defaults to Font // Camera, defines position/orientation in 3d space
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera3D { typedef struct Camera3D {
Vector3 position; // Camera position Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at Vector3 target; // Camera target it looks-at
@ -305,7 +302,7 @@ typedef struct Camera3D {
typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
// Camera2D type, defines a 2d camera // Camera2D, defines position/orientation in 2d space
typedef struct Camera2D { typedef struct Camera2D {
Vector2 offset; // Camera offset (displacement from target) Vector2 offset; // Camera offset (displacement from target)
Vector2 target; // Camera target (rotation and zoom origin) Vector2 target; // Camera target (rotation and zoom origin)
@ -313,148 +310,145 @@ typedef struct Camera2D {
float zoom; // Camera zoom (scaling), should be 1.0f by default float zoom; // Camera zoom (scaling), should be 1.0f by default
} Camera2D; } Camera2D;
// Vertex data definning a mesh // Mesh, vertex data and vao/vbo
// NOTE: Data stored in CPU memory (and GPU)
typedef struct Mesh { typedef struct Mesh {
int vertexCount; // Number of vertices stored in arrays int vertexCount; // Number of vertices stored in arrays
int triangleCount; // Number of triangles stored (indexed or not) int triangleCount; // Number of triangles stored (indexed or not)
// Default vertex data // Default vertex data
float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5) float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)
unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
unsigned short *indices;// Vertex indices (in case vertex data comes indexed) unsigned short *indices; // Vertex indices (in case vertex data comes indexed)
// Animation vertex data // Animation vertex data
float *animVertices; // Animated vertex positions (after bones transformations) float *animVertices; // Animated vertex positions (after bones transformations)
float *animNormals; // Animated normals (after bones transformations) float *animNormals; // Animated normals (after bones transformations)
int *boneIds; // Vertex bone ids, up to 4 bones influence by vertex (skinning) int *boneIds; // Vertex bone ids, up to 4 bones influence by vertex (skinning)
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning)
// OpenGL identifiers // OpenGL identifiers
unsigned int vaoId; // OpenGL Vertex Array Object id unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int *vboId; // OpenGL Vertex Buffer Objects id (default vertex data) unsigned int *vboId; // OpenGL Vertex Buffer Objects id (default vertex data)
} Mesh; } Mesh;
// Shader type (generic) // Shader
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
int *locs; // Shader locations array (MAX_SHADER_LOCATIONS) int *locs; // Shader locations array (MAX_SHADER_LOCATIONS)
} Shader; } Shader;
// Material texture map // MaterialMap
typedef struct MaterialMap { typedef struct MaterialMap {
Texture2D texture; // Material map texture Texture2D texture; // Material map texture
Color color; // Material map color Color color; // Material map color
float value; // Material map value float value; // Material map value
} MaterialMap; } MaterialMap;
// Material type (generic) // Material, includes shader and maps
typedef struct Material { typedef struct Material {
Shader shader; // Material shader Shader shader; // Material shader
MaterialMap *maps; // Material maps array (MAX_MATERIAL_MAPS) MaterialMap *maps; // Material maps array (MAX_MATERIAL_MAPS)
float params[4]; // Material generic parameters (if required) float params[4]; // Material generic parameters (if required)
} Material; } Material;
// Transformation properties // Transform, vectex transformation data
typedef struct Transform { typedef struct Transform {
Vector3 translation; // Translation Vector3 translation; // Translation
Quaternion rotation; // Rotation Quaternion rotation; // Rotation
Vector3 scale; // Scale Vector3 scale; // Scale
} Transform; } Transform;
// Bone information // Bone, skeletal animation bone
typedef struct BoneInfo { typedef struct BoneInfo {
char name[32]; // Bone name char name[32]; // Bone name
int parent; // Bone parent int parent; // Bone parent
} BoneInfo; } BoneInfo;
// Model type // Model, meshes, materials and animation data
typedef struct Model { typedef struct Model {
Matrix transform; // Local transform matrix Matrix transform; // Local transform matrix
int meshCount; // Number of meshes int meshCount; // Number of meshes
int materialCount; // Number of materials int materialCount; // Number of materials
Mesh *meshes; // Meshes array Mesh *meshes; // Meshes array
Material *materials; // Materials array Material *materials; // Materials array
int *meshMaterial; // Mesh material number int *meshMaterial; // Mesh material number
// Animation data // Animation data
int boneCount; // Number of bones int boneCount; // Number of bones
BoneInfo *bones; // Bones information (skeleton) BoneInfo *bones; // Bones information (skeleton)
Transform *bindPose; // Bones base transformation (pose) Transform *bindPose; // Bones base transformation (pose)
} Model; } Model;
// Model animation // ModelAnimation
typedef struct ModelAnimation { typedef struct ModelAnimation {
int boneCount; // Number of bones int boneCount; // Number of bones
int frameCount; // Number of animation frames int frameCount; // Number of animation frames
BoneInfo *bones; // Bones information (skeleton) BoneInfo *bones; // Bones information (skeleton)
Transform **framePoses; // Poses array by frame Transform **framePoses; // Poses array by frame
} ModelAnimation; } ModelAnimation;
// Ray type (useful for raycast) // Ray, ray for raycasting
typedef struct Ray { typedef struct Ray {
Vector3 position; // Ray position (origin) Vector3 position; // Ray position (origin)
Vector3 direction; // Ray direction Vector3 direction; // Ray direction
} Ray; } Ray;
// Raycast hit information // RayCollision, ray hit information
typedef struct RayCollision { typedef struct RayCollision {
bool hit; // Did the ray hit something? bool hit; // Did the ray hit something?
float distance; // Distance to nearest hit float distance; // Distance to nearest hit
Vector3 point; // Point of nearest hit Vector3 point; // Point of nearest hit
Vector3 normal; // Surface normal of hit Vector3 normal; // Surface normal of hit
} RayCollision; } RayCollision;
// Bounding box type // BoundingBox
typedef struct BoundingBox { typedef struct BoundingBox {
Vector3 min; // Minimum vertex box-corner Vector3 min; // Minimum vertex box-corner
Vector3 max; // Maximum vertex box-corner Vector3 max; // Maximum vertex box-corner
} BoundingBox; } BoundingBox;
// Wave type, defines audio wave data // Wave, audio wave data
typedef struct Wave { typedef struct Wave {
unsigned int sampleCount; // Total number of samples (considering channels!) unsigned int sampleCount; // Total number of samples (considering channels!)
unsigned int sampleRate; // Frequency (samples per second) unsigned int sampleRate; // Frequency (samples per second)
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
unsigned int channels; // Number of channels (1-mono, 2-stereo) unsigned int channels; // Number of channels (1-mono, 2-stereo)
void *data; // Buffer data pointer void *data; // Buffer data pointer
} Wave; } Wave;
typedef struct rAudioBuffer rAudioBuffer; typedef struct rAudioBuffer rAudioBuffer;
// Audio stream type // AudioStream, custom audio stream
// NOTE: Useful to create custom audio streams not bound to a specific file
typedef struct AudioStream { typedef struct AudioStream {
rAudioBuffer *buffer; // Pointer to internal data used by the audio system rAudioBuffer *buffer; // Pointer to internal data used by the audio system
unsigned int sampleRate; // Frequency (samples per second) unsigned int sampleRate; // Frequency (samples per second)
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
unsigned int channels; // Number of channels (1-mono, 2-stereo) unsigned int channels; // Number of channels (1-mono, 2-stereo)
} AudioStream; } AudioStream;
// Sound source type // Sound
typedef struct Sound { typedef struct Sound {
AudioStream stream; // Audio stream AudioStream stream; // Audio stream
unsigned int sampleCount; // Total number of samples unsigned int sampleCount; // Total number of samples
} Sound; } Sound;
// Music stream type (audio file streaming from memory) // Music, audio stream, anything longer than ~10 seconds should be streamed
// NOTE: Anything longer than ~10 seconds should be streamed
typedef struct Music { typedef struct Music {
AudioStream stream; // Audio stream AudioStream stream; // Audio stream
unsigned int sampleCount; // Total number of samples unsigned int sampleCount; // Total number of samples
bool looping; // Music looping enable bool looping; // Music looping enable
int ctxType; // Type of music context (audio filetype) int ctxType; // Type of music context (audio filetype)
void *ctxData; // Audio context data, depends on type void *ctxData; // Audio context data, depends on type
} Music; } Music;
// Head-Mounted-Display device parameters // VrDeviceInfo, Head-Mounted-Display device parameters
typedef struct VrDeviceInfo { typedef struct VrDeviceInfo {
int hResolution; // Horizontal resolution in pixels int hResolution; // Horizontal resolution in pixels
int vResolution; // Vertical resolution in pixels int vResolution; // Vertical resolution in pixels
@ -468,7 +462,7 @@ typedef struct VrDeviceInfo {
float chromaAbCorrection[4]; // Chromatic aberration correction parameters float chromaAbCorrection[4]; // Chromatic aberration correction parameters
} VrDeviceInfo; } VrDeviceInfo;
// VR Stereo rendering configuration for simulator // VrStereoConfig, VR stereo rendering configuration for simulator
typedef struct VrStereoConfig { typedef struct VrStereoConfig {
Matrix projection[2]; // VR projection matrices (per eye) Matrix projection[2]; // VR projection matrices (per eye)
Matrix viewOffset[2]; // VR view offset matrices (per eye) Matrix viewOffset[2]; // VR view offset matrices (per eye)
@ -504,14 +498,15 @@ typedef enum {
} ConfigFlags; } ConfigFlags;
// Trace log level // Trace log level
// NOTE: Organized by priority level
typedef enum { typedef enum {
LOG_ALL = 0, // Display all logs LOG_ALL = 0, // Display all logs
LOG_TRACE, LOG_TRACE, // Trace logging, intended for internal use only
LOG_DEBUG, LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds
LOG_INFO, LOG_INFO, // Info logging, used for program execution info
LOG_WARNING, LOG_WARNING, // Warning logging, used on recoverable failures
LOG_ERROR, LOG_ERROR, // Error logging, used on unrecoverable failures
LOG_FATAL, LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE)
LOG_NONE // Disable logging LOG_NONE // Disable logging
} TraceLogLevel; } TraceLogLevel;
@ -871,7 +866,7 @@ typedef enum {
GESTURE_SWIPE_DOWN = 128, GESTURE_SWIPE_DOWN = 128,
GESTURE_PINCH_IN = 256, GESTURE_PINCH_IN = 256,
GESTURE_PINCH_OUT = 512 GESTURE_PINCH_OUT = 512
} Gestures; } Gesture;
// Camera system modes // Camera system modes
typedef enum { typedef enum {
@ -898,9 +893,9 @@ typedef enum {
// Callbacks to hook some internal functions // Callbacks to hook some internal functions
// WARNING: This callbacks are intended for advance users // WARNING: This callbacks are intended for advance users
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
typedef unsigned char* (*LoadFileDataCallback)(const char* fileName, unsigned int* bytesRead); // FileIO: Load binary data typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, unsigned int *bytesRead); // FileIO: Load binary data
typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, unsigned int bytesToWrite); // FileIO: Save binary data typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, unsigned int bytesToWrite); // FileIO: Save binary data
typedef char *(*LoadFileTextCallback)(const char* fileName); // FileIO: Load text 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, char *text); // FileIO: Save text data
@ -970,15 +965,15 @@ RLAPI bool IsCursorOnScreen(void); // Check if cu
RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color) RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing
RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering) RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering)
RLAPI void BeginMode2D(Camera2D camera); // Initialize 2D mode with custom camera (2D) RLAPI void BeginMode2D(Camera2D camera); // Begin 2D mode with custom camera (2D)
RLAPI void EndMode2D(void); // Ends 2D mode with custom camera RLAPI void EndMode2D(void); // Ends 2D mode with custom camera
RLAPI void BeginMode3D(Camera3D camera); // Initializes 3D mode with custom camera (3D) RLAPI void BeginMode3D(Camera3D camera); // Begin 3D mode with custom camera (3D)
RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode RLAPI void EndMode3D(void); // Ends 3D mode and returns to default 2D orthographic mode
RLAPI void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing RLAPI void BeginTextureMode(RenderTexture2D target); // Begin drawing to render texture
RLAPI void EndTextureMode(void); // Ends drawing to render texture RLAPI void EndTextureMode(void); // Ends drawing to render texture
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader) RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied) RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied, subtract, custom)
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending) RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
RLAPI void BeginScissorMode(int x, int y, int width, int height); // Begin scissor mode (define screen area for following drawing) RLAPI void BeginScissorMode(int x, int y, int width, int height); // Begin scissor mode (define screen area for following drawing)
RLAPI void EndScissorMode(void); // End scissor mode RLAPI void EndScissorMode(void); // End scissor mode
@ -1021,7 +1016,7 @@ RLAPI int GetRandomValue(int min, int max); // Returns a r
RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format) RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (filename extension defines format)
RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS) RLAPI void SetConfigFlags(unsigned int flags); // Setup init configuration flags (view FLAGS)
RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR) RLAPI void TraceLog(int logLevel, const char *text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)
RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level RLAPI void SetTraceLogLevel(int logLevel); // Set the current threshold (minimum) log level
RLAPI void *MemAlloc(int size); // Internal memory allocator RLAPI void *MemAlloc(int size); // Internal memory allocator
RLAPI void *MemRealloc(void *ptr, int size); // Internal memory reallocator RLAPI void *MemRealloc(void *ptr, int size); // Internal memory reallocator
@ -1040,12 +1035,12 @@ RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead)
RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
RLAPI void UnloadFileText(unsigned char *text); // Unload file text data allocated by LoadFileText() 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, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
RLAPI bool FileExists(const char *fileName); // Check if file exists RLAPI bool FileExists(const char *fileName); // Check if file exists
RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists
RLAPI bool IsFileExtension(const char *fileName, const char *ext);// Check file extension (including point: .png, .wav) RLAPI bool IsFileExtension(const char *fileName, const char *ext);// Check file extension (including point: .png, .wav)
RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: ".png") RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png')
RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string) RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)
RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string) RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string)
@ -1143,7 +1138,7 @@ RLAPI void SetCameraMoveControls(int keyFront, int keyBack, int keyRight, int ke
// Set texture and rectangle to be used on shapes drawing // Set texture and rectangle to be used on shapes drawing
// NOTE: It can be useful when using basic shapes and one single font, // NOTE: It can be useful when using basic shapes and one single font,
// defining a font char white rectangle would allow drawing everything in a single draw call // defining a font char white rectangle would allow drawing everything in a single draw call
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
// Basic shapes drawing functions // Basic shapes drawing functions
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel
@ -1202,7 +1197,7 @@ RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2);
RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data) RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data)
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. ".png" RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success RLAPI bool ExportImageAsCode(Image image, const char *fileName); // Export image as code file defining an array of bytes, returns true on success
@ -1232,7 +1227,7 @@ RLAPI void ImageAlphaPremultiply(Image *image);
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm)
RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm)
RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color
RLAPI void ImageMipmaps(Image *image); // Generate all mipmap levels for a provided image RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally
@ -1319,7 +1314,7 @@ RLAPI Font GetFontDefault(void);
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCount); // Load font from file with extended parameters RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCount); // Load font from file with extended parameters
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount); // Load font from memory buffer, fileType refers to extension: i.e. ".ttf" RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
RLAPI CharInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount, int type); // Load font data for further use RLAPI CharInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount, int type); // Load font data for further use
RLAPI Image GenImageFontAtlas(const CharInfo *chars, Rectangle **recs, int charsCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info RLAPI Image GenImageFontAtlas(const CharInfo *chars, Rectangle **recs, int charsCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
RLAPI void UnloadFontData(CharInfo *chars, int charsCount); // Unload font chars info data (RAM) RLAPI void UnloadFontData(CharInfo *chars, int charsCount); // Unload font chars info data (RAM)
@ -1330,8 +1325,7 @@ RLAPI void DrawFPS(int posX, int posY);
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters
RLAPI void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits RLAPI void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
RLAPI void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, RLAPI void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint)
// Text misc. functions // Text misc. functions
@ -1433,7 +1427,7 @@ RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size);
RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
// Mesh manipulation functions // Mesh manipulation functions
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
@ -1470,7 +1464,7 @@ RLAPI void SetMasterVolume(float volume); // Set mas
// Wave/Sound loading/unloading functions // Wave/Sound loading/unloading functions
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. ".wav" RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
RLAPI Sound LoadSound(const char *fileName); // Load sound from file RLAPI Sound LoadSound(const char *fileName); // Load sound from file
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data

View File

@ -326,7 +326,7 @@ RMDEF Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance)
float dy = target.y - v.y; float dy = target.y - v.y;
float value = (dx*dx) + (dy*dy); float value = (dx*dx) + (dy*dy);
if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) result = target; if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance * maxDistance))) return target;
float dist = sqrtf(value); float dist = sqrtf(value);
@ -1390,22 +1390,27 @@ RMDEF Matrix QuaternionToMatrix(Quaternion q)
{ {
Matrix result = MatrixIdentity(); Matrix result = MatrixIdentity();
float a2 = 2*(q.x*q.x), b2=2*(q.y*q.y), c2=2*(q.z*q.z); //, d2=2*(q.w*q.w); float a2 = q.x*q.x;
float b2 = q.y*q.y;
float c2 = q.z*q.z;
float ac = q.x*q.z;
float ab = q.x*q.y;
float bc = q.y*q.z;
float ad = q.w*q.x;
float bd = q.w*q.y;
float cd = q.w*q.z;
float ab = 2*(q.x*q.y), ac=2*(q.x*q.z), bc=2*(q.y*q.z); result.m0 = 1 - 2*(b2 + c2);
float ad = 2*(q.x*q.w), bd=2*(q.y*q.w), cd=2*(q.z*q.w); result.m1 = 2*(ab + cd);
result.m2 = 2*(ac - bd);
result.m0 = 1 - b2 - c2; result.m4 = 2*(ab - cd);
result.m1 = ab - cd; result.m5 = 1 - 2*(a2 + c2);
result.m2 = ac + bd; result.m6 = 2*(bc + ad);
result.m4 = ab + cd; result.m8 = 2*(ac + bd);
result.m5 = 1 - a2 - c2; result.m9 = 2*(bc - ad);
result.m6 = bc - ad; result.m10 = 1 - 2*(a2 + b2);
result.m8 = ac - bd;
result.m9 = bc + ad;
result.m10 = 1 - a2 - b2;
return result; return result;
} }

View File

@ -329,16 +329,17 @@ typedef enum {
int *locs; // Shader locations array (MAX_SHADER_LOCATIONS) int *locs; // Shader locations array (MAX_SHADER_LOCATIONS)
} Shader; } Shader;
// TraceLog message types // Trace log level
// NOTE: Organized by priority level
typedef enum { typedef enum {
LOG_ALL, LOG_ALL = 0, // Display all logs
LOG_TRACE, LOG_TRACE, // Trace logging, intended for internal use only
LOG_DEBUG, LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds
LOG_INFO, LOG_INFO, // Info logging, used for program execution info
LOG_WARNING, LOG_WARNING, // Warning logging, used on recoverable failures
LOG_ERROR, LOG_ERROR, // Error logging, used on unrecoverable failures
LOG_FATAL, LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE)
LOG_NONE LOG_NONE // Disable logging
} TraceLogLevel; } TraceLogLevel;
// Texture formats (support depends on OpenGL version) // Texture formats (support depends on OpenGL version)
@ -1685,7 +1686,7 @@ void rlLoadExtensions(void *loader)
#if defined(SUPPORT_GL_DETAILS_INFO) #if defined(SUPPORT_GL_DETAILS_INFO)
// Get supported extensions list // Get supported extensions list
// WARNING: glGetStringi() not available on OpenGL 2.1 // WARNING: glGetStringi() not available on OpenGL 2.1
char **extList = RL_MALLOC(sizeof(char *)*numExt); char **extList = RL_MALLOC(numExt*sizeof(char *));
TRACELOG(LOG_INFO, "GL: OpenGL extensions:"); TRACELOG(LOG_INFO, "GL: OpenGL extensions:");
for (int i = 0; i < numExt; i++) for (int i = 0; i < numExt; i++)
{ {
@ -1966,7 +1967,7 @@ RenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes)
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
batch.vertexBuffer = (VertexBuffer *)RL_MALLOC(sizeof(VertexBuffer)*numBuffers); batch.vertexBuffer = (VertexBuffer *)RL_MALLOC(numBuffers*sizeof(VertexBuffer));
for (int i = 0; i < numBuffers; i++) for (int i = 0; i < numBuffers; i++)
{ {

View File

@ -1272,7 +1272,7 @@ const char *TextSubtext(const char *text, int position, int length)
// Replace text string // Replace text string
// REQUIRES: strstr(), strncpy(), strcpy() // REQUIRES: strstr(), strncpy(), strcpy()
// WARNING: Internally allocated memory must be freed by the user (if return != NULL) // WARNING: Returned buffer must be freed by the user (if return != NULL)
char *TextReplace(char *text, const char *replace, const char *by) char *TextReplace(char *text, const char *replace, const char *by)
{ {
// Sanity checks and initialization // Sanity checks and initialization
@ -1297,14 +1297,14 @@ char *TextReplace(char *text, const char *replace, const char *by)
for (count = 0; (temp = strstr(insertPoint, replace)); count++) insertPoint = temp + replaceLen; for (count = 0; (temp = strstr(insertPoint, replace)); count++) insertPoint = temp + replaceLen;
// Allocate returning string and point temp to it // Allocate returning string and point temp to it
temp = result = RL_MALLOC(TextLength(text) + (byLen - replaceLen)*count + 1); temp = result = (char *)RL_MALLOC(TextLength(text) + (byLen - replaceLen)*count + 1);
if (!result) return NULL; // Memory could not be allocated if (!result) return NULL; // Memory could not be allocated
// First time through the loop, all the variable are set correctly from here on, // First time through the loop, all the variable are set correctly from here on,
// temp points to the end of the result string // - 'temp' points to the end of the result string
// insertPoint points to the next occurrence of replace in text // - 'insertPoint' points to the next occurrence of replace in text
// text points to the remainder of text after "end of replace" // - 'text' points to the remainder of text after "end of replace"
while (count--) while (count--)
{ {
insertPoint = strstr(text, replace); insertPoint = strstr(text, replace);
@ -1865,7 +1865,7 @@ static Font LoadBMFont(const char *fileName)
} }
UnloadImage(imFont); UnloadImage(imFont);
RL_FREE(fileText); UnloadFileText(fileText);
if (font.texture.id == 0) if (font.texture.id == 0)
{ {

View File

@ -67,6 +67,7 @@
#include <stdlib.h> // Required for: malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strlen() [Used in ImageTextEx()] #include <string.h> // Required for: strlen() [Used in ImageTextEx()]
#include <math.h> // Required for: fabsf() #include <math.h> // Required for: fabsf()
#include <stdio.h> // Required for: sprintf() [Used in ExportImageAsCode()]
#include "utils.h" // Required for: fopen() Android mapping #include "utils.h" // Required for: fopen() Android mapping
@ -122,7 +123,7 @@
// NOTE: Used to read image data (multiple formats support) // NOTE: Used to read image data (multiple formats support)
#endif #endif
#if (defined(SUPPORT_IMAGE_EXPORT) || defined(SUPPORT_COMPRESSION_API)) #if defined(SUPPORT_IMAGE_EXPORT)
#define STBIW_MALLOC RL_MALLOC #define STBIW_MALLOC RL_MALLOC
#define STBIW_FREE RL_FREE #define STBIW_FREE RL_FREE
#define STBIW_REALLOC RL_REALLOC #define STBIW_REALLOC RL_REALLOC
@ -459,6 +460,8 @@ bool ExportImageAsCode(Image image, const char *fileName)
{ {
bool success = false; bool success = false;
#if defined(SUPPORT_IMAGE_EXPORT)
#ifndef TEXT_BYTES_PER_LINE #ifndef TEXT_BYTES_PER_LINE
#define TEXT_BYTES_PER_LINE 20 #define TEXT_BYTES_PER_LINE 20
#endif #endif
@ -501,6 +504,11 @@ bool ExportImageAsCode(Image image, const char *fileName)
RL_FREE(txtData); RL_FREE(txtData);
#endif // SUPPORT_IMAGE_EXPORT
if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image exported successfully", fileName);
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image", fileName);
return success; return success;
} }
@ -1354,7 +1362,7 @@ void ImageResize(Image *image, int newWidth, int newHeight)
if (fastPath) if (fastPath)
{ {
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *output = RL_MALLOC(newWidth*newHeight*bytesPerPixel); unsigned char *output = (unsigned char *)RL_MALLOC(newWidth*newHeight*bytesPerPixel);
switch (image->format) switch (image->format)
{ {

View File

@ -155,7 +155,7 @@ void TraceLog(int logType, const char *text, ...)
va_end(args); va_end(args);
if (logType == LOG_ERROR) exit(1); // If error, exit program if (logType == LOG_FATAL) exit(EXIT_FAILURE); // If fatal logging, exit program
#endif // SUPPORT_TRACELOG #endif // SUPPORT_TRACELOG
} }
@ -325,7 +325,7 @@ char *LoadFileText(const char *fileName)
} }
// Unload file text data allocated by LoadFileText() // Unload file text data allocated by LoadFileText()
void UnloadFileText(unsigned char *text) void UnloadFileText(char *text)
{ {
RL_FREE(text); RL_FREE(text);
} }

View File

@ -5,7 +5,7 @@
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* Copyright (c) 2020-2020 Reece Mackie (@Rover656) * Copyright (c) 2020-2021 Reece Mackie (@Rover656)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.