Merge branch 'raysan5:master' into master

This commit is contained in:
Crydsch 2021-06-01 17:32:32 +02:00
commit 7ac4a2920a
41 changed files with 3473 additions and 2731 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

@ -33,7 +33,7 @@ int main(void)
Ray ray = { 0 }; // Picking line ray Ray ray = { 0 }; // Picking line ray
bool collision = false; RayCollision collision = { 0 };
SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode
@ -49,16 +49,16 @@ int main(void)
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
{ {
if (!collision) if (!collision.hit)
{ {
ray = GetMouseRay(GetMousePosition(), camera); ray = GetMouseRay(GetMousePosition(), camera);
// Check collision between ray and box // Check collision between ray and box
collision = CheckCollisionRayBox(ray, 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 }});
} }
else collision = false; else collision.hit = false;
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -70,7 +70,7 @@ int main(void)
BeginMode3D(camera); BeginMode3D(camera);
if (collision) if (collision.hit)
{ {
DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED); DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED);
DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON); DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON);
@ -90,7 +90,7 @@ int main(void)
DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY); DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY);
if (collision) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, (int)(screenHeight * 0.1f), 30, GREEN); if (collision.hit) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, (int)(screenHeight * 0.1f), 30, GREEN);
DrawFPS(10, 10); DrawFPS(10, 10);

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

@ -98,7 +98,7 @@ int main(void)
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
{ {
// Check collision between ray and box // Check collision between ray and box
if (CheckCollisionRayBox(GetMouseRay(GetMousePosition(), camera), bounds)) selected = !selected; if (GetRayCollisionBox(GetMouseRay(GetMousePosition(), camera), bounds).hit) selected = !selected;
else selected = false; else selected = false;
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -63,53 +63,53 @@ int main(void)
UpdateCamera(&camera); // Update camera UpdateCamera(&camera); // Update camera
// Display information about closest hit // Display information about closest hit
RayHitInfo 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 ground, triangle, and mesh // Get ray and test against ground, triangle, and mesh
ray = GetMouseRay(GetMousePosition(), camera); ray = GetMouseRay(GetMousePosition(), camera);
// Check ray collision aginst ground plane // Check ray collision aginst ground plane
RayHitInfo groundHitInfo = GetCollisionRayGround(ray, 0.0f); RayCollision groundHitInfo = GetRayCollisionGround(ray, 0.0f);
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";
} }
// Check ray collision against test triangle // Check ray collision against test triangle
RayHitInfo triHitInfo = GetCollisionRayTriangle(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 = PURPLE; cursorColor = PURPLE;
hitObjectName = "Triangle"; hitObjectName = "Triangle";
bary = Vector3Barycenter(nearestHit.position, ta, tb, tc); bary = Vector3Barycenter(collision.point, ta, tb, tc);
hitTriangle = true; hitTriangle = true;
} }
else hitTriangle = false; else hitTriangle = false;
RayHitInfo meshHitInfo = { 0 }; RayCollision meshHitInfo = { 0 };
// Check ray collision against bounding box first, before trying the full ray-mesh test // Check ray collision against bounding box first, before trying the full ray-mesh test
if (CheckCollisionRayBox(ray, towerBBox)) if (GetRayCollisionBox(ray, towerBBox).hit)
{ {
hitMeshBBox = true; hitMeshBBox = true;
// Check ray collision against model // Check ray collision against model
// NOTE: It considers model.transform matrix! // NOTE: It considers model.transform matrix!
meshHitInfo = GetCollisionRayModel(ray, tower); meshHitInfo = GetRayCollisionModel(ray, tower);
if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance)) if ((meshHitInfo.hit) && (meshHitInfo.distance < collision.distance))
{ {
nearestHit = meshHitInfo; collision = meshHitInfo;
cursorColor = ORANGE; cursorColor = ORANGE;
hitObjectName = "Mesh"; hitObjectName = "Mesh";
} }
@ -128,7 +128,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
@ -140,17 +140,17 @@ int main(void)
if (hitMeshBBox) DrawBoundingBox(towerBBox, LIME); if (hitMeshBBox) 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.position, 0.3f, 0.3f, 0.3f, cursorColor); DrawCube(collision.point, 0.3f, 0.3f, 0.3f, cursorColor);
DrawCubeWires(nearestHit.position, 0.3f, 0.3f, 0.3f, RED); DrawCubeWires(collision.point, 0.3f, 0.3f, 0.3f, RED);
Vector3 normalEnd; Vector3 normalEnd;
normalEnd.x = nearestHit.position.x + nearestHit.normal.x; normalEnd.x = collision.point.x + collision.normal.x;
normalEnd.y = nearestHit.position.y + nearestHit.normal.y; normalEnd.y = collision.point.y + collision.normal.y;
normalEnd.z = nearestHit.position.z + nearestHit.normal.z; normalEnd.z = collision.point.z + collision.normal.z;
DrawLine3D(nearestHit.position, normalEnd, RED); DrawLine3D(collision.point, normalEnd, RED);
} }
DrawRay(ray, MAROON); DrawRay(ray, MAROON);
@ -162,21 +162,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.position.x, collision.point.x,
nearestHit.position.y, collision.point.y,
nearestHit.position.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 (hitTriangle) DrawText(TextFormat("Barycenter: %3.2f %3.2f %3.2f", bary.x, bary.y, bary.z), 10, ypos + 45, 10, BLACK); if (hitTriangle) 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,12 +1,5 @@
/*******************************************************************************************
*
* rPBR [shader] - Prefiltered environment for reflections fragment shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330 #version 330
#define MAX_SAMPLES 1024u #define MAX_SAMPLES 1024u
#define CUBEMAP_RESOLUTION 1024.0 #define CUBEMAP_RESOLUTION 1024.0

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;
} }
@ -2979,53 +2979,32 @@ bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius)
return collision; return collision;
} }
// Detect collision between ray and sphere // Get collision info between ray and sphere
bool CheckCollisionRaySphere(Ray ray, Vector3 center, float radius) RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius)
{ {
bool collision = false; RayCollision collision = { 0 };
Vector3 raySpherePos = Vector3Subtract(center, ray.position); Vector3 raySpherePos = Vector3Subtract(center, ray.position);
float distance = Vector3Length(raySpherePos); float distance = Vector3Length(raySpherePos);
float vector = Vector3DotProduct(raySpherePos, ray.direction); float vector = Vector3DotProduct(raySpherePos, ray.direction);
float d = radius*radius - (distance*distance - vector*vector); float d = radius*radius - (distance*distance - vector*vector);
if (d >= 0.0f) collision = true; if (d >= 0.0f) collision.hit = true;
return collision;
}
// Detect collision between ray and sphere with extended parameters and collision point detection
bool CheckCollisionRaySphereEx(Ray ray, Vector3 center, float radius, Vector3 *collisionPoint)
{
bool collision = false;
Vector3 raySpherePos = Vector3Subtract(center, ray.position);
float distance = Vector3Length(raySpherePos);
float vector = Vector3DotProduct(raySpherePos, ray.direction);
float d = radius*radius - (distance*distance - vector*vector);
if (d >= 0.0f) collision = true;
// Check if ray origin is inside the sphere to calculate the correct collision point // Check if ray origin is inside the sphere to calculate the correct collision point
float collisionDistance = 0; if (distance < radius) collision.distance = vector + sqrtf(d);
else collision.distance = vector - sqrtf(d);
if (distance < radius) collisionDistance = vector + sqrtf(d);
else collisionDistance = vector - sqrtf(d);
// Calculate collision point // Calculate collision point
Vector3 cPoint = Vector3Add(ray.position, Vector3Scale(ray.direction, collisionDistance)); collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, collision.distance));
collisionPoint->x = cPoint.x;
collisionPoint->y = cPoint.y;
collisionPoint->z = cPoint.z;
return collision; return collision;
} }
// Detect collision between ray and bounding box // Get collision info between ray and box
bool CheckCollisionRayBox(Ray ray, BoundingBox box) RayCollision GetRayCollisionBox(Ray ray, BoundingBox box)
{ {
bool collision = false; RayCollision collision = { 0 };
float t[8] = { 0 }; float t[8] = { 0 };
t[0] = (box.min.x - ray.position.x)/ray.direction.x; t[0] = (box.min.x - ray.position.x)/ray.direction.x;
@ -3037,14 +3016,17 @@ bool CheckCollisionRayBox(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]));
collision = !(t[7] < 0 || t[6] > t[7]); collision.hit = !(t[7] < 0 || t[6] > t[7]);
// TODO: Calculate other RayCollision data
return collision; return collision;
} }
// Get collision info between ray and mesh // Get collision info between ray and mesh
RayHitInfo GetCollisionRayMesh(Ray ray, Mesh mesh, Matrix transform) RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform)
{ {
RayHitInfo 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)
@ -3074,47 +3056,49 @@ RayHitInfo GetCollisionRayMesh(Ray ray, Mesh mesh, Matrix transform)
b = Vector3Transform(b, transform); b = Vector3Transform(b, transform);
c = Vector3Transform(c, transform); c = Vector3Transform(c, transform);
RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, a, b, c); RayCollision triHitInfo = GetRayCollisionTriangle(ray, a, b, c);
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
RayHitInfo GetCollisionRayModel(Ray ray, Model model) RayCollision GetRayCollisionModel(Ray ray, Model model)
{ {
RayHitInfo result = { 0 }; RayCollision collision = { 0 };
for (int m = 0; m < model.meshCount; m++) for (int m = 0; m < model.meshCount; m++)
{ {
RayHitInfo meshHitInfo = GetCollisionRayMesh(ray, model.meshes[m], model.transform); RayCollision meshHitInfo = GetRayCollisionMesh(ray, model.meshes[m], model.transform);
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
// NOTE: Based on https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm // NOTE: Based on https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3) 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;
RayHitInfo result = {0};
// Find vectors for two edges sharing V1 // Find vectors for two edges sharing V1
edge1 = Vector3Subtract(p2, p1); edge1 = Vector3Subtract(p2, p1);
@ -3127,7 +3111,7 @@ RayHitInfo GetCollisionRayTriangle(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;
@ -3138,7 +3122,7 @@ RayHitInfo GetCollisionRayTriangle(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);
@ -3147,29 +3131,28 @@ RayHitInfo GetCollisionRayTriangle(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.hit = true; collision.normal = Vector3Normalize(Vector3CrossProduct(edge1, edge2));
result.normal = Vector3Normalize(Vector3CrossProduct(edge1, edge2)); collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, t));
result.position = Vector3Add(ray.position, Vector3Scale(ray.direction, t));
} }
return result; return collision;
} }
// Get collision info between ray and ground plane (Y-normal plane) // Get collision info between ray and ground plane (Y-normal plane)
RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight) RayCollision GetRayCollisionGround(Ray ray, float groundHeight)
{ {
#define EPSILON 0.000001 // A small number #define EPSILON 0.000001 // A small number
RayHitInfo result = { 0 }; RayCollision collision = { 0 };
if (fabsf(ray.direction.y) > EPSILON) if (fabsf(ray.direction.y) > EPSILON)
{ {
@ -3177,15 +3160,15 @@ RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight)
if (distance >= 0.0) if (distance >= 0.0)
{ {
result.hit = true; collision.hit = true;
result.distance = distance; collision.distance = distance;
result.normal = (Vector3){ 0.0, 1.0, 0.0 }; collision.normal = (Vector3){ 0.0, 1.0, 0.0 };
result.position = Vector3Add(ray.position, Vector3Scale(ray.direction, distance)); collision.point = Vector3Add(ray.position, Vector3Scale(ray.direction, distance));
result.position.y = groundHeight; collision.point.y = groundHeight;
} }
} }
return result; return collision;
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -3205,11 +3188,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);
@ -3219,7 +3202,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);
@ -3346,9 +3329,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);
@ -3458,7 +3441,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
}; };
@ -3474,6 +3457,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;
@ -3496,7 +3480,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));
@ -3662,6 +3646,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;
} }
} }
@ -4301,6 +4304,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;
@ -4466,8 +4503,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++)
{ {
@ -4491,8 +4528,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,6 +160,7 @@
// 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 SpriteFont Font
#define FormatText TextFormat #define FormatText TextFormat
#define LoadText LoadFileText #define LoadText LoadFileText
#define GetExtension GetFileExtension #define GetExtension GetFileExtension
@ -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,8 +310,7 @@ 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)
@ -326,7 +322,7 @@ typedef struct Mesh {
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)
@ -339,40 +335,40 @@ typedef struct Mesh {
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
@ -388,7 +384,7 @@ typedef struct Model {
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
@ -396,27 +392,27 @@ typedef struct ModelAnimation {
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 RayHitInfo { 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 position; // Position of nearest hit Vector3 point; // Point of nearest hit
Vector3 normal; // Surface normal of hit Vector3 normal; // Surface normal of hit
} RayHitInfo; } 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)
@ -427,8 +423,7 @@ typedef struct 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
@ -437,14 +432,13 @@ typedef struct AudioStream {
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
@ -454,7 +448,7 @@ typedef struct Music {
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
@ -1451,13 +1445,12 @@ RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source,
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Detect collision between two spheres RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Detect collision between two spheres
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Detect collision between box and sphere RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Detect collision between box and sphere
RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 center, float radius); // Detect collision between ray and sphere RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 center, float radius, Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh RLAPI RayCollision GetRayCollisionModel(Ray ray, Model model); // Get collision info between ray and model
RLAPI RayHitInfo GetCollisionRayModel(Ray ray, Model model); // Get collision info between ray and model RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle RLAPI RayCollision GetRayCollisionGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane)
RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio) // Audio Loading and Playing Functions (Module: audio)
@ -1471,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.