mirror of
https://github.com/raysan5/raylib.git
synced 2026-10-24 02:09:38 -04:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 48f352c966 | |||
| 63d01d6237 | |||
| ad124dd7f5 | |||
| 7b677dd847 | |||
| 6095f71e54 | |||
| 4383fe1c22 | |||
| 1026cb9645 | |||
| c9fca4c15a | |||
| 5e63cf99a3 | |||
| 114a857bde | |||
| a40a167804 | |||
| 57c0764853 | |||
| bbdc73e324 | |||
| dcdbdde89b | |||
| 9c5d9f2856 | |||
| a750741cf8 | |||
| 2e66d4080c | |||
| ab1dde8fbb | |||
| f400535eb6 | |||
| d9ff09c3c9 | |||
| 9b6d185ef0 | |||
| 28789122ce | |||
| 5dc3674c00 | |||
| bf08870034 | |||
| 3061e73f0e | |||
| 986e8b0f1a | |||
| 777e17f9d4 | |||
| c4a49fd24f | |||
| dec2fdfbf8 | |||
| 3d5d33bc51 | |||
| 430439e63b | |||
| 226b281e55 | |||
| c757c7435a | |||
| b9758a6403 | |||
| 426d656185 | |||
| c0921587c3 | |||
| 8658e4e551 |
@ -28,6 +28,7 @@ This is a set of recomendations and guidelines for binding authors, meant to hel
|
|||||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **auto** | [Beef](https://www.beeflang.org) | MIT |
|
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **auto** | [Beef](https://www.beeflang.org) | MIT |
|
||||||
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||||
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib6.c3l) | **6** | [C3](https://c3-lang.org) | MIT |
|
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib6.c3l) | **6** | [C3](https://c3-lang.org) | MIT |
|
||||||
|
| [raylib.c3l](https://github.com/NexushasTaken/raylib.c3l) | **6.2** | [C3](https://c3-lang.org) | MIT |
|
||||||
| [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **6.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
| [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **6.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||||
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||||
| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
|
| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
|
||||||
@ -44,7 +45,7 @@ This is a set of recomendations and guidelines for binding authors, meant to hel
|
|||||||
| [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT |
|
| [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT |
|
||||||
| [raylib_dart](https://pub.dev/packages/raylib_dart) | 6.0 | [Dart](https://dart.dev) | MIT |
|
| [raylib_dart](https://pub.dev/packages/raylib_dart) | 6.0 | [Dart](https://dart.dev) | MIT |
|
||||||
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
|
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
|
||||||
| [raylib-d](https://github.com/schveiguy/raylib-d) | **6.0** | [D](https://dlang.org) | Zlib |
|
| [raylib-d](https://github.com/schveiguy/raylib-d) | **6.2** | [D](https://dlang.org) | Zlib |
|
||||||
| [Deno-Raylib](https://github.com/JJLDonley/Deno-Raylib) | **6.0** | [Deno / TS](https://deno.land) | MIT |
|
| [Deno-Raylib](https://github.com/JJLDonley/Deno-Raylib) | **6.0** | [Deno / TS](https://deno.land) | MIT |
|
||||||
| [rayex](https://github.com/shiryel/rayex) | 5.5 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
| [rayex](https://github.com/shiryel/rayex) | 5.5 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||||
| [raylib-elfscript](https://github.com/ohmtal/raylib-elfscript) | 6.0 | [ElfScript](https://github.com/ohmtal/ElfScript) | MIT |
|
| [raylib-elfscript](https://github.com/ohmtal/raylib-elfscript) | 6.0 | [ElfScript](https://github.com/ohmtal/ElfScript) | MIT |
|
||||||
@ -70,7 +71,7 @@ This is a set of recomendations and guidelines for binding authors, meant to hel
|
|||||||
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib |
|
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib |
|
||||||
| [raylib-luajit](https://github.com/homma/raylib-luajit) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
| [raylib-luajit](https://github.com/homma/raylib-luajit) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
||||||
| [raylib-luajit-generated](https://github.com/james2doyle/raylib-luajit-generated) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
| [raylib-luajit-generated](https://github.com/james2doyle/raylib-luajit-generated) | 5.5 | [Lua](http://www.lua.org) | MIT |
|
||||||
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | **???** |
|
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | MIT |
|
||||||
| [raylib_mojo](https://github.com/willGuimont/raylib_mojo) | **6.0** | [Mojo](https://www.modular.com/mojo) | ZLib |
|
| [raylib_mojo](https://github.com/willGuimont/raylib_mojo) | **6.0** | [Mojo](https://www.modular.com/mojo) | ZLib |
|
||||||
| [raymojo](https://github.com/RobertFlexx/raymojo) | **6.0** | [Mojo](https://www.modular.com/mojo) | GPLv3 |
|
| [raymojo](https://github.com/RobertFlexx/raymojo) | **6.0** | [Mojo](https://www.modular.com/mojo) | GPLv3 |
|
||||||
| [raymod](https://github.com/RobertFlexx/raymod) | **6.0** | [Modula-2](https://en.wikipedia.org/wiki/Modula-2) / [Modula-3](https://en.wikipedia.org/wiki/Modula-3) | Apache-2.0 |
|
| [raymod](https://github.com/RobertFlexx/raymod) | **6.0** | [Modula-2](https://en.wikipedia.org/wiki/Modula-2) / [Modula-3](https://en.wikipedia.org/wiki/Modula-3) | Apache-2.0 |
|
||||||
@ -83,7 +84,7 @@ This is a set of recomendations and guidelines for binding authors, meant to hel
|
|||||||
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
||||||
| [Rayberon](https://github.com/RobertFlexx/Rayberon) | **6.0** | [Oberon-2](https://en.wikipedia.org/wiki/Oberon-2) | MIT |
|
| [Rayberon](https://github.com/RobertFlexx/Rayberon) | **6.0** | [Oberon-2](https://en.wikipedia.org/wiki/Oberon-2) | MIT |
|
||||||
| [EuRaylib](https://github.com/gAndy50/EuRaylib6) | **6.0** | [openEuphoria](https://openeuphoria.org/) | Zlib |
|
| [EuRaylib](https://github.com/gAndy50/EuRaylib6) | **6.0** | [openEuphoria](https://openeuphoria.org/) | Zlib |
|
||||||
| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **6.0** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **6.2** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
||||||
| [Raylib.4.0.Pascal](https://github.com/sysrpl/Raylib.4.0.Pascal) | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
| [Raylib.4.0.Pascal](https://github.com/sysrpl/Raylib.4.0.Pascal) | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
||||||
| [raylib-python-cffi](https://github.com/electronstudio/raylib-python-cffi) | **6.0** | [Python](https://www.python.org) | EPL-2.0 |
|
| [raylib-python-cffi](https://github.com/electronstudio/raylib-python-cffi) | **6.0** | [Python](https://www.python.org) | EPL-2.0 |
|
||||||
| [raylibpyctbg](https://github.com/overdev/raylibpyctbg) | 5.5 | [Python](https://www.python.org) | MIT |
|
| [raylibpyctbg](https://github.com/overdev/raylibpyctbg) | 5.5 | [Python](https://www.python.org) | MIT |
|
||||||
|
|||||||
@ -689,6 +689,6 @@ Make sure to check raylib [CHANGELOG](https://github.com/raysan5/raylib/blob/mas
|
|||||||
|
|
||||||
Again, I want to **thank all the contributors (+950!**) that helped improving raylib, this time there have been **more than 100 new contributors** sending fixes and improvements!
|
Again, I want to **thank all the contributors (+950!**) that helped improving raylib, this time there have been **more than 100 new contributors** sending fixes and improvements!
|
||||||
|
|
||||||
After 13 years of development, `raylib 6.2` is today probably one of the bests libraries to enjoy **games/tools/graphics/AI programming!**
|
After 13 years of development, `raylib 6.2` is today probably one of the best libraries to enjoy **games/tools/graphics/AI programming!**
|
||||||
|
|
||||||
**Hope you keep enjoying programming with raylib!** :)
|
**Hope you keep enjoying programming with raylib!** :)
|
||||||
|
|||||||
@ -14,7 +14,7 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
|
|||||||
|
|
||||||
[](https://github.com/raysan5/raylib/releases)
|
[](https://github.com/raysan5/raylib/releases)
|
||||||
[](https://github.com/raysan5/raylib/stargazers)
|
[](https://github.com/raysan5/raylib/stargazers)
|
||||||
[](https://github.com/raysan5/raylib/commits/master)
|
[](https://github.com/raysan5/raylib/commits/master)
|
||||||
[](https://github.com/sponsors/raysan5)
|
[](https://github.com/sponsors/raysan5)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,8 @@ static int turtleTop = -1;
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static void PushTurtleState(TurtleState state);
|
static void PushTurtleState(TurtleState state);
|
||||||
static TurtleState PopTurtleState(void);
|
static TurtleState PopTurtleState(void);
|
||||||
static PenroseLSystem CreatePenroseLSystem(float drawLength);
|
static PenroseLSystem LoadPenroseLSystem(float drawLength);
|
||||||
|
static void UnloadPenroseLSystem(PenroseLSystem ls);
|
||||||
static void BuildProductionStep(PenroseLSystem *ls);
|
static void BuildProductionStep(PenroseLSystem *ls);
|
||||||
static void DrawPenroseLSystem(PenroseLSystem *ls);
|
static void DrawPenroseLSystem(PenroseLSystem *ls);
|
||||||
|
|
||||||
@ -77,8 +78,8 @@ int main(void)
|
|||||||
int maxGenerations = 4;
|
int maxGenerations = 4;
|
||||||
int generations = 0;
|
int generations = 0;
|
||||||
|
|
||||||
// Initializee new penrose tile
|
// Initialize new penrose tile
|
||||||
PenroseLSystem ls = CreatePenroseLSystem(drawLength*(generations/(float)maxGenerations));
|
PenroseLSystem ls = LoadPenroseLSystem(drawLength*(generations/(float)maxGenerations));
|
||||||
for (int i = 0; i < generations; i++) BuildProductionStep(&ls);
|
for (int i = 0; i < generations; i++) BuildProductionStep(&ls);
|
||||||
|
|
||||||
SetTargetFPS(120); // Set our game to run at 120 frames-per-second
|
SetTargetFPS(120); // Set our game to run at 120 frames-per-second
|
||||||
@ -109,8 +110,8 @@ int main(void)
|
|||||||
|
|
||||||
if (rebuild)
|
if (rebuild)
|
||||||
{
|
{
|
||||||
RL_FREE(ls.production); // Free previous production for re-creation
|
UnloadPenroseLSystem(ls); // Free previous production for re-creation
|
||||||
ls = CreatePenroseLSystem(drawLength*(generations/(float)maxGenerations));
|
ls = LoadPenroseLSystem(drawLength*(generations/(float)maxGenerations));
|
||||||
for (int i = 0; i < generations; i++) BuildProductionStep(&ls);
|
for (int i = 0; i < generations; i++) BuildProductionStep(&ls);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -119,7 +120,7 @@ int main(void)
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground( RAYWHITE );
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
if (generations > 0) DrawPenroseLSystem(&ls);
|
if (generations > 0) DrawPenroseLSystem(&ls);
|
||||||
|
|
||||||
@ -133,6 +134,8 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadPenroseLSystem(ls); // Free production string
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -158,10 +161,9 @@ static TurtleState PopTurtleState(void)
|
|||||||
return (TurtleState){ 0 };
|
return (TurtleState){ 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new penrose tile structure
|
// Load a new penrose tile structure
|
||||||
static PenroseLSystem CreatePenroseLSystem(float drawLength)
|
static PenroseLSystem LoadPenroseLSystem(float drawLength)
|
||||||
{
|
{
|
||||||
// TODO: Review constant values assignment on recreation?
|
|
||||||
PenroseLSystem ls = {
|
PenroseLSystem ls = {
|
||||||
.steps = 0,
|
.steps = 0,
|
||||||
.ruleW = "YF++ZF4-XF[-YF4-WF]++",
|
.ruleW = "YF++ZF4-XF[-YF4-WF]++",
|
||||||
@ -179,6 +181,12 @@ static PenroseLSystem CreatePenroseLSystem(float drawLength)
|
|||||||
return ls;
|
return ls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unload penrose tile structure
|
||||||
|
static void UnloadPenroseLSystem(PenroseLSystem ls)
|
||||||
|
{
|
||||||
|
RL_FREE(ls.production);
|
||||||
|
}
|
||||||
|
|
||||||
// Build next penrose step
|
// Build next penrose step
|
||||||
static void BuildProductionStep(PenroseLSystem *ls)
|
static void BuildProductionStep(PenroseLSystem *ls)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -41,6 +41,7 @@ int main(void)
|
|||||||
float donutInnerRadius = 25.0f;
|
float donutInnerRadius = 25.0f;
|
||||||
float values[MAX_PIE_SLICES] = { 300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f }; // Initial slice values
|
float values[MAX_PIE_SLICES] = { 300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f }; // Initial slice values
|
||||||
bool editingLabel[MAX_PIE_SLICES] = { 0 };
|
bool editingLabel[MAX_PIE_SLICES] = { 0 };
|
||||||
|
char labels[MAX_PIE_SLICES][32] = { 0 }; // Slice label texts, editable
|
||||||
|
|
||||||
bool showValues = true;
|
bool showValues = true;
|
||||||
bool showPercentages = false;
|
bool showPercentages = false;
|
||||||
@ -75,6 +76,9 @@ int main(void)
|
|||||||
// Total value for percentage calculations
|
// Total value for percentage calculations
|
||||||
float totalValue = 0.0f;
|
float totalValue = 0.0f;
|
||||||
|
|
||||||
|
// Initialize slice labels
|
||||||
|
for (int i = 0; i < MAX_PIE_SLICES; i++) snprintf(labels[i], 32, "Slice %02i", i + 1);
|
||||||
|
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -97,7 +101,7 @@ int main(void)
|
|||||||
float dy = mousePos.y - center.y;
|
float dy = mousePos.y - center.y;
|
||||||
float distance = sqrtf(dx*dx + dy*dy);
|
float distance = sqrtf(dx*dx + dy*dy);
|
||||||
|
|
||||||
if (distance <= radius) // Inside the pie radius
|
if ((distance <= radius) && (!showDonut || distance >= donutInnerRadius)) // Inside the pie, outside the donut hole
|
||||||
{
|
{
|
||||||
float angle = atan2f(dy, dx)*RAD2DEG;
|
float angle = atan2f(dy, dx)*RAD2DEG;
|
||||||
if (angle < 0) angle += 360;
|
if (angle < 0) angle += 360;
|
||||||
@ -134,11 +138,12 @@ int main(void)
|
|||||||
Color color = ColorFromHSV((float)i/sliceCount*360.0f, 0.75f, 0.9f);
|
Color color = ColorFromHSV((float)i/sliceCount*360.0f, 0.75f, 0.9f);
|
||||||
float currentRadius = radius;
|
float currentRadius = radius;
|
||||||
|
|
||||||
// Make the hovered slice pop out by adding 5 pixels to its radius
|
// Make the hovered slice pop out by adding 20 pixels to its radius
|
||||||
if (i == hoveredSlice) currentRadius += 20.0f;
|
if (i == hoveredSlice) currentRadius += 20.0f;
|
||||||
|
|
||||||
// Draw the pie slice using raylib's DrawCircleSector function
|
// Draw the pie slice (DrawRing() for donut mode)
|
||||||
DrawCircleSector(center, currentRadius, startAngle, startAngle + sweepAngle, 120, color);
|
if (showDonut) DrawRing(center, donutInnerRadius, currentRadius, startAngle, startAngle + sweepAngle, 120, color);
|
||||||
|
else DrawCircleSector(center, currentRadius, startAngle, startAngle + sweepAngle, 120, color);
|
||||||
|
|
||||||
// Draw the label for the current slice
|
// Draw the label for the current slice
|
||||||
if (values[i] > 0)
|
if (values[i] > 0)
|
||||||
@ -150,16 +155,12 @@ int main(void)
|
|||||||
else labelText[0] = '\0';
|
else labelText[0] = '\0';
|
||||||
|
|
||||||
Vector2 textSize = MeasureTextEx(GetFontDefault(), labelText, 20, 1);
|
Vector2 textSize = MeasureTextEx(GetFontDefault(), labelText, 20, 1);
|
||||||
float labelRadius = radius*0.7f;
|
float labelRadius = showDonut? (donutInnerRadius + radius)/2.0f : radius*0.7f;
|
||||||
Vector2 labelPos = { center.x + cosf(midAngle*DEG2RAD)*labelRadius - textSize.x/2.0f,
|
Vector2 labelPos = { center.x + cosf(midAngle*DEG2RAD)*labelRadius - textSize.x/2.0f,
|
||||||
center.y + sinf(midAngle*DEG2RAD)*labelRadius - textSize.y/2.0f };
|
center.y + sinf(midAngle*DEG2RAD)*labelRadius - textSize.y/2.0f };
|
||||||
DrawText(labelText, (int)labelPos.x, (int)labelPos.y, 20, WHITE);
|
DrawText(labelText, (int)labelPos.x, (int)labelPos.y, 20, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw inner circle to create donut effect
|
|
||||||
// TODO: This is a hacky solution, better use DrawRing()
|
|
||||||
if (showDonut) DrawCircleV(center, donutInnerRadius, RAYWHITE);
|
|
||||||
|
|
||||||
startAngle += sweepAngle;
|
startAngle += sweepAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ int main(void)
|
|||||||
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 70, 20, 20 }, "Show Percentages", &showPercentages);
|
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 70, 20, 20 }, "Show Percentages", &showPercentages);
|
||||||
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 100, 20, 20 }, "Make Donut", &showDonut);
|
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 100, 20, 20 }, "Make Donut", &showDonut);
|
||||||
|
|
||||||
if (showDonut) GuiDisable();
|
if (!showDonut) GuiDisable();
|
||||||
GuiSliderBar((Rectangle){ panelPos.x + 80, (float)panelPos.y + 12 + 130, panelRect.width - 100, 30 },
|
GuiSliderBar((Rectangle){ panelPos.x + 80, (float)panelPos.y + 12 + 130, panelRect.width - 100, 30 },
|
||||||
"Inner Radius", NULL, & donutInnerRadius, 5.0f, radius - 10.0f);
|
"Inner Radius", NULL, & donutInnerRadius, 5.0f, radius - 10.0f);
|
||||||
GuiEnable();
|
GuiEnable();
|
||||||
@ -184,7 +185,7 @@ int main(void)
|
|||||||
panelPos.x + panelMargin,
|
panelPos.x + panelMargin,
|
||||||
(float)panelPos.y + 12 + 190,
|
(float)panelPos.y + 12 + 190,
|
||||||
panelRect.width - panelMargin*2,
|
panelRect.width - panelMargin*2,
|
||||||
panelRect.y + panelRect.height - panelPos.y + 12 + 190 - panelMargin
|
panelRect.y + panelRect.height - (panelPos.y + 12 + 190) - panelMargin
|
||||||
};
|
};
|
||||||
int contentHeight = sliceCount*35;
|
int contentHeight = sliceCount*35;
|
||||||
|
|
||||||
@ -205,7 +206,7 @@ int main(void)
|
|||||||
DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
|
DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
|
||||||
|
|
||||||
// Label textbox
|
// Label textbox
|
||||||
if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, TextFormat("Slice %02i", i + 1), 32, editingLabel[i]))
|
if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, labels[i], 32, editingLabel[i]))
|
||||||
editingLabel[i] = !editingLabel[i];
|
editingLabel[i] = !editingLabel[i];
|
||||||
|
|
||||||
GuiSliderBar((Rectangle){ contentX + 130, (float)rowY, 110, 30 }, NULL, NULL, &values[i], 0.0f, 1000.0f);
|
GuiSliderBar((Rectangle){ contentX + 130, (float)rowY, 110, 30 }, NULL, NULL, &values[i], 0.0f, 1000.0f);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
* Example complexity rating: [★★★★] 4/4
|
* Example complexity rating: [★★★★] 4/4
|
||||||
*
|
*
|
||||||
* NOTE: Draw a 2D text in 3D space, each letter is drawn in a quad (or 2 quads if backface is set)
|
* NOTE: Draw a 2D text in 3D space, each letter is drawn in a quad (or 2 quads if backface is set)
|
||||||
* where the texture coodinates of each quad map to the texture coordinates of the glyphs
|
* where the texture coordinates of each quad map to the texture coordinates of the glyphs
|
||||||
* inside the font texture
|
* inside the font texture
|
||||||
*
|
*
|
||||||
* A more efficient approach, i believe, would be to render the text in a render texture and
|
* A more efficient approach, i believe, would be to render the text in a render texture and
|
||||||
@ -303,11 +303,11 @@ int main(void)
|
|||||||
DrawTextWave3D(font, text, (Vector3){ -tbox.x/2.0f, layerDistance*i, -4.5f }, fontSize, fontSpacing, lineSpacing, true, &wcfg, time, clr);
|
DrawTextWave3D(font, text, (Vector3){ -tbox.x/2.0f, layerDistance*i, -4.5f }, fontSize, fontSpacing, lineSpacing, true, &wcfg, time, clr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the text boundry if set
|
// Draw the text boundary if set
|
||||||
if (SHOW_TEXT_BOUNDRY) DrawCubeWiresV((Vector3){ 0.0f, 0.0f, -4.5f + tbox.z/2 }, tbox, dark);
|
if (SHOW_TEXT_BOUNDRY) DrawCubeWiresV((Vector3){ 0.0f, 0.0f, -4.5f + tbox.z/2 }, tbox, dark);
|
||||||
rlPopMatrix();
|
rlPopMatrix();
|
||||||
|
|
||||||
// Don't draw the letter boundries for the 3D text below
|
// Don't draw the letter boundaries for the 3D text below
|
||||||
bool slb = SHOW_LETTER_BOUNDRY;
|
bool slb = SHOW_LETTER_BOUNDRY;
|
||||||
SHOW_LETTER_BOUNDRY = false;
|
SHOW_LETTER_BOUNDRY = false;
|
||||||
|
|
||||||
@ -388,14 +388,14 @@ int main(void)
|
|||||||
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
|
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
|
||||||
pos.z += 0.5f + m.y;
|
pos.z += 0.5f + m.y;
|
||||||
|
|
||||||
opt = "press [F1] to toggle the letter boundry";
|
opt = "press [F1] to toggle the letter boundary";
|
||||||
quads += 39;
|
quads += 39;
|
||||||
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
|
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
|
||||||
pos.x = -m.x/2.0f;
|
pos.x = -m.x/2.0f;
|
||||||
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
|
DrawText3D(GetFontDefault(), opt, pos, 0.6f, 0.05f, 0.0f, false, DARKBLUE);
|
||||||
pos.z += 0.5f + m.y;
|
pos.z += 0.5f + m.y;
|
||||||
|
|
||||||
opt = "press [F2] to toggle the text boundry";
|
opt = "press [F2] to toggle the text boundary";
|
||||||
quads += 37;
|
quads += 37;
|
||||||
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
|
m = MeasureTextEx(GetFontDefault(), opt, 0.6f, 0.05f);
|
||||||
pos.x = -m.x/2.0f;
|
pos.x = -m.x/2.0f;
|
||||||
@ -543,8 +543,6 @@ static void DrawText3D(Font font, const char *text, Vector3 position, float font
|
|||||||
|
|
||||||
if (codepoint == '\n')
|
if (codepoint == '\n')
|
||||||
{
|
{
|
||||||
// NOTE: Fixed line spacing of 1.5 line-height
|
|
||||||
// TODO: Support custom line spacing defined by user
|
|
||||||
textOffsetY += fontSize + lineSpacing;
|
textOffsetY += fontSize + lineSpacing;
|
||||||
textOffsetX = 0.0f;
|
textOffsetX = 0.0f;
|
||||||
}
|
}
|
||||||
@ -589,8 +587,6 @@ static void DrawTextWave3D(Font font, const char *text, Vector3 position, float
|
|||||||
|
|
||||||
if (codepoint == '\n')
|
if (codepoint == '\n')
|
||||||
{
|
{
|
||||||
// NOTE: Fixed line spacing of 1.5 line-height
|
|
||||||
// TODO: Support custom line spacing defined by user
|
|
||||||
textOffsetY += fontSize + lineSpacing;
|
textOffsetY += fontSize + lineSpacing;
|
||||||
textOffsetX = 0.0f;
|
textOffsetX = 0.0f;
|
||||||
k = 0;
|
k = 0;
|
||||||
|
|||||||
@ -136,7 +136,7 @@ int main(void)
|
|||||||
DrawText(TextFormat("Duration (A | D): %d", (int)text.duration), 20, 20, 20, GRAY);
|
DrawText(TextFormat("Duration (A | D): %d", (int)text.duration), 20, 20, 20, GRAY);
|
||||||
DrawText(TextFormat("Delta (W | S): %.1f", text.delta), 20, 50, 20, GRAY);
|
DrawText(TextFormat("Delta (W | S): %.1f", text.delta), 20, 50, 20, GRAY);
|
||||||
DrawText(TextFormat("Offset (Z | X): %.1f", text.offset), 20, 80, 20, GRAY);
|
DrawText(TextFormat("Offset (Z | X): %.1f", text.offset), 20, 80, 20, GRAY);
|
||||||
DrawText(TextFormat("Curent Animation (Q | E): %s", animations[currentAnimation]), 20, 110, 20, GRAY);
|
DrawText(TextFormat("Current Animation (Q | E): %s", animations[currentAnimation]), 20, 110, 20, GRAY);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < TextLength(text.str); i++)
|
for (unsigned int i = 0; i < TextLength(text.str); i++)
|
||||||
{
|
{
|
||||||
|
|||||||
2
src/external/rltexgpu.h
vendored
2
src/external/rltexgpu.h
vendored
@ -605,8 +605,10 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
|
|||||||
// Calculate file data_size required
|
// Calculate file data_size required
|
||||||
int data_size = sizeof(ktx_header);
|
int data_size = sizeof(ktx_header);
|
||||||
|
|
||||||
|
// NOTE: Each mipmap level is stored as: UInt32 imageSize + pixel data
|
||||||
for (int i = 0, w = width, h = height; i < mipmaps; i++)
|
for (int i = 0, w = width, h = height; i < mipmaps; i++)
|
||||||
{
|
{
|
||||||
|
data_size += (int)sizeof(unsigned int);
|
||||||
data_size += get_pixel_data_size(w, h, format);
|
data_size += get_pixel_data_size(w, h, format);
|
||||||
w /= 2; h /= 2;
|
w /= 2; h /= 2;
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/external/tinyobj_loader_c.h
vendored
18
src/external/tinyobj_loader_c.h
vendored
@ -128,7 +128,7 @@ extern void tinyobj_materials_free(tinyobj_material_t *materials,
|
|||||||
#define TINYOBJ_FREE free
|
#define TINYOBJ_FREE free
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TINYOBJ_MAX_FACES_PER_F_LINE (16)
|
#define TINYOBJ_MAX_FACES_PER_F_LINE (64)
|
||||||
|
|
||||||
#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t'))
|
#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t'))
|
||||||
#define IS_DIGIT(x) ((unsigned int)((x) - '0') < (unsigned int)(10))
|
#define IS_DIGIT(x) ((unsigned int)((x) - '0') < (unsigned int)(10))
|
||||||
@ -1093,11 +1093,20 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
|
|||||||
tinyobj_vertex_index_t vi = parseRawTriple(&token);
|
tinyobj_vertex_index_t vi = parseRawTriple(&token);
|
||||||
skip_space_and_cr(&token);
|
skip_space_and_cr(&token);
|
||||||
|
|
||||||
|
// Guard the fixed-size f[] buffer against overrun.
|
||||||
|
if (num_f >= TINYOBJ_MAX_FACES_PER_F_LINE) return 0;
|
||||||
f[num_f] = vi;
|
f[num_f] = vi;
|
||||||
num_f++;
|
num_f++;
|
||||||
}
|
}
|
||||||
|
|
||||||
command->type = COMMAND_F;
|
// A face needs at least 3 vertices, otherwise the triangulation
|
||||||
|
// below reads uninitialized f[] entries.
|
||||||
|
if (num_f < 3) return 0;
|
||||||
|
|
||||||
|
// NOTE: command->type is deliberately not set here. A face rejected by
|
||||||
|
// the size checks below must not look like COMMAND_F to the later
|
||||||
|
// attribute-construction pass, which would otherwise consume
|
||||||
|
// uninitialized command->num_f/f[] fields (heap buffer overflow).
|
||||||
|
|
||||||
if (triangulate) {
|
if (triangulate) {
|
||||||
unsigned int k;
|
unsigned int k;
|
||||||
@ -1111,7 +1120,7 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
|
|||||||
// WARNING: If -DNDEBUG is set when compiling, assertions will not
|
// WARNING: If -DNDEBUG is set when compiling, assertions will not
|
||||||
// be present in the compiled binary, replacing by a runtime check
|
// be present in the compiled binary, replacing by a runtime check
|
||||||
//assert(3 * num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
|
//assert(3 * num_f < TINYOBJ_MAX_FACES_PER_F_LINE);
|
||||||
if (3*num_f > TINYOBJ_MAX_FACES_PER_F_LINE) return 0;
|
if ((num_f - 2) * 3 > TINYOBJ_MAX_FACES_PER_F_LINE) return 0;
|
||||||
|
|
||||||
for (k = 2; k < num_f; k++) {
|
for (k = 2; k < num_f; k++) {
|
||||||
i1 = i2;
|
i1 = i2;
|
||||||
@ -1144,6 +1153,9 @@ static int parseLine(Command *command, const char *p, unsigned int p_len,
|
|||||||
command->num_f_num_verts = 1;
|
command->num_f_num_verts = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark COMMAND_F only after full validation/fill so a rejected face
|
||||||
|
// stays COMMAND_EMPTY for the attribute pass below.
|
||||||
|
command->type = COMMAND_F;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1677,8 +1677,10 @@ int InitPlatform(void)
|
|||||||
// If the area requested by the user exceeds the maximum workable area, clamp it to that
|
// If the area requested by the user exceeds the maximum workable area, clamp it to that
|
||||||
// GLFW has a problem where if the window is greater than the workable area (this means
|
// GLFW has a problem where if the window is greater than the workable area (this means
|
||||||
// the taskbar / dockable areas) it won't show up if the window isn't fullscreen
|
// the taskbar / dockable areas) it won't show up if the window isn't fullscreen
|
||||||
if (CORE.Window.screen.width > (unsigned int)workWidth) CORE.Window.screen.width = workWidth;
|
// NOTE: Some window managers report a workarea that does not overlap the primary monitor
|
||||||
if (CORE.Window.screen.height > (unsigned int)workHeight) CORE.Window.screen.height = workHeight;
|
// (i.e. multi-monitor setups on X11), resulting in a zero/negative size, skip clamping then
|
||||||
|
if ((workWidth > 0) && (CORE.Window.screen.width > (unsigned int)workWidth)) CORE.Window.screen.width = workWidth;
|
||||||
|
if ((workHeight > 0) && (CORE.Window.screen.height > (unsigned int)workHeight)) CORE.Window.screen.height = workHeight;
|
||||||
|
|
||||||
platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
|
platform.handle = glfwCreateWindow(CORE.Window.screen.width, CORE.Window.screen.height, (CORE.Window.title != 0)? CORE.Window.title : " ", NULL, NULL);
|
||||||
if (!platform.handle)
|
if (!platform.handle)
|
||||||
@ -2206,7 +2208,8 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
|
|||||||
// GLFW3: Mouse wheel scroll callback, runs on mouse wheel changes
|
// GLFW3: Mouse wheel scroll callback, runs on mouse wheel changes
|
||||||
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset)
|
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset)
|
||||||
{
|
{
|
||||||
CORE.Input.Mouse.currentWheelMove = (Vector2){ (float)xoffset, (float)yoffset };
|
CORE.Input.Mouse.currentWheelMove.x += (float)xoffset;
|
||||||
|
CORE.Input.Mouse.currentWheelMove.y += (float)yoffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLFW3: Cursor ennter callback, when cursor enters the window
|
// GLFW3: Cursor ennter callback, when cursor enters the window
|
||||||
|
|||||||
@ -2020,20 +2020,13 @@ int InitPlatform(void)
|
|||||||
// Close platform
|
// Close platform
|
||||||
void ClosePlatform(void)
|
void ClosePlatform(void)
|
||||||
{
|
{
|
||||||
mg_gamepads_free(&platform.minigamepad);
|
mg_gamepads_free(&platform.minigamepad); // Clear gamepad data
|
||||||
RGFW_window_close(platform.window);
|
RGFW_window_close(platform.window);
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
||||||
if (platform.surfacePixels != NULL)
|
if (platform.surfacePixels != NULL) RL_FREE(platform.surfacePixels);
|
||||||
{
|
if (platform.surface != NULL) RGFW_surface_free(platform.surface);
|
||||||
RL_FREE(platform.surfacePixels);
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
if (platform.surface != NULL)
|
|
||||||
{
|
|
||||||
RGFW_surface_free(platform.surface);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keycode mapping
|
// Keycode mapping
|
||||||
|
|||||||
@ -1720,11 +1720,11 @@ void PollInputEvents(void)
|
|||||||
case SDL_MOUSEWHEEL:
|
case SDL_MOUSEWHEEL:
|
||||||
{
|
{
|
||||||
#if defined(USING_VERSION_SDL3)
|
#if defined(USING_VERSION_SDL3)
|
||||||
CORE.Input.Mouse.currentWheelMove.x = event.wheel.x;
|
CORE.Input.Mouse.currentWheelMove.x -= event.wheel.x;
|
||||||
CORE.Input.Mouse.currentWheelMove.y = event.wheel.y;
|
CORE.Input.Mouse.currentWheelMove.y += event.wheel.y;
|
||||||
#else
|
#else
|
||||||
CORE.Input.Mouse.currentWheelMove.x = event.wheel.preciseX;
|
CORE.Input.Mouse.currentWheelMove.x -= event.wheel.preciseX;
|
||||||
CORE.Input.Mouse.currentWheelMove.y = event.wheel.preciseY;
|
CORE.Input.Mouse.currentWheelMove.y += event.wheel.preciseY;
|
||||||
#endif
|
#endif
|
||||||
} break;
|
} break;
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
@ -2198,6 +2198,7 @@ int InitPlatform(void)
|
|||||||
|
|
||||||
// NOTE: No need to call InitTimer(), let SDL manage it internally
|
// NOTE: No need to call InitTimer(), let SDL manage it internally
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
CORE.Time.previous = 0.0;
|
||||||
|
|
||||||
// Initialize storage system
|
// Initialize storage system
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -2218,8 +2219,10 @@ int InitPlatform(void)
|
|||||||
void ClosePlatform(void)
|
void ClosePlatform(void)
|
||||||
{
|
{
|
||||||
SDL_FreeCursor(platform.cursor); // Free cursor
|
SDL_FreeCursor(platform.cursor); // Free cursor
|
||||||
|
|
||||||
if (platform.glContext != NULL) SDL_GL_DeleteContext(platform.glContext); // Deinitialize OpenGL context
|
if (platform.glContext != NULL) SDL_GL_DeleteContext(platform.glContext); // Deinitialize OpenGL context
|
||||||
SDL_DestroyWindow(platform.window);
|
SDL_DestroyWindow(platform.window);
|
||||||
|
|
||||||
SDL_Quit(); // Deinitialize SDL internal global state
|
SDL_Quit(); // Deinitialize SDL internal global state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -87,6 +87,9 @@ typedef struct {
|
|||||||
HDC hdc; // Graphic context handler
|
HDC hdc; // Graphic context handler
|
||||||
HGLRC glContext; // OpenGL context handler
|
HGLRC glContext; // OpenGL context handler
|
||||||
|
|
||||||
|
HICON largeIcon; // Large icon typically used for the taskbar
|
||||||
|
HICON smallIcon; // Small icon typically used for the window's title bar
|
||||||
|
|
||||||
// Software renderer variables
|
// Software renderer variables
|
||||||
HDC hdcmem; // Memory graphic context handler
|
HDC hdcmem; // Memory graphic context handler
|
||||||
HBITMAP hbitmap; // GDI bitmap handler
|
HBITMAP hbitmap; // GDI bitmap handler
|
||||||
@ -107,6 +110,10 @@ typedef BOOL (WINAPI *PFNWGLCHOOSEPIXELFORMATARBPROC)(HDC, const int *, const FL
|
|||||||
typedef BOOL (WINAPI *PFNWGLSWAPINTERVALEXTPROC)(int);
|
typedef BOOL (WINAPI *PFNWGLSWAPINTERVALEXTPROC)(int);
|
||||||
typedef const char *(WINAPI *PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
|
typedef const char *(WINAPI *PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
|
||||||
|
|
||||||
|
// Define Win32 function pointer types
|
||||||
|
typedef UINT (WINAPI *GetDpiForWindowProc)(HWND hwnd);
|
||||||
|
typedef BOOL (WINAPI *AdjustWindowRectExForDpiProc)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi);
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -120,6 +127,10 @@ static PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL;
|
|||||||
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
|
static PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
|
||||||
static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
|
static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
|
||||||
|
|
||||||
|
// Win32 functions that need to be dynamically loaded to support older versions of Windows
|
||||||
|
static GetDpiForWindowProc pGetDpiForWindow = NULL;
|
||||||
|
static AdjustWindowRectExForDpiProc pAdjustWindowRectExForDpi = NULL;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
// This part of the file contains pure functions that never access global state
|
// This part of the file contains pure functions that never access global state
|
||||||
// This distinction helps keep the backend maintainable as the inputs and outputs
|
// This distinction helps keep the backend maintainable as the inputs and outputs
|
||||||
@ -152,7 +163,7 @@ static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
|
|||||||
|
|
||||||
#define CLASS_NAME L"raylibWindow"
|
#define CLASS_NAME L"raylibWindow"
|
||||||
|
|
||||||
#define FLAG_MASK_OPTIONAL (FLAG_VSYNC_HINT)
|
#define FLAG_MASK_OPTIONAL (FLAG_VSYNC_HINT | FLAG_WINDOW_UNFOCUSED)
|
||||||
#define FLAG_MASK_REQUIRED ~(FLAG_MASK_OPTIONAL)
|
#define FLAG_MASK_REQUIRED ~(FLAG_MASK_OPTIONAL)
|
||||||
|
|
||||||
// Flags that have no operations to perform during an update
|
// Flags that have no operations to perform during an update
|
||||||
@ -200,6 +211,20 @@ static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
|
|||||||
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
|
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
|
||||||
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
|
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
|
||||||
|
|
||||||
|
// Older versions of Windows don't support these events
|
||||||
|
// These events won't be triggered, but this allows them to compile
|
||||||
|
#ifndef WM_DPICHANGED
|
||||||
|
#define WM_DPICHANGED 0x02E0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WM_GETDPISCALEDSIZE
|
||||||
|
#define WM_GETDPISCALEDSIZE 0x02E4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WM_MOUSEHWHEEL
|
||||||
|
#define WM_MOUSEHWHEEL 0x020E
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -368,6 +393,51 @@ static void AToWCopy(const char *ascii, wchar_t *outPtr, size_t outLen)
|
|||||||
if (size != outLen) TRACELOG(LOG_WARNING, "WIN32: Failed to convert %i UTF-8 chars to WCHAR, converted %i chars", outLen, size);
|
if (size != outLen) TRACELOG(LOG_WARNING, "WIN32: Failed to convert %i UTF-8 chars to WCHAR, converted %i chars", outLen, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamically load Windows functions that may not be available on older versions
|
||||||
|
static void LoadWin32FunctionPointers(void)
|
||||||
|
{
|
||||||
|
HMODULE user32 = GetModuleHandleW(L"user32.dll");
|
||||||
|
pGetDpiForWindow = (GetDpiForWindowProc)GetProcAddress(user32, "GetDpiForWindow");
|
||||||
|
pAdjustWindowRectExForDpi = (AdjustWindowRectExForDpiProc)GetProcAddress(user32, "AdjustWindowRectExForDpi");
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDpiForWindow with a fallback for older versions of Windows
|
||||||
|
static UINT GetDpiForWindowCompat(HWND hwnd)
|
||||||
|
{
|
||||||
|
UINT result = 0;
|
||||||
|
|
||||||
|
if (pGetDpiForWindow != NULL)
|
||||||
|
{
|
||||||
|
// This API requires Windows 10 v1607 or newer
|
||||||
|
result = pGetDpiForWindow(hwnd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Window uses CS_OWNDC, so we don't need to call ReleaseDC
|
||||||
|
HDC dc = GetDC(hwnd);
|
||||||
|
|
||||||
|
// Before Windows 10 v1607: fallback to system-wide DPI (96 for DPI-unaware processes)
|
||||||
|
result = GetDeviceCaps(dc, LOGPIXELSX);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdjustWindowRectExForDpi with a fallback for older versions of Windows
|
||||||
|
static BOOL AdjustWindowRectExForDpiCompat(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi)
|
||||||
|
{
|
||||||
|
BOOL result = FALSE;
|
||||||
|
if (pAdjustWindowRectExForDpi != NULL)
|
||||||
|
{
|
||||||
|
result = pAdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static bool DecoratedFromStyle(DWORD style)
|
static bool DecoratedFromStyle(DWORD style)
|
||||||
{
|
{
|
||||||
if (style & STYLE_FLAGS_UNDECORATED_ON)
|
if (style & STYLE_FLAGS_UNDECORATED_ON)
|
||||||
@ -464,7 +534,7 @@ static SIZE CalcWindowSize(UINT dpi, SIZE clientSize, DWORD style)
|
|||||||
{
|
{
|
||||||
RECT rect = { 0, 0, clientSize.cx, clientSize.cy };
|
RECT rect = { 0, 0, clientSize.cx, clientSize.cy };
|
||||||
|
|
||||||
int result = AdjustWindowRectExForDpi(&rect, style, 0, WINDOW_STYLE_EX, dpi);
|
int result = AdjustWindowRectExForDpiCompat(&rect, style, 0, WINDOW_STYLE_EX, dpi);
|
||||||
if (result == 0) TRACELOG(LOG_ERROR, "WIN32: Failed to adjust window rect [ERROR: %lu]", GetLastError());
|
if (result == 0) TRACELOG(LOG_ERROR, "WIN32: Failed to adjust window rect [ERROR: %lu]", GetLastError());
|
||||||
|
|
||||||
return (SIZE){ rect.right - rect.left, rect.bottom - rect.top };
|
return (SIZE){ rect.right - rect.left, rect.bottom - rect.top };
|
||||||
@ -510,7 +580,7 @@ static bool UpdateWindowSize(int mode, HWND hwnd, int width, int height, unsigne
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get size in pixels from points, considering high-dpi
|
// Get size in pixels from points, considering high-dpi
|
||||||
UINT dpi = GetDpiForWindow(hwnd);
|
UINT dpi = GetDpiForWindowCompat(hwnd);
|
||||||
float dpiScale = ((float)dpi)/96.0f;
|
float dpiScale = ((float)dpi)/96.0f;
|
||||||
bool dpiScaling = flags & FLAG_WINDOW_HIGHDPI;
|
bool dpiScaling = flags & FLAG_WINDOW_HIGHDPI;
|
||||||
SIZE desiredSize = {
|
SIZE desiredSize = {
|
||||||
@ -635,6 +705,101 @@ static LPCWSTR GetCursorName(int cursor)
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete platform.smallIcon and platform.largeIcon
|
||||||
|
static void DeletePlatformIconHandles(void)
|
||||||
|
{
|
||||||
|
HICON smallIcon = platform.smallIcon;
|
||||||
|
HICON largeIcon = platform.largeIcon;
|
||||||
|
|
||||||
|
if (smallIcon != NULL) DestroyIcon(smallIcon);
|
||||||
|
|
||||||
|
// Only delete largeIcon if it's not pointing to the same underlying resource as smallIcon
|
||||||
|
if ((largeIcon != NULL) && (largeIcon != smallIcon)) DestroyIcon(largeIcon);
|
||||||
|
|
||||||
|
platform.smallIcon = NULL;
|
||||||
|
platform.largeIcon = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete existing icons and replace them with the standard window/taskbar icons
|
||||||
|
static void ResetToDefaultWindowsIcons(void)
|
||||||
|
{
|
||||||
|
HICON smallIcon = (HICON)GetClassLongPtrW(platform.hwnd, GCLP_HICONSM);
|
||||||
|
HICON largeIcon = (HICON)GetClassLongPtrW(platform.hwnd, GCLP_HICON);
|
||||||
|
|
||||||
|
SendMessage(platform.hwnd, WM_SETICON, ICON_SMALL, (LPARAM)smallIcon);
|
||||||
|
SendMessage(platform.hwnd, WM_SETICON, ICON_BIG, (LPARAM)largeIcon);
|
||||||
|
|
||||||
|
// The built-in Windows icons shouldn't be deleted, so there's no need to store a reference to them
|
||||||
|
// Just delete the previous icons and exit
|
||||||
|
DeletePlatformIconHandles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert Image to Win32 HICON (must be RGBA)
|
||||||
|
static HICON ConvertImageToWindowsIcon(Image image)
|
||||||
|
{
|
||||||
|
if (image.format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "WIN32: Window icon image must be in R8G8B8A8 pixel format");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
HDC hdc = GetDC(platform.hwnd);
|
||||||
|
|
||||||
|
// Create 32-bit BGRA DIB for color
|
||||||
|
BITMAPV5HEADER bi = { 0 };
|
||||||
|
ZeroMemory(&bi, sizeof(bi));
|
||||||
|
bi.bV5Size = sizeof(bi);
|
||||||
|
bi.bV5Width = image.width;
|
||||||
|
bi.bV5Height = -image.height; // Negative = top-down bitmap
|
||||||
|
bi.bV5Planes = 1;
|
||||||
|
bi.bV5BitCount = 32;
|
||||||
|
bi.bV5Compression = BI_BITFIELDS;
|
||||||
|
bi.bV5RedMask = 0x00FF0000;
|
||||||
|
bi.bV5GreenMask = 0x0000FF00;
|
||||||
|
bi.bV5BlueMask = 0x000000FF;
|
||||||
|
bi.bV5AlphaMask = 0xFF000000;
|
||||||
|
|
||||||
|
unsigned char *targetBits = NULL;
|
||||||
|
HBITMAP hColorBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&targetBits, NULL, 0);
|
||||||
|
if (!hColorBitmap)
|
||||||
|
{
|
||||||
|
ReleaseDC(platform.hwnd, hdc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy RGBA > BGRA (Win32 expects BGRA)
|
||||||
|
for (int y = 0; y < image.height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < image.width; x++)
|
||||||
|
{
|
||||||
|
int i = (y*image.width + x)*4;
|
||||||
|
targetBits[i + 0] = ((unsigned char *)image.data)[i + 2]; // B
|
||||||
|
targetBits[i + 1] = ((unsigned char *)image.data)[i + 1]; // G
|
||||||
|
targetBits[i + 2] = ((unsigned char *)image.data)[i + 0]; // R
|
||||||
|
targetBits[i + 3] = ((unsigned char *)image.data)[i + 3]; // A
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create mask bitmap (1-bit, all opaque)
|
||||||
|
HBITMAP hMaskBitmap = CreateBitmap(image.width, image.height, 1, 1, NULL);
|
||||||
|
|
||||||
|
// Build icon info
|
||||||
|
ICONINFO ii = { 0 };
|
||||||
|
ZeroMemory(&ii, sizeof(ii));
|
||||||
|
ii.fIcon = TRUE;
|
||||||
|
ii.hbmMask = hMaskBitmap;
|
||||||
|
ii.hbmColor = hColorBitmap;
|
||||||
|
|
||||||
|
HICON result = CreateIconIndirect(&ii);
|
||||||
|
|
||||||
|
// Clean up GDI bitmaps (icon keeps copies internally)
|
||||||
|
DeleteObject(hColorBitmap);
|
||||||
|
DeleteObject(hMaskBitmap);
|
||||||
|
ReleaseDC(platform.hwnd, hdc);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Count monitors process
|
// Count monitors process
|
||||||
// NOTE: Required by GetMonitorCount()
|
// NOTE: Required by GetMonitorCount()
|
||||||
static BOOL CALLBACK CountMonitorsProc(HMONITOR handle, HDC hdc, LPRECT rect, LPARAM lparam)
|
static BOOL CALLBACK CountMonitorsProc(HMONITOR handle, HDC hdc, LPRECT rect, LPARAM lparam)
|
||||||
@ -812,75 +977,82 @@ void ClearWindowState(unsigned int flags)
|
|||||||
// Set icon for window
|
// Set icon for window
|
||||||
void SetWindowIcon(Image image)
|
void SetWindowIcon(Image image)
|
||||||
{
|
{
|
||||||
if (!platform.hwnd || (image.data == NULL) || (image.width <= 0) || (image.height <= 0)) return;
|
if (!platform.hwnd) return;
|
||||||
|
|
||||||
HDC hdc = GetDC(platform.hwnd);
|
if ((image.data == NULL) || (image.width <= 0) || (image.height <= 0))
|
||||||
|
|
||||||
// Create 32-bit BGRA DIB for color
|
|
||||||
BITMAPV5HEADER bi = { 0 };
|
|
||||||
ZeroMemory(&bi, sizeof(bi));
|
|
||||||
bi.bV5Size = sizeof(bi);
|
|
||||||
bi.bV5Width = image.width;
|
|
||||||
bi.bV5Height = -image.height; // Negative = top-down bitmap
|
|
||||||
bi.bV5Planes = 1;
|
|
||||||
bi.bV5BitCount = 32;
|
|
||||||
bi.bV5Compression = BI_BITFIELDS;
|
|
||||||
bi.bV5RedMask = 0x00FF0000;
|
|
||||||
bi.bV5GreenMask = 0x0000FF00;
|
|
||||||
bi.bV5BlueMask = 0x000000FF;
|
|
||||||
bi.bV5AlphaMask = 0xFF000000;
|
|
||||||
|
|
||||||
unsigned char *targetBits = NULL;
|
|
||||||
HBITMAP hColorBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&targetBits, NULL, 0);
|
|
||||||
if (!hColorBitmap)
|
|
||||||
{
|
{
|
||||||
ReleaseDC(platform.hwnd, hdc);
|
ResetToDefaultWindowsIcons();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy RGBA > BGRA (Win32 expects BGRA)
|
HICON hIcon = ConvertImageToWindowsIcon(image);
|
||||||
for (int y = 0; y < image.height; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < image.width; x++)
|
|
||||||
{
|
|
||||||
int i = (y*image.width + x)*4;
|
|
||||||
targetBits[i + 0] = ((unsigned char *)image.data)[i + 2]; // B
|
|
||||||
targetBits[i + 1] = ((unsigned char *)image.data)[i + 1]; // G
|
|
||||||
targetBits[i + 2] = ((unsigned char *)image.data)[i + 0]; // R
|
|
||||||
targetBits[i + 3] = ((unsigned char *)image.data)[i + 3]; // A
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create mask bitmap (1-bit, all opaque)
|
|
||||||
HBITMAP hMaskBitmap = CreateBitmap(image.width, image.height, 1, 1, NULL);
|
|
||||||
|
|
||||||
// Build icon info
|
|
||||||
ICONINFO ii = { 0 };
|
|
||||||
ZeroMemory(&ii, sizeof(ii));
|
|
||||||
ii.fIcon = TRUE;
|
|
||||||
ii.hbmMask = hMaskBitmap;
|
|
||||||
ii.hbmColor = hColorBitmap;
|
|
||||||
|
|
||||||
HICON hIcon = CreateIconIndirect(&ii);
|
|
||||||
|
|
||||||
// Clean up GDI bitmaps (icon keeps copies internally)
|
|
||||||
DeleteObject(hColorBitmap);
|
|
||||||
DeleteObject(hMaskBitmap);
|
|
||||||
ReleaseDC(platform.hwnd, hdc);
|
|
||||||
|
|
||||||
if (hIcon)
|
if (hIcon)
|
||||||
{
|
{
|
||||||
// Set both large and small icons
|
SendMessage(platform.hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||||
SendMessage(platform.hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
SendMessage(platform.hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||||
HICON previousIcon = (HICON)SendMessage(platform.hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
DeletePlatformIconHandles();
|
||||||
if (previousIcon) DestroyIcon(previousIcon);
|
platform.smallIcon = hIcon;
|
||||||
|
platform.largeIcon = hIcon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set icon for window (multiple sizes)
|
// Set icon for window (multiple sizes)
|
||||||
void SetWindowIcons(Image *images, int count)
|
void SetWindowIcons(Image *images, int count)
|
||||||
{
|
{
|
||||||
// TODO: Implement SetWindowIcons()
|
if ((images == NULL) || (count <= 0))
|
||||||
|
{
|
||||||
|
ResetToDefaultWindowsIcons();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Large icon has a resolution of (SM_CXICON*SM_CXICON) pixels
|
||||||
|
int largeIconRenderSize = GetSystemMetrics(SM_CXICON);
|
||||||
|
|
||||||
|
// Attempt to find a best match for the large icon based on each image's width
|
||||||
|
int bestLargeIconIndex = -1;
|
||||||
|
int bestLargeIconSizeDifference = INT_MAX;
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
Image img = images[i];
|
||||||
|
int difference = abs(img.width - largeIconRenderSize);
|
||||||
|
if ((img.data != NULL) && (img.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8A8) && (difference < bestLargeIconSizeDifference))
|
||||||
|
{
|
||||||
|
bestLargeIconIndex = i;
|
||||||
|
bestLargeIconSizeDifference = difference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Small icon has a resolution of (SM_CYSMICON*SM_CYSMICON) pixels
|
||||||
|
int smallIconRenderSize = GetSystemMetrics(SM_CYSMICON);
|
||||||
|
|
||||||
|
// Attempt to find a best match for the small icon based on each image's width
|
||||||
|
int bestSmallIconIndex = -1;
|
||||||
|
int bestSmallIconSizeDifference = INT_MAX;
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
Image img = images[i];
|
||||||
|
int difference = abs(img.width - smallIconRenderSize);
|
||||||
|
if ((img.data != NULL) && (img.format == PIXELFORMAT_UNCOMPRESSED_R8G8B8A8) && (difference < bestSmallIconSizeDifference))
|
||||||
|
{
|
||||||
|
bestSmallIconIndex = i;
|
||||||
|
bestSmallIconSizeDifference = difference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bestSmallIconIndex != -1) && (bestLargeIconIndex != -1))
|
||||||
|
{
|
||||||
|
HICON smallIcon = ConvertImageToWindowsIcon(images[bestSmallIconIndex]);
|
||||||
|
HICON largeIcon = ConvertImageToWindowsIcon(images[bestLargeIconIndex]);
|
||||||
|
|
||||||
|
SendMessage(platform.hwnd, WM_SETICON, ICON_SMALL, (LPARAM)smallIcon);
|
||||||
|
SendMessage(platform.hwnd, WM_SETICON, ICON_BIG, (LPARAM)largeIcon);
|
||||||
|
|
||||||
|
DeletePlatformIconHandles();
|
||||||
|
|
||||||
|
platform.smallIcon = smallIcon;
|
||||||
|
platform.largeIcon = largeIcon;
|
||||||
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "WIN32: All icons passed to SetWindowIcons were invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWindowTitle(const char *title)
|
void SetWindowTitle(const char *title)
|
||||||
@ -965,7 +1137,11 @@ void SetWindowOpacity(float opacity)
|
|||||||
// Set window focused
|
// Set window focused
|
||||||
void SetWindowFocused(void)
|
void SetWindowFocused(void)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "SetWindowFocused not implemented");
|
BringWindowToTop(platform.hwnd);
|
||||||
|
SetForegroundWindow(platform.hwnd);
|
||||||
|
SetFocus(platform.hwnd);
|
||||||
|
|
||||||
|
if (GetForegroundWindow() != platform.hwnd) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed to set window focus");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get native window handle
|
// Get native window handle
|
||||||
@ -1060,7 +1236,7 @@ Vector2 GetWindowPosition(void)
|
|||||||
// Get window scale DPI factor for current monitor
|
// Get window scale DPI factor for current monitor
|
||||||
Vector2 GetWindowScaleDPI(void)
|
Vector2 GetWindowScaleDPI(void)
|
||||||
{
|
{
|
||||||
float scale = ((float)GetDpiForWindow(platform.hwnd))/96.0f;
|
float scale = ((float)GetDpiForWindowCompat(platform.hwnd))/96.0f;
|
||||||
return (Vector2){ scale, scale };
|
return (Vector2){ scale, scale };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1069,10 +1245,7 @@ void SetClipboardText(const char *text)
|
|||||||
{
|
{
|
||||||
if (OpenClipboard(platform.hwnd))
|
if (OpenClipboard(platform.hwnd))
|
||||||
{
|
{
|
||||||
if (text == NULL)
|
if (text == NULL) EmptyClipboard();
|
||||||
{
|
|
||||||
EmptyClipboard();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t length = strlen(text);
|
size_t length = strlen(text);
|
||||||
@ -1105,20 +1278,14 @@ void SetClipboardText(const char *text)
|
|||||||
GlobalFree(globalHandle);
|
GlobalFree(globalHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else GlobalFree(globalHandle);
|
||||||
{
|
|
||||||
GlobalFree(globalHandle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
}
|
}
|
||||||
else
|
else TRACELOG(LOG_WARNING, "Clipboard: Failed to write to clipboard. It may be locked by another program.");
|
||||||
{
|
|
||||||
TRACELOG(LOG_WARNING, "Clipboard: Failed to write to clipboard. It may be locked by another program.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get clipboard text content
|
// Get clipboard text content
|
||||||
@ -1189,7 +1356,6 @@ Image GetClipboardImage(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
image = LoadImageFromMemory(".bmp", (const unsigned char*)fileData, (int)dataSize);
|
image = LoadImageFromMemory(".bmp", (const unsigned char*)fileData, (int)dataSize);
|
||||||
|
|
||||||
RL_FREE(fileData);
|
RL_FREE(fileData);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -1426,6 +1592,7 @@ void PollInputEvents(void)
|
|||||||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||||
|
|
||||||
CORE.Window.resizedLastFrame = false;
|
CORE.Window.resizedLastFrame = false;
|
||||||
|
CORE.Window.shouldClose = false;
|
||||||
|
|
||||||
// Process windows messages
|
// Process windows messages
|
||||||
MSG msg = { 0 };
|
MSG msg = { 0 };
|
||||||
@ -1444,7 +1611,7 @@ void PollInputEvents(void)
|
|||||||
// Windows won't send a WM_KEYDOWN event for print screen; check it manually
|
// Windows won't send a WM_KEYDOWN event for print screen; check it manually
|
||||||
bool isPrintScreenDown = ((GetAsyncKeyState(VK_SNAPSHOT) & 0x8000) != 0) && (GetForegroundWindow() == platform.hwnd);
|
bool isPrintScreenDown = ((GetAsyncKeyState(VK_SNAPSHOT) & 0x8000) != 0) && (GetForegroundWindow() == platform.hwnd);
|
||||||
CORE.Input.Keyboard.currentKeyState[KEY_PRINT_SCREEN] = isPrintScreenDown;
|
CORE.Input.Keyboard.currentKeyState[KEY_PRINT_SCREEN] = isPrintScreenDown;
|
||||||
if (isPrintScreenDown && (CORE.Input.Keyboard.exitKey == KEY_PRINT_SCREEN)) CORE.Window.shouldClose = true;
|
if (IsKeyPressed(KEY_PRINT_SCREEN) && (CORE.Input.Keyboard.exitKey == KEY_PRINT_SCREEN)) CORE.Window.shouldClose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -1642,6 +1809,8 @@ int InitPlatform(void)
|
|||||||
CORE.Window.flags = FLAG_WINDOW_HIDDEN | (platform.desiredFlags & FLAG_MASK_NO_UPDATE);
|
CORE.Window.flags = FLAG_WINDOW_HIDDEN | (platform.desiredFlags & FLAG_MASK_NO_UPDATE);
|
||||||
CORE.Window.screenMax.width = 9999;
|
CORE.Window.screenMax.width = 9999;
|
||||||
CORE.Window.screenMax.height = 9999;
|
CORE.Window.screenMax.height = 9999;
|
||||||
|
|
||||||
|
LoadWin32FunctionPointers();
|
||||||
/*
|
/*
|
||||||
// TODO: Review SetProcessDpiAwarenessContext()
|
// TODO: Review SetProcessDpiAwarenessContext()
|
||||||
// NOTE: SetProcessDpiAwarenessContext() requires Windows 10, version 1703 and shcore.lib linkage
|
// NOTE: SetProcessDpiAwarenessContext() requires Windows 10, version 1703 and shcore.lib linkage
|
||||||
@ -1764,8 +1933,14 @@ int InitPlatform(void)
|
|||||||
|
|
||||||
CORE.Window.ready = true;
|
CORE.Window.ready = true;
|
||||||
|
|
||||||
// Activate window to set focus and show taskbar icon
|
if ((platform.desiredFlags & FLAG_WINDOW_HIDDEN) == 0)
|
||||||
ShowWindow(platform.hwnd, SW_SHOWDEFAULT);
|
{
|
||||||
|
// Show window and taskbar icon, activate unless FLAG_WINDOW_UNFOCUSED is set
|
||||||
|
bool isUnfocused = ((platform.desiredFlags & FLAG_WINDOW_UNFOCUSED) != 0);
|
||||||
|
if (isUnfocused) CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED;
|
||||||
|
int nCmdShow = (isUnfocused)? SW_SHOWNA : SW_SHOWDEFAULT;
|
||||||
|
ShowWindow(platform.hwnd, nCmdShow);
|
||||||
|
}
|
||||||
|
|
||||||
// Update flags (in case of deferred state change required)
|
// Update flags (in case of deferred state change required)
|
||||||
UpdateFlags(platform.hwnd, platform.desiredFlags, platform.appScreenWidth, platform.appScreenHeight);
|
UpdateFlags(platform.hwnd, platform.desiredFlags, platform.appScreenWidth, platform.appScreenHeight);
|
||||||
@ -1814,19 +1989,11 @@ int InitPlatform(void)
|
|||||||
// Close platform
|
// Close platform
|
||||||
void ClosePlatform(void)
|
void ClosePlatform(void)
|
||||||
{
|
{
|
||||||
// Undo disable cursor if it's locked and unregister raw input devices
|
// Clear required platform data
|
||||||
EnableCursor();
|
|
||||||
|
|
||||||
// Calling DestroyWindow invokes a WindowProc event that sets the FLAG_WINDOW_HIDDEN flag to true
|
|
||||||
// If InitWindow is called again, the hidden flag will be interpreted as something the user requested
|
|
||||||
// Save the current flags and restore them after
|
|
||||||
unsigned int savedFlags = CORE.Window.flags;
|
|
||||||
|
|
||||||
if (platform.hwnd)
|
if (platform.hwnd)
|
||||||
{
|
{
|
||||||
// SetWindowIcon uses the same resource for both ICON_BIG and ICON_SMALL
|
// Disable cursor lock (if enabled) and unregister raw input devices
|
||||||
// If this ever changes, this code may have to be updated
|
EnableCursor();
|
||||||
HICON icon = (HICON)SendMessage(platform.hwnd, WM_GETICON, ICON_BIG, (LPARAM)0);
|
|
||||||
|
|
||||||
BOOL result = DestroyWindow(platform.hwnd);
|
BOOL result = DestroyWindow(platform.hwnd);
|
||||||
if (!result) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed on window destroy [ERROR: %u]", GetLastError());
|
if (!result) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed on window destroy [ERROR: %u]", GetLastError());
|
||||||
@ -1835,19 +2002,18 @@ void ClosePlatform(void)
|
|||||||
result = UnregisterClassW(CLASS_NAME, hInstance);
|
result = UnregisterClassW(CLASS_NAME, hInstance);
|
||||||
if (!result) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed to unregister window class [ERROR: %u]", GetLastError());
|
if (!result) TRACELOG(LOG_WARNING, "WIN32: WINDOW: Failed to unregister window class [ERROR: %u]", GetLastError());
|
||||||
|
|
||||||
if (icon != NULL) DestroyIcon(icon);
|
DeletePlatformIconHandles();
|
||||||
|
|
||||||
platform.hwnd = NULL;
|
platform.hwnd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear clipboard
|
||||||
if (platform.clipboardText != NULL)
|
if (platform.clipboardText != NULL)
|
||||||
{
|
{
|
||||||
RL_FREE(platform.clipboardText);
|
RL_FREE(platform.clipboardText);
|
||||||
platform.clipboardText = NULL;
|
platform.clipboardText = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CORE.Window.flags = savedFlags;
|
|
||||||
|
|
||||||
#if SUPPORT_WINMM_HIGHRES_TIMER && !SUPPORT_BUSY_WAIT_LOOP
|
#if SUPPORT_WINMM_HIGHRES_TIMER && !SUPPORT_BUSY_WAIT_LOOP
|
||||||
timeEndPeriod(1); // Restore time period
|
timeEndPeriod(1); // Restore time period
|
||||||
#endif
|
#endif
|
||||||
@ -1921,10 +2087,12 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
|
|||||||
//case WM_QUIT: // Application closing, not related to window
|
//case WM_QUIT: // Application closing, not related to window
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
{
|
{
|
||||||
|
CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED;
|
||||||
memset(CORE.Input.Keyboard.currentKeyState, 0, sizeof(CORE.Input.Keyboard.currentKeyState));
|
memset(CORE.Input.Keyboard.currentKeyState, 0, sizeof(CORE.Input.Keyboard.currentKeyState));
|
||||||
memset(CORE.Input.Mouse.currentButtonState, 0, sizeof(CORE.Input.Mouse.currentButtonState));
|
memset(CORE.Input.Mouse.currentButtonState, 0, sizeof(CORE.Input.Mouse.currentButtonState));
|
||||||
memset(CORE.Input.Touch.currentTouchState, 0, sizeof(CORE.Input.Touch.currentTouchState));
|
memset(CORE.Input.Touch.currentTouchState, 0, sizeof(CORE.Input.Touch.currentTouchState));
|
||||||
} break;
|
} break;
|
||||||
|
case WM_SETFOCUS: CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; break;
|
||||||
case WM_SIZING: // Sent to a window that the user is resizing
|
case WM_SIZING: // Sent to a window that the user is resizing
|
||||||
{
|
{
|
||||||
if (CORE.Window.flags & FLAG_WINDOW_RESIZABLE)
|
if (CORE.Window.flags & FLAG_WINDOW_RESIZABLE)
|
||||||
@ -1973,7 +2141,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
|
|||||||
STYLESTRUCT *ss = (STYLESTRUCT *)lparam;
|
STYLESTRUCT *ss = (STYLESTRUCT *)lparam;
|
||||||
GetStyleChangeFlagOps(CORE.Window.flags, ss, deferredFlags);
|
GetStyleChangeFlagOps(CORE.Window.flags, ss, deferredFlags);
|
||||||
|
|
||||||
UINT dpi = GetDpiForWindow(hwnd);
|
UINT dpi = GetDpiForWindowCompat(hwnd);
|
||||||
// Get client size (framebuffer inside the window)
|
// Get client size (framebuffer inside the window)
|
||||||
RECT rect = { 0 };
|
RECT rect = { 0 };
|
||||||
GetClientRect(hwnd, &rect);
|
GetClientRect(hwnd, &rect);
|
||||||
@ -2187,8 +2355,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
|
|||||||
default: TRACELOG(LOG_WARNING, "TODO: Handle ex mouse button UP [wparam=%u]", HIWORD(wparam)); break;
|
default: TRACELOG(LOG_WARNING, "TODO: Handle ex mouse button UP [wparam=%u]", HIWORD(wparam)); break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case WM_MOUSEWHEEL: CORE.Input.Mouse.currentWheelMove.y = ((float)GET_WHEEL_DELTA_WPARAM(wparam))/WHEEL_DELTA; break;
|
case WM_MOUSEWHEEL: CORE.Input.Mouse.currentWheelMove.y += ((float)GET_WHEEL_DELTA_WPARAM(wparam))/WHEEL_DELTA; break;
|
||||||
case WM_MOUSEHWHEEL: CORE.Input.Mouse.currentWheelMove.x = ((float)GET_WHEEL_DELTA_WPARAM(wparam))/WHEEL_DELTA; break;
|
// Horizontal wheel movement is inverted to match GLFW
|
||||||
|
case WM_MOUSEHWHEEL: CORE.Input.Mouse.currentWheelMove.x -= ((float)GET_WHEEL_DELTA_WPARAM(wparam))/WHEEL_DELTA; break;
|
||||||
|
|
||||||
default: result = DefWindowProcW(hwnd, msg, wparam, lparam); // Message passed directly for execution (default behaviour)
|
default: result = DefWindowProcW(hwnd, msg, wparam, lparam); // Message passed directly for execution (default behaviour)
|
||||||
}
|
}
|
||||||
@ -2260,8 +2429,9 @@ static void HandleKey(WPARAM wparam, LPARAM lparam, char state)
|
|||||||
{
|
{
|
||||||
CORE.Input.Keyboard.currentKeyState[key] = state;
|
CORE.Input.Keyboard.currentKeyState[key] = state;
|
||||||
|
|
||||||
if (((HIWORD(lparam) & KF_REPEAT) != 0) && (state == 1)) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
bool isKeyRepeatEvent = ((HIWORD(lparam) & KF_REPEAT) != 0);
|
||||||
if ((key == CORE.Input.Keyboard.exitKey) && (state == 1)) CORE.Window.shouldClose = true;
|
if (isKeyRepeatEvent && (state == 1)) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
||||||
|
if (!isKeyRepeatEvent && (key == CORE.Input.Keyboard.exitKey) && (state == 1)) CORE.Window.shouldClose = true;
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "INPUT: Unknown (or currently unhandled) virtual keycode %d (0x%x)", wparam, wparam);
|
else TRACELOG(LOG_WARNING, "INPUT: Unknown (or currently unhandled) virtual keycode %d (0x%x)", wparam, wparam);
|
||||||
}
|
}
|
||||||
@ -2351,7 +2521,7 @@ static void HandleWindowResize(HWND hwnd, int *width, int *height)
|
|||||||
SetupViewport(clientSize.cx, clientSize.cy);
|
SetupViewport(clientSize.cx, clientSize.cy);
|
||||||
|
|
||||||
CORE.Window.resizedLastFrame = true;
|
CORE.Window.resizedLastFrame = true;
|
||||||
float dpiScale = ((float)GetDpiForWindow(hwnd))/96.0f;
|
float dpiScale = ((float)GetDpiForWindowCompat(hwnd))/96.0f;
|
||||||
bool highdpi = !!(CORE.Window.flags & FLAG_WINDOW_HIGHDPI);
|
bool highdpi = !!(CORE.Window.flags & FLAG_WINDOW_HIGHDPI);
|
||||||
unsigned int screenWidth = highdpi? (unsigned int)(((float)clientSize.cx)/dpiScale) : clientSize.cx;
|
unsigned int screenWidth = highdpi? (unsigned int)(((float)clientSize.cx)/dpiScale) : clientSize.cx;
|
||||||
unsigned int screenHeight = highdpi? (unsigned int)(((float)clientSize.cy)/dpiScale) : clientSize.cy;
|
unsigned int screenHeight = highdpi? (unsigned int)(((float)clientSize.cy)/dpiScale) : clientSize.cy;
|
||||||
|
|||||||
@ -1735,7 +1735,6 @@ void ClosePlatform(void)
|
|||||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||||
|
|
||||||
// Close the evdev devices
|
// Close the evdev devices
|
||||||
|
|
||||||
if (platform.mouseFd != -1)
|
if (platform.mouseFd != -1)
|
||||||
{
|
{
|
||||||
close(platform.mouseFd);
|
close(platform.mouseFd);
|
||||||
|
|||||||
@ -554,7 +554,7 @@ int InitPlatform(void)
|
|||||||
// Close platform
|
// Close platform
|
||||||
void ClosePlatform(void)
|
void ClosePlatform(void)
|
||||||
{
|
{
|
||||||
RL_FREE(platform.pixels);
|
RL_FREE(platform.pixels); // Free pixels buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -1450,6 +1450,7 @@ int InitPlatform(void)
|
|||||||
void ClosePlatform(void)
|
void ClosePlatform(void)
|
||||||
{
|
{
|
||||||
if (platform.pixels != NULL) RL_FREE(platform.pixels);
|
if (platform.pixels != NULL) RL_FREE(platform.pixels);
|
||||||
|
|
||||||
if (platform.glContext != 0) emscripten_webgl_destroy_context(platform.glContext);
|
if (platform.glContext != 0) emscripten_webgl_destroy_context(platform.glContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/raudio.c
12
src/raudio.c
@ -810,6 +810,12 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
|
|||||||
{
|
{
|
||||||
Wave wave = { 0 };
|
Wave wave = { 0 };
|
||||||
|
|
||||||
|
if (fileType == NULL)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "WAVE: Missing file extension");
|
||||||
|
return wave;
|
||||||
|
}
|
||||||
|
|
||||||
if (false) { }
|
if (false) { }
|
||||||
#if SUPPORT_FILEFORMAT_WAV
|
#if SUPPORT_FILEFORMAT_WAV
|
||||||
else if ((strcmp(fileType, ".wav") == 0) || (strcmp(fileType, ".WAV") == 0))
|
else if ((strcmp(fileType, ".wav") == 0) || (strcmp(fileType, ".WAV") == 0))
|
||||||
@ -2781,7 +2787,7 @@ static bool IsFileExtension(const char *fileName, const char *ext)
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
const char *fileExt;
|
const char *fileExt;
|
||||||
|
|
||||||
if ((fileExt = strrchr(fileName, '.')) != NULL)
|
if ((fileExt = GetFileExtension(fileName)) != NULL)
|
||||||
{
|
{
|
||||||
if (strcmp(fileExt, ext) == 0) result = true;
|
if (strcmp(fileExt, ext) == 0) result = true;
|
||||||
}
|
}
|
||||||
@ -2792,7 +2798,9 @@ static bool IsFileExtension(const char *fileName, const char *ext)
|
|||||||
// Get pointer to extension for a filename string (includes the dot: .png)
|
// Get pointer to extension for a filename string (includes the dot: .png)
|
||||||
static const char *GetFileExtension(const char *fileName)
|
static const char *GetFileExtension(const char *fileName)
|
||||||
{
|
{
|
||||||
const char *dot = strrchr(fileName, '.');
|
// Only the file name part can contain the extension, not a directory name
|
||||||
|
const char *name = GetFileName(fileName);
|
||||||
|
const char *dot = strrchr(name, '.');
|
||||||
|
|
||||||
if (!dot || dot == fileName) return NULL;
|
if (!dot || dot == fileName) return NULL;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
*
|
*
|
||||||
* raylib v6.2 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
* raylib v6.5-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||||
*
|
*
|
||||||
* FEATURES:
|
* FEATURES:
|
||||||
* - NO external dependencies, all required libraries included with raylib
|
* - NO external dependencies, all required libraries included with raylib
|
||||||
@ -87,9 +87,9 @@
|
|||||||
#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_MAJOR 6
|
#define RAYLIB_VERSION_MAJOR 6
|
||||||
#define RAYLIB_VERSION_MINOR 2
|
#define RAYLIB_VERSION_MINOR 5
|
||||||
#define RAYLIB_VERSION_PATCH 0
|
#define RAYLIB_VERSION_PATCH 0
|
||||||
#define RAYLIB_VERSION "6.2"
|
#define RAYLIB_VERSION "6.5-dev"
|
||||||
|
|
||||||
// Function specifiers in case library is build/used as a shared library
|
// Function specifiers in case library is build/used as a shared library
|
||||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
*
|
*
|
||||||
* raymath v2.0 - Math functions to work with Vector2, Vector3, Vector4, Matrix and Quaternions
|
* raymath v2.1 - Math functions to work with Vector2, Vector3, Vector4, Matrix and Quaternions
|
||||||
*
|
*
|
||||||
* CONVENTIONS:
|
* CONVENTIONS:
|
||||||
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
|
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
|
||||||
@ -9,6 +9,7 @@
|
|||||||
* It benefits some functions making them cache-friendly and also avoids matrix
|
* It benefits some functions making them cache-friendly and also avoids matrix
|
||||||
* transpositions sometimes required by OpenGL
|
* transpositions sometimes required by OpenGL
|
||||||
* Example: In memory order, row0 is [m0 m4 m8 m12] but in semantic math row0 is [m0 m1 m2 m3]
|
* Example: In memory order, row0 is [m0 m4 m8 m12] but in semantic math row0 is [m0 m1 m2 m3]
|
||||||
|
* - All math is float only, no doubles usage
|
||||||
* - Functions are always self-contained, no function use another raymath function inside,
|
* - Functions are always self-contained, no function use another raymath function inside,
|
||||||
* required code is directly re-implemented inside
|
* required code is directly re-implemented inside
|
||||||
* - Functions input parameters are always received by value (2 unavoidable exceptions)
|
* - Functions input parameters are always received by value (2 unavoidable exceptions)
|
||||||
@ -1970,32 +1971,32 @@ RMAPI Matrix MatrixScale(float x, float y, float z)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get perspective projection matrix
|
// Get perspective projection matrix
|
||||||
RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double nearPlane, double farPlane)
|
RMAPI Matrix MatrixFrustum(float left, float right, float bottom, float top, float nearPlane, float farPlane)
|
||||||
{
|
{
|
||||||
Matrix result = { 0 };
|
Matrix result = { 0 };
|
||||||
|
|
||||||
float rl = (float)(right - left);
|
float rl = right - left;
|
||||||
float tb = (float)(top - bottom);
|
float tb = top - bottom;
|
||||||
float fn = (float)(farPlane - nearPlane);
|
float fn = farPlane - nearPlane;
|
||||||
|
|
||||||
result.m0 = ((float)nearPlane*2.0f)/rl;
|
result.m0 = (nearPlane*2.0f)/rl;
|
||||||
result.m1 = 0.0f;
|
result.m1 = 0.0f;
|
||||||
result.m2 = 0.0f;
|
result.m2 = 0.0f;
|
||||||
result.m3 = 0.0f;
|
result.m3 = 0.0f;
|
||||||
|
|
||||||
result.m4 = 0.0f;
|
result.m4 = 0.0f;
|
||||||
result.m5 = ((float)nearPlane*2.0f)/tb;
|
result.m5 = (nearPlane*2.0f)/tb;
|
||||||
result.m6 = 0.0f;
|
result.m6 = 0.0f;
|
||||||
result.m7 = 0.0f;
|
result.m7 = 0.0f;
|
||||||
|
|
||||||
result.m8 = ((float)right + (float)left)/rl;
|
result.m8 = (right + left)/rl;
|
||||||
result.m9 = ((float)top + (float)bottom)/tb;
|
result.m9 = (top + bottom)/tb;
|
||||||
result.m10 = -((float)farPlane + (float)nearPlane)/fn;
|
result.m10 = -(farPlane + nearPlane)/fn;
|
||||||
result.m11 = -1.0f;
|
result.m11 = -1.0f;
|
||||||
|
|
||||||
result.m12 = 0.0f;
|
result.m12 = 0.0f;
|
||||||
result.m13 = 0.0f;
|
result.m13 = 0.0f;
|
||||||
result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn;
|
result.m14 = -(farPlane*nearPlane*2.0f)/fn;
|
||||||
result.m15 = 0.0f;
|
result.m15 = 0.0f;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -2003,39 +2004,39 @@ RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top,
|
|||||||
|
|
||||||
// Get perspective projection matrix
|
// Get perspective projection matrix
|
||||||
// NOTE: Fovy angle must be provided in radians
|
// NOTE: Fovy angle must be provided in radians
|
||||||
RMAPI Matrix MatrixPerspective(double fovY, double aspect, double nearPlane, double farPlane)
|
RMAPI Matrix MatrixPerspective(float fovY, float aspect, float nearPlane, float farPlane)
|
||||||
{
|
{
|
||||||
Matrix result = { 0 };
|
Matrix result = { 0 };
|
||||||
|
|
||||||
double top = nearPlane*tan(fovY*0.5);
|
float top = nearPlane*tanf(fovY*0.5f);
|
||||||
double bottom = -top;
|
float bottom = -top;
|
||||||
double right = top*aspect;
|
float right = top*aspect;
|
||||||
double left = -right;
|
float left = -right;
|
||||||
|
|
||||||
// MatrixFrustum(-right, right, -top, top, near, far);
|
// MatrixFrustum(-right, right, -top, top, near, far);
|
||||||
float rl = (float)(right - left);
|
float rl = right - left;
|
||||||
float tb = (float)(top - bottom);
|
float tb = top - bottom;
|
||||||
float fn = (float)(farPlane - nearPlane);
|
float fn = farPlane - nearPlane;
|
||||||
|
|
||||||
result.m0 = ((float)nearPlane*2.0f)/rl;
|
result.m0 = (nearPlane*2.0f)/rl;
|
||||||
result.m5 = ((float)nearPlane*2.0f)/tb;
|
result.m5 = (nearPlane*2.0f)/tb;
|
||||||
result.m8 = ((float)right + (float)left)/rl;
|
result.m8 = (right + left)/rl;
|
||||||
result.m9 = ((float)top + (float)bottom)/tb;
|
result.m9 = (top + bottom)/tb;
|
||||||
result.m10 = -((float)farPlane + (float)nearPlane)/fn;
|
result.m10 = -(farPlane + nearPlane)/fn;
|
||||||
result.m11 = -1.0f;
|
result.m11 = -1.0f;
|
||||||
result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn;
|
result.m14 = -(farPlane*nearPlane*2.0f)/fn;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get orthographic projection matrix
|
// Get orthographic projection matrix
|
||||||
RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, double nearPlane, double farPlane)
|
RMAPI Matrix MatrixOrtho(float left, float right, float bottom, float top, float nearPlane, float farPlane)
|
||||||
{
|
{
|
||||||
Matrix result = { 0 };
|
Matrix result = { 0 };
|
||||||
|
|
||||||
float rl = (float)(right - left);
|
float rl = right - left;
|
||||||
float tb = (float)(top - bottom);
|
float tb = top - bottom;
|
||||||
float fn = (float)(farPlane - nearPlane);
|
float fn = farPlane - nearPlane;
|
||||||
|
|
||||||
result.m0 = 2.0f/rl;
|
result.m0 = 2.0f/rl;
|
||||||
result.m1 = 0.0f;
|
result.m1 = 0.0f;
|
||||||
@ -2049,9 +2050,9 @@ RMAPI Matrix MatrixOrtho(double left, double right, double bottom, double top, d
|
|||||||
result.m9 = 0.0f;
|
result.m9 = 0.0f;
|
||||||
result.m10 = -2.0f/fn;
|
result.m10 = -2.0f/fn;
|
||||||
result.m11 = 0.0f;
|
result.m11 = 0.0f;
|
||||||
result.m12 = -((float)left + (float)right)/rl;
|
result.m12 = -(left + right)/rl;
|
||||||
result.m13 = -((float)top + (float)bottom)/tb;
|
result.m13 = -(top + bottom)/tb;
|
||||||
result.m14 = -((float)farPlane + (float)nearPlane)/fn;
|
result.m14 = -(farPlane + nearPlane)/fn;
|
||||||
result.m15 = 1.0f;
|
result.m15 = 1.0f;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -2281,6 +2282,12 @@ RMAPI Quaternion QuaternionNlerp(Quaternion q1, Quaternion q2, float amount)
|
|||||||
{
|
{
|
||||||
Quaternion result = { 0 };
|
Quaternion result = { 0 };
|
||||||
|
|
||||||
|
// q2 and -q2 are the same rotation, take the shorter path like QuaternionSlerp()
|
||||||
|
if ((q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w) < 0.0f)
|
||||||
|
{
|
||||||
|
q2.x = -q2.x; q2.y = -q2.y; q2.z = -q2.z; q2.w = -q2.w;
|
||||||
|
}
|
||||||
|
|
||||||
// QuaternionLerp(q1, q2, amount)
|
// QuaternionLerp(q1, q2, amount)
|
||||||
result.x = q1.x + amount*(q2.x - q1.x);
|
result.x = q1.x + amount*(q2.x - q1.x);
|
||||||
result.y = q1.y + amount*(q2.y - q1.y);
|
result.y = q1.y + amount*(q2.y - q1.y);
|
||||||
|
|||||||
@ -65,8 +65,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(RCAMERA_STANDALONE)
|
#if defined(RCAMERA_STANDALONE)
|
||||||
#define CAMERA_CULL_DISTANCE_NEAR 0.05
|
#define CAMERA_CULL_DISTANCE_NEAR 0.05f
|
||||||
#define CAMERA_CULL_DISTANCE_FAR 4000.0
|
#define CAMERA_CULL_DISTANCE_FAR 4000.0f
|
||||||
#else
|
#else
|
||||||
#define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR
|
#define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR
|
||||||
#define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR
|
#define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR
|
||||||
@ -430,8 +430,8 @@ Matrix GetCameraProjectionMatrix(Camera *camera, float aspect)
|
|||||||
}
|
}
|
||||||
else if (camera->projection == CAMERA_ORTHOGRAPHIC)
|
else if (camera->projection == CAMERA_ORTHOGRAPHIC)
|
||||||
{
|
{
|
||||||
double top = camera->fovy/2.0;
|
float top = camera->fovy/2.0f;
|
||||||
double right = top*aspect;
|
float right = top*aspect;
|
||||||
|
|
||||||
return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
|
return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
|
||||||
}
|
}
|
||||||
|
|||||||
45
src/rcore.c
45
src/rcore.c
@ -379,6 +379,7 @@ typedef struct CoreData {
|
|||||||
float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXES]; // Gamepad axes state
|
float axisState[MAX_GAMEPADS][MAX_GAMEPAD_AXES]; // Gamepad axes state
|
||||||
|
|
||||||
} Gamepad;
|
} Gamepad;
|
||||||
|
|
||||||
} Input;
|
} Input;
|
||||||
struct {
|
struct {
|
||||||
double current; // Current time measure (seconds)
|
double current; // Current time measure (seconds)
|
||||||
@ -646,7 +647,6 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||||
|
|
||||||
// Initialize global input state
|
// Initialize global input state
|
||||||
memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
|
|
||||||
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
||||||
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||||
@ -708,15 +708,16 @@ void InitWindow(int width, int height, const char *title)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// NOTE: Should be already initialized to 0 but just in case
|
||||||
CORE.Time.frameCounter = 0;
|
CORE.Time.frameCounter = 0;
|
||||||
CORE.Window.shouldClose = false;
|
CORE.Window.shouldClose = false;
|
||||||
|
|
||||||
// Initialize random seed using available timer source instead of standard time() on embedded platforms
|
// Initialize random seed using available timer source instead of standard time() on embedded platforms
|
||||||
#ifndef PICO_RP2350
|
#ifndef PICO_RP2350
|
||||||
SetRandomSeed((unsigned int)time(NULL));
|
SetRandomSeed((unsigned int)time(NULL));
|
||||||
#else
|
#else
|
||||||
SetRandomSeed(get_rand_32());
|
SetRandomSeed(get_rand_32());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
|
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
|
||||||
}
|
}
|
||||||
@ -735,7 +736,9 @@ void CloseWindow(void)
|
|||||||
ClosePlatform();
|
ClosePlatform();
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
CORE.Window.ready = false;
|
// Clear CORE data, in case new window is initialized
|
||||||
|
CORE = (CoreData){ 0 };
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "Window closed successfully");
|
TRACELOG(LOG_INFO, "Window closed successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,16 +957,16 @@ void BeginMode3D(Camera camera)
|
|||||||
if (camera.projection == CAMERA_PERSPECTIVE)
|
if (camera.projection == CAMERA_PERSPECTIVE)
|
||||||
{
|
{
|
||||||
// Setup perspective projection
|
// Setup perspective projection
|
||||||
double top = rlGetCullDistanceNear()*tan(camera.fovy*0.5*DEG2RAD);
|
float top = rlGetCullDistanceNear()*tanf(camera.fovy*0.5f*DEG2RAD);
|
||||||
double right = top*aspect;
|
float right = top*aspect;
|
||||||
|
|
||||||
rlFrustum(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
rlFrustum(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
||||||
}
|
}
|
||||||
else if (camera.projection == CAMERA_ORTHOGRAPHIC)
|
else if (camera.projection == CAMERA_ORTHOGRAPHIC)
|
||||||
{
|
{
|
||||||
// Setup orthographic projection
|
// Setup orthographic projection
|
||||||
double top = camera.fovy/2.0;
|
float top = camera.fovy/2.0f;
|
||||||
double right = top*aspect;
|
float right = top*aspect;
|
||||||
|
|
||||||
rlOrtho(-right, right, -top,top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
rlOrtho(-right, right, -top,top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
||||||
}
|
}
|
||||||
@ -1011,7 +1014,7 @@ void BeginTextureMode(RenderTexture2D target)
|
|||||||
|
|
||||||
// Set orthographic projection to current framebuffer size
|
// Set orthographic projection to current framebuffer size
|
||||||
// NOTE: Configured top-left corner as (0, 0)
|
// NOTE: Configured top-left corner as (0, 0)
|
||||||
rlOrtho(0, target.texture.width, target.texture.height, 0, 0.0f, 1.0f);
|
rlOrtho(0.0f, (float)target.texture.width, (float)target.texture.height, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
|
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
|
||||||
rlLoadIdentity(); // Reset current matrix (modelview)
|
rlLoadIdentity(); // Reset current matrix (modelview)
|
||||||
@ -1424,13 +1427,13 @@ Ray GetScreenToWorldRayEx(Vector2 position, Camera camera, int width, int height
|
|||||||
if (camera.projection == CAMERA_PERSPECTIVE)
|
if (camera.projection == CAMERA_PERSPECTIVE)
|
||||||
{
|
{
|
||||||
// Calculate projection matrix from perspective
|
// Calculate projection matrix from perspective
|
||||||
matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)width/(double)height), rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
matProj = MatrixPerspective(camera.fovy*DEG2RAD, (float)width/(float)height, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
||||||
}
|
}
|
||||||
else if (camera.projection == CAMERA_ORTHOGRAPHIC)
|
else if (camera.projection == CAMERA_ORTHOGRAPHIC)
|
||||||
{
|
{
|
||||||
double aspect = (double)width/(double)height;
|
float aspect = (float)width/(float)height;
|
||||||
double top = camera.fovy/2.0;
|
float top = camera.fovy/2.0f;
|
||||||
double right = top*aspect;
|
float right = top*aspect;
|
||||||
|
|
||||||
// Calculate projection matrix from orthographic
|
// Calculate projection matrix from orthographic
|
||||||
matProj = MatrixOrtho(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
matProj = MatrixOrtho(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
||||||
@ -1511,13 +1514,13 @@ Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int heigh
|
|||||||
if (camera.projection == CAMERA_PERSPECTIVE)
|
if (camera.projection == CAMERA_PERSPECTIVE)
|
||||||
{
|
{
|
||||||
// Calculate projection matrix from perspective
|
// Calculate projection matrix from perspective
|
||||||
matProj = MatrixPerspective(camera.fovy*DEG2RAD, ((double)width/(double)height), rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
matProj = MatrixPerspective(camera.fovy*DEG2RAD, (float)width/(float)height, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
||||||
}
|
}
|
||||||
else if (camera.projection == CAMERA_ORTHOGRAPHIC)
|
else if (camera.projection == CAMERA_ORTHOGRAPHIC)
|
||||||
{
|
{
|
||||||
double aspect = (double)width/(double)height;
|
float aspect = (float)width/(float)height;
|
||||||
double top = camera.fovy/2.0;
|
float top = camera.fovy/2.0f;
|
||||||
double right = top*aspect;
|
float right = top*aspect;
|
||||||
|
|
||||||
// Calculate projection matrix from orthographic
|
// Calculate projection matrix from orthographic
|
||||||
matProj = MatrixOrtho(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
matProj = MatrixOrtho(-right, right, -top, top, rlGetCullDistanceNear(), rlGetCullDistanceFar());
|
||||||
@ -2496,7 +2499,9 @@ long GetFileModTime(const char *fileName)
|
|||||||
// WARNING: Getting the pointer to the input string extension position (not a string copy)
|
// WARNING: Getting the pointer to the input string extension position (not a string copy)
|
||||||
const char *GetFileExtension(const char *fileName)
|
const char *GetFileExtension(const char *fileName)
|
||||||
{
|
{
|
||||||
const char *dot = strrchr(fileName, '.');
|
// Only the file name part can contain the extension, not a directory name
|
||||||
|
const char *name = GetFileName(fileName);
|
||||||
|
const char *dot = strrchr(name, '.');
|
||||||
|
|
||||||
if ((dot == NULL) || (dot == fileName)) return NULL;
|
if ((dot == NULL) || (dot == fileName)) return NULL;
|
||||||
|
|
||||||
@ -4336,7 +4341,7 @@ void SetupViewport(int width, int height)
|
|||||||
|
|
||||||
// Set orthographic projection to current framebuffer size
|
// Set orthographic projection to current framebuffer size
|
||||||
// NOTE: Configured top-left corner as (0, 0)
|
// NOTE: Configured top-left corner as (0, 0)
|
||||||
rlOrtho(0, CORE.Window.render.width, CORE.Window.render.height, 0, 0.0f, 1.0f);
|
rlOrtho(0.0f, (float)CORE.Window.render.width, (float)CORE.Window.render.height, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
|
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
|
||||||
rlLoadIdentity(); // Reset current matrix (modelview)
|
rlLoadIdentity(); // Reset current matrix (modelview)
|
||||||
|
|||||||
66
src/rlgl.h
66
src/rlgl.h
@ -53,8 +53,8 @@
|
|||||||
*
|
*
|
||||||
* #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack
|
* #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack
|
||||||
* #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
|
* #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
|
||||||
* #define RL_CULL_DISTANCE_NEAR 0.05 // Default projection matrix near cull distance
|
* #define RL_CULL_DISTANCE_NEAR 0.05f // Default projection matrix near cull distance
|
||||||
* #define RL_CULL_DISTANCE_FAR 4000.0 // Default projection matrix far cull distance
|
* #define RL_CULL_DISTANCE_FAR 4000.0f // Default projection matrix far cull distance
|
||||||
*
|
*
|
||||||
* When loading a shader, the following vertex attributes and uniform location names are tried to be set automatically:
|
* When loading a shader, the following vertex attributes and uniform location names are tried to be set automatically:
|
||||||
* WARNING: Pre-defined names can not be changed, they are used by default shaders and all raylib examples shaders, they are just listed here for reference
|
* WARNING: Pre-defined names can not be changed, they are used by default shaders and all raylib examples shaders, they are just listed here for reference
|
||||||
@ -235,10 +235,10 @@
|
|||||||
|
|
||||||
// Projection matrix culling
|
// Projection matrix culling
|
||||||
#ifndef RL_CULL_DISTANCE_NEAR
|
#ifndef RL_CULL_DISTANCE_NEAR
|
||||||
#define RL_CULL_DISTANCE_NEAR 0.05 // Default near cull distance
|
#define RL_CULL_DISTANCE_NEAR 0.05f // Default near cull distance
|
||||||
#endif
|
#endif
|
||||||
#ifndef RL_CULL_DISTANCE_FAR
|
#ifndef RL_CULL_DISTANCE_FAR
|
||||||
#define RL_CULL_DISTANCE_FAR 4000.0 // Default far cull distance
|
#define RL_CULL_DISTANCE_FAR 4000.0f // Default far cull distance
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Texture parameters (equivalent to OpenGL defines)
|
// Texture parameters (equivalent to OpenGL defines)
|
||||||
@ -611,12 +611,12 @@ RLAPI void rlTranslatef(float x, float y, float z); // Multiply the current
|
|||||||
RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix
|
RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix
|
||||||
RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix
|
RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix
|
||||||
RLAPI void rlMultMatrixf(const float *matf); // Multiply the current matrix by another matrix
|
RLAPI void rlMultMatrixf(const float *matf); // Multiply the current matrix by another matrix
|
||||||
RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar);
|
RLAPI void rlFrustum(float left, float right, float bottom, float top, float znear, float zfar);
|
||||||
RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar);
|
RLAPI void rlOrtho(float left, float right, float bottom, float top, float znear, float zfar);
|
||||||
RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area
|
RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area
|
||||||
RLAPI void rlSetClipPlanes(double nearPlane, double farPlane); // Set clip planes distances
|
RLAPI void rlSetClipPlanes(float nearPlane, float farPlane); // Set clip planes distances
|
||||||
RLAPI double rlGetCullDistanceNear(void); // Get cull plane distance near
|
RLAPI float rlGetCullDistanceNear(void); // Get cull plane distance near
|
||||||
RLAPI double rlGetCullDistanceFar(void); // Get cull plane distance far
|
RLAPI float rlGetCullDistanceFar(void); // Get cull plane distance far
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Functions Declaration - Vertex level operations
|
// Functions Declaration - Vertex level operations
|
||||||
@ -1111,8 +1111,8 @@ typedef struct rlglData {
|
|||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static bool isGpuReady = false;
|
static bool isGpuReady = false;
|
||||||
static double rlCullDistanceNear = RL_CULL_DISTANCE_NEAR;
|
static float rlCullDistanceNear = RL_CULL_DISTANCE_NEAR;
|
||||||
static double rlCullDistanceFar = RL_CULL_DISTANCE_FAR;
|
static float rlCullDistanceFar = RL_CULL_DISTANCE_FAR;
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
static rlglData RLGL = { 0 };
|
static rlglData RLGL = { 0 };
|
||||||
@ -1174,12 +1174,12 @@ void rlMatrixMode(int mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar)
|
void rlFrustum(float left, float right, float bottom, float top, float znear, float zfar)
|
||||||
{
|
{
|
||||||
glFrustum(left, right, bottom, top, znear, zfar);
|
glFrustum(left, right, bottom, top, znear, zfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
|
void rlOrtho(float left, float right, float bottom, float top, float znear, float zfar)
|
||||||
{
|
{
|
||||||
glOrtho(left, right, bottom, top, znear, zfar);
|
glOrtho(left, right, bottom, top, znear, zfar);
|
||||||
}
|
}
|
||||||
@ -1332,47 +1332,47 @@ void rlMultMatrixf(const float *matf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Multiply the current matrix by a perspective matrix generated by parameters
|
// Multiply the current matrix by a perspective matrix generated by parameters
|
||||||
void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar)
|
void rlFrustum(float left, float right, float bottom, float top, float znear, float zfar)
|
||||||
{
|
{
|
||||||
Matrix matFrustum = { 0 };
|
Matrix matFrustum = { 0 };
|
||||||
|
|
||||||
float rl = (float)(right - left);
|
float rl = right - left;
|
||||||
float tb = (float)(top - bottom);
|
float tb = top - bottom;
|
||||||
float fn = (float)(zfar - znear);
|
float fn = zfar - znear;
|
||||||
|
|
||||||
matFrustum.m0 = ((float) znear*2.0f)/rl;
|
matFrustum.m0 = (znear*2.0f)/rl;
|
||||||
matFrustum.m1 = 0.0f;
|
matFrustum.m1 = 0.0f;
|
||||||
matFrustum.m2 = 0.0f;
|
matFrustum.m2 = 0.0f;
|
||||||
matFrustum.m3 = 0.0f;
|
matFrustum.m3 = 0.0f;
|
||||||
|
|
||||||
matFrustum.m4 = 0.0f;
|
matFrustum.m4 = 0.0f;
|
||||||
matFrustum.m5 = ((float) znear*2.0f)/tb;
|
matFrustum.m5 = (znear*2.0f)/tb;
|
||||||
matFrustum.m6 = 0.0f;
|
matFrustum.m6 = 0.0f;
|
||||||
matFrustum.m7 = 0.0f;
|
matFrustum.m7 = 0.0f;
|
||||||
|
|
||||||
matFrustum.m8 = ((float)right + (float)left)/rl;
|
matFrustum.m8 = (right + left)/rl;
|
||||||
matFrustum.m9 = ((float)top + (float)bottom)/tb;
|
matFrustum.m9 = (top + bottom)/tb;
|
||||||
matFrustum.m10 = -((float)zfar + (float)znear)/fn;
|
matFrustum.m10 = -(zfar + znear)/fn;
|
||||||
matFrustum.m11 = -1.0f;
|
matFrustum.m11 = -1.0f;
|
||||||
|
|
||||||
matFrustum.m12 = 0.0f;
|
matFrustum.m12 = 0.0f;
|
||||||
matFrustum.m13 = 0.0f;
|
matFrustum.m13 = 0.0f;
|
||||||
matFrustum.m14 = -((float)zfar*(float)znear*2.0f)/fn;
|
matFrustum.m14 = -(zfar*znear*2.0f)/fn;
|
||||||
matFrustum.m15 = 0.0f;
|
matFrustum.m15 = 0.0f;
|
||||||
|
|
||||||
*RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matFrustum);
|
*RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matFrustum);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply the current matrix by an orthographic matrix generated by parameters
|
// Multiply the current matrix by an orthographic matrix generated by parameters
|
||||||
void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
|
void rlOrtho(float left, float right, float bottom, float top, float znear, float zfar)
|
||||||
{
|
{
|
||||||
// NOTE: If left-right and top-botton values are equal it could create a division by zero,
|
// NOTE: If left-right and top-botton values are equal it could create a division by zero,
|
||||||
// response to it is platform/compiler dependent
|
// response to it is platform/compiler dependent
|
||||||
Matrix matOrtho = { 0 };
|
Matrix matOrtho = { 0 };
|
||||||
|
|
||||||
float rl = (float)(right - left);
|
float rl = right - left;
|
||||||
float tb = (float)(top - bottom);
|
float tb = top - bottom;
|
||||||
float fn = (float)(zfar - znear);
|
float fn = zfar - znear;
|
||||||
|
|
||||||
matOrtho.m0 = 2.0f/rl;
|
matOrtho.m0 = 2.0f/rl;
|
||||||
matOrtho.m1 = 0.0f;
|
matOrtho.m1 = 0.0f;
|
||||||
@ -1386,9 +1386,9 @@ void rlOrtho(double left, double right, double bottom, double top, double znear,
|
|||||||
matOrtho.m9 = 0.0f;
|
matOrtho.m9 = 0.0f;
|
||||||
matOrtho.m10 = -2.0f/fn;
|
matOrtho.m10 = -2.0f/fn;
|
||||||
matOrtho.m11 = 0.0f;
|
matOrtho.m11 = 0.0f;
|
||||||
matOrtho.m12 = -((float)left + (float)right)/rl;
|
matOrtho.m12 = -(left + right)/rl;
|
||||||
matOrtho.m13 = -((float)top + (float)bottom)/tb;
|
matOrtho.m13 = -(top + bottom)/tb;
|
||||||
matOrtho.m14 = -((float)zfar + (float)znear)/fn;
|
matOrtho.m14 = -(zfar + znear)/fn;
|
||||||
matOrtho.m15 = 1.0f;
|
matOrtho.m15 = 1.0f;
|
||||||
|
|
||||||
*RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
|
*RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
|
||||||
@ -1402,20 +1402,20 @@ void rlViewport(int x, int y, int width, int height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set clip planes distances
|
// Set clip planes distances
|
||||||
void rlSetClipPlanes(double nearPlane, double farPlane)
|
void rlSetClipPlanes(float nearPlane, float farPlane)
|
||||||
{
|
{
|
||||||
rlCullDistanceNear = nearPlane;
|
rlCullDistanceNear = nearPlane;
|
||||||
rlCullDistanceFar = farPlane;
|
rlCullDistanceFar = farPlane;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get cull plane distance near
|
// Get cull plane distance near
|
||||||
double rlGetCullDistanceNear(void)
|
float rlGetCullDistanceNear(void)
|
||||||
{
|
{
|
||||||
return rlCullDistanceNear;
|
return rlCullDistanceNear;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get cull plane distance far
|
// Get cull plane distance far
|
||||||
double rlGetCullDistanceFar(void)
|
float rlGetCullDistanceFar(void)
|
||||||
{
|
{
|
||||||
return rlCullDistanceFar;
|
return rlCullDistanceFar;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -512,7 +512,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|
|||||||
if (fileData != NULL)
|
if (fileData != NULL)
|
||||||
{
|
{
|
||||||
qoi_desc desc = { 0 };
|
qoi_desc desc = { 0 };
|
||||||
image.data = qoi_decode(fileData, dataSize, &desc, (int) fileData[12]);
|
image.data = qoi_decode(fileData, dataSize, &desc, 0); // NOTE: Using channels from file data
|
||||||
image.width = desc.width;
|
image.width = desc.width;
|
||||||
image.height = desc.height;
|
image.height = desc.height;
|
||||||
image.format = (desc.channels == 4)? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8;
|
image.format = (desc.channels == 4)? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8;
|
||||||
@ -540,7 +540,6 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|
|||||||
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
||||||
image.mipmaps = 1;
|
image.mipmaps = 1;
|
||||||
|
|
||||||
PEP_FREE(pepData);
|
|
||||||
pep_free(&p);
|
pep_free(&p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1269,48 +1268,58 @@ void ImageCrop(Image *image, Rectangle crop)
|
|||||||
// Security check to avoid program crash
|
// Security check to avoid program crash
|
||||||
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
|
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
|
||||||
|
|
||||||
|
crop.x = floorf(crop.x);
|
||||||
|
crop.y = floorf(crop.y);
|
||||||
|
crop.width = floorf(crop.width);
|
||||||
|
crop.height = floorf(crop.height);
|
||||||
|
|
||||||
// Security checks to validate crop rectangle
|
// Security checks to validate crop rectangle
|
||||||
if (crop.x < 0) { crop.width += crop.x; crop.x = 0; }
|
if (crop.x < 0) { crop.width += crop.x; crop.x = 0; }
|
||||||
if (crop.y < 0) { crop.height += crop.y; crop.y = 0; }
|
if (crop.y < 0) { crop.height += crop.y; crop.y = 0; }
|
||||||
if ((crop.x + crop.width) > image->width) crop.width = image->width - crop.x;
|
if ((crop.x + crop.width) > image->width) crop.width = image->width - crop.x;
|
||||||
if ((crop.y + crop.height) > image->height) crop.height = image->height - crop.y;
|
if ((crop.y + crop.height) > image->height) crop.height = image->height - crop.y;
|
||||||
if ((crop.x > image->width) || (crop.y > image->height))
|
if ((crop.x > image->width) || (crop.y > image->height) || (crop.width < 1) || (crop.height < 1))
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "IMAGE: Failed to crop, rectangle out of bounds");
|
TRACELOG(LOG_WARNING, "IMAGE: Failed to crop, rectangle out of bounds");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cropX = (int)crop.x;
|
||||||
|
int cropY = (int)crop.y;
|
||||||
|
int cropWidth = (int)crop.width;
|
||||||
|
int cropHeight = (int)crop.height;
|
||||||
|
|
||||||
if (image->mipmaps > 1) TRACELOG(LOG_WARNING, "Image manipulation only applied to base mipmap level");
|
if (image->mipmaps > 1) TRACELOG(LOG_WARNING, "Image manipulation only applied to base mipmap level");
|
||||||
if (image->format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
|
if (image->format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
|
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
|
||||||
|
|
||||||
unsigned char *croppedData = (unsigned char *)RL_MALLOC((int)(crop.width*crop.height)*bytesPerPixel);
|
unsigned char *croppedData = (unsigned char *)RL_MALLOC(cropWidth*cropHeight*bytesPerPixel);
|
||||||
|
|
||||||
// OPTION 1: Move cropped data line-by-line
|
// OPTION 1: Move cropped data line-by-line
|
||||||
for (int y = (int)crop.y, offsetSize = 0; y < (int)(crop.y + crop.height); y++)
|
for (int y = cropY, offsetSize = 0; y < cropY + cropHeight; y++)
|
||||||
{
|
{
|
||||||
memcpy(croppedData + offsetSize, ((unsigned char *)image->data) + (y*image->width + (int)crop.x)*bytesPerPixel, (int)crop.width*bytesPerPixel);
|
memcpy(croppedData + offsetSize, ((unsigned char *)image->data) + (y*image->width + cropX)*bytesPerPixel, cropWidth*bytesPerPixel);
|
||||||
offsetSize += ((int)crop.width*bytesPerPixel);
|
offsetSize += (cropWidth*bytesPerPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// OPTION 2: Move cropped data pixel-by-pixel or byte-by-byte
|
// OPTION 2: Move cropped data pixel-by-pixel or byte-by-byte
|
||||||
for (int y = (int)crop.y; y < (int)(crop.y + crop.height); y++)
|
for (int y = cropY; y < cropY + cropHeight; y++)
|
||||||
{
|
{
|
||||||
for (int x = (int)crop.x; x < (int)(crop.x + crop.width); x++)
|
for (int x = cropX; x < cropX + cropWidth; x++)
|
||||||
{
|
{
|
||||||
//memcpy(croppedData + ((y - (int)crop.y)*(int)crop.width + (x - (int)crop.x))*bytesPerPixel, ((unsigned char *)image->data) + (y*image->width + x)*bytesPerPixel, bytesPerPixel);
|
//memcpy(croppedData + ((y - cropY)*cropWidth + (x - cropX))*bytesPerPixel, ((unsigned char *)image->data) + (y*image->width + x)*bytesPerPixel, bytesPerPixel);
|
||||||
for (int i = 0; i < bytesPerPixel; i++) croppedData[((y - (int)crop.y)*(int)crop.width + (x - (int)crop.x))*bytesPerPixel + i] = ((unsigned char *)image->data)[(y*image->width + x)*bytesPerPixel + i];
|
for (int i = 0; i < bytesPerPixel; i++) croppedData[((y - cropY)*cropWidth + (x - cropX))*bytesPerPixel + i] = ((unsigned char *)image->data)[(y*image->width + x)*bytesPerPixel + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RL_FREE(image->data);
|
RL_FREE(image->data);
|
||||||
image->data = croppedData;
|
image->data = croppedData;
|
||||||
image->width = (int)crop.width;
|
image->width = cropWidth;
|
||||||
image->height = (int)crop.height;
|
image->height = cropHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1547,13 +1556,25 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
|
|||||||
int textLength = (int)strlen(text); // Get length of text in bytes
|
int textLength = (int)strlen(text); // Get length of text in bytes
|
||||||
int textOffsetX = 0; // Image drawing position X
|
int textOffsetX = 0; // Image drawing position X
|
||||||
int textOffsetY = 0; // Offset between lines (on linebreak '\n')
|
int textOffsetY = 0; // Offset between lines (on linebreak '\n')
|
||||||
|
int lineIndex = 0; // Current line index (on linebreak '\n')
|
||||||
|
|
||||||
// NOTE: Text image is generated at font base size, later scaled to desired font size
|
// NOTE: Text image is generated at font base size, later scaled to desired font size
|
||||||
Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing); // WARNING: Module required: rtext
|
Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing); // WARNING: Module required: rtext
|
||||||
Vector2 textSize = MeasureTextEx(font, text, fontSize, spacing);
|
Vector2 textSize = MeasureTextEx(font, text, fontSize, spacing);
|
||||||
|
|
||||||
|
int lineBreakCount = 0; // Number of line breaks ('\n') in text
|
||||||
|
for (int i = 0; i < textLength; i++)
|
||||||
|
{
|
||||||
|
if (text[i] == '\n') lineBreakCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
float lineSpacing = 0.0f; // Line spacing, as used by MeasureTextEx()
|
||||||
|
if (lineBreakCount > 0) lineSpacing = (textSize.y - fontSize)/lineBreakCount - fontSize;
|
||||||
|
|
||||||
|
float lineStep = (float)font.baseSize + lineSpacing*(float)font.baseSize/fontSize; // Line advance at base size
|
||||||
|
|
||||||
// Create image to store text
|
// Create image to store text
|
||||||
imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK);
|
imText = GenImageColor((int)imSize.x, font.baseSize + (int)(lineBreakCount*lineStep), BLANK);
|
||||||
|
|
||||||
for (int i = 0; i < textLength;)
|
for (int i = 0; i < textLength;)
|
||||||
{
|
{
|
||||||
@ -1564,9 +1585,8 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
|
|||||||
|
|
||||||
if (codepoint == '\n')
|
if (codepoint == '\n')
|
||||||
{
|
{
|
||||||
// NOTE: Fixed line spacing of 1.5 line-height
|
lineIndex++;
|
||||||
// TODO: Support custom line spacing defined by user
|
textOffsetY = (int)(lineIndex*lineStep);
|
||||||
textOffsetY += (font.baseSize + font.baseSize/2);
|
|
||||||
textOffsetX = 0;
|
textOffsetX = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1586,15 +1606,15 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Scale image depending on text size
|
// Scale image depending on text size
|
||||||
if (textSize.y != imSize.y)
|
if (fontSize != (float)font.baseSize)
|
||||||
{
|
{
|
||||||
float scaleFactor = textSize.y/imSize.y;
|
float scaleFactor = fontSize/(float)font.baseSize;
|
||||||
TRACELOG(LOG_INFO, "IMAGE: Text scaled by factor: %f", scaleFactor);
|
TRACELOG(LOG_INFO, "IMAGE: Text scaled by factor: %f", scaleFactor);
|
||||||
|
|
||||||
// Using nearest-neighbor scaling algorithm for default font
|
// Using nearest-neighbor scaling algorithm for default font
|
||||||
// TODO: Support other scaling mechanism, use flag?
|
// TODO: Support other scaling mechanism, use flag?
|
||||||
if (font.texture.id == GetFontDefault().texture.id) ImageResizeNN(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
|
if (font.texture.id == GetFontDefault().texture.id) ImageResizeNN(&imText, (int)(imText.width*scaleFactor), (int)(imText.height*scaleFactor));
|
||||||
else ImageResize(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
|
else ImageResize(&imText, (int)(imText.width*scaleFactor), (int)(imText.height*scaleFactor));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
imText = GenImageColor(200, 60, BLACK); // Generating placeholder black image rectangle
|
imText = GenImageColor(200, 60, BLACK); // Generating placeholder black image rectangle
|
||||||
@ -2904,13 +2924,13 @@ void ImageColorBrightness(Image *image, int brightness)
|
|||||||
int cG = pixels[i].g + brightness;
|
int cG = pixels[i].g + brightness;
|
||||||
int cB = pixels[i].b + brightness;
|
int cB = pixels[i].b + brightness;
|
||||||
|
|
||||||
if (cR < 0) cR = 1;
|
if (cR < 0) cR = 0;
|
||||||
if (cR > 255) cR = 255;
|
if (cR > 255) cR = 255;
|
||||||
|
|
||||||
if (cG < 0) cG = 1;
|
if (cG < 0) cG = 0;
|
||||||
if (cG > 255) cG = 255;
|
if (cG > 255) cG = 255;
|
||||||
|
|
||||||
if (cB < 0) cB = 1;
|
if (cB < 0) cB = 0;
|
||||||
if (cB > 255) cB = 255;
|
if (cB > 255) cB = 255;
|
||||||
|
|
||||||
pixels[i].r = (unsigned char)cR;
|
pixels[i].r = (unsigned char)cR;
|
||||||
@ -3011,9 +3031,9 @@ Color *LoadImageColors(Image image)
|
|||||||
{
|
{
|
||||||
unsigned short pixel = ((unsigned short *)image.data)[i];
|
unsigned short pixel = ((unsigned short *)image.data)[i];
|
||||||
|
|
||||||
pixels[i].r = (unsigned char)((float)((pixel & 0b1111100000000000) >> 11)*(255/31));
|
pixels[i].r = (unsigned char)((float)((pixel & 0b1111100000000000) >> 11)*255.0f/31);
|
||||||
pixels[i].g = (unsigned char)((float)((pixel & 0b0000011111000000) >> 6)*(255/31));
|
pixels[i].g = (unsigned char)((float)((pixel & 0b0000011111000000) >> 6)*255.0f/31);
|
||||||
pixels[i].b = (unsigned char)((float)((pixel & 0b0000000000111110) >> 1)*(255/31));
|
pixels[i].b = (unsigned char)((float)((pixel & 0b0000000000111110) >> 1)*255.0f/31);
|
||||||
pixels[i].a = (unsigned char)((pixel & 0b0000000000000001)*255);
|
pixels[i].a = (unsigned char)((pixel & 0b0000000000000001)*255);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
@ -3021,9 +3041,9 @@ Color *LoadImageColors(Image image)
|
|||||||
{
|
{
|
||||||
unsigned short pixel = ((unsigned short *)image.data)[i];
|
unsigned short pixel = ((unsigned short *)image.data)[i];
|
||||||
|
|
||||||
pixels[i].r = (unsigned char)((float)((pixel & 0b1111100000000000) >> 11)*(255/31));
|
pixels[i].r = (unsigned char)((float)((pixel & 0b1111100000000000) >> 11)*255.0f/31);
|
||||||
pixels[i].g = (unsigned char)((float)((pixel & 0b0000011111100000) >> 5)*(255/63));
|
pixels[i].g = (unsigned char)((float)((pixel & 0b0000011111100000) >> 5)*255.0f/63);
|
||||||
pixels[i].b = (unsigned char)((float)(pixel & 0b0000000000011111)*(255/31));
|
pixels[i].b = (unsigned char)((float)(pixel & 0b0000000000011111)*255.0f/31);
|
||||||
pixels[i].a = 255;
|
pixels[i].a = 255;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
@ -3255,9 +3275,9 @@ Color GetImageColor(Image image, int x, int y)
|
|||||||
{
|
{
|
||||||
unsigned short pixel = ((unsigned short *)image.data)[y*image.width + x];
|
unsigned short pixel = ((unsigned short *)image.data)[y*image.width + x];
|
||||||
|
|
||||||
color.r = (unsigned char)((float)((pixel & 0b1111100000000000) >> 11)*(255/31));
|
color.r = (unsigned char)((float)((pixel & 0b1111100000000000) >> 11)*255.0f/31);
|
||||||
color.g = (unsigned char)((float)((pixel & 0b0000011111000000) >> 6)*(255/31));
|
color.g = (unsigned char)((float)((pixel & 0b0000011111000000) >> 6)*255.0f/31);
|
||||||
color.b = (unsigned char)((float)((pixel & 0b0000000000111110) >> 1)*(255/31));
|
color.b = (unsigned char)((float)((pixel & 0b0000000000111110) >> 1)*255.0f/31);
|
||||||
color.a = (unsigned char)((pixel & 0b0000000000000001)*255);
|
color.a = (unsigned char)((pixel & 0b0000000000000001)*255);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
@ -3265,9 +3285,9 @@ Color GetImageColor(Image image, int x, int y)
|
|||||||
{
|
{
|
||||||
unsigned short pixel = ((unsigned short *)image.data)[y*image.width + x];
|
unsigned short pixel = ((unsigned short *)image.data)[y*image.width + x];
|
||||||
|
|
||||||
color.r = (unsigned char)((float)((pixel & 0b1111100000000000) >> 11)*(255/31));
|
color.r = (unsigned char)((float)((pixel & 0b1111100000000000) >> 11)*255.0f/31);
|
||||||
color.g = (unsigned char)((float)((pixel & 0b0000011111100000) >> 5)*(255/63));
|
color.g = (unsigned char)((float)((pixel & 0b0000011111100000) >> 5)*255.0f/63);
|
||||||
color.b = (unsigned char)((float)(pixel & 0b0000000000011111)*(255/31));
|
color.b = (unsigned char)((float)(pixel & 0b0000000000011111)*255.0f/31);
|
||||||
color.a = 255;
|
color.a = 255;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@ -106,8 +106,8 @@ reasings_api.$(EXTENSION): ../../examples/others/reasings.h rlparser
|
|||||||
./rlparser -i ../../examples/others/reasings.h -o reasings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
|
./rlparser -i ../../examples/others/reasings.h -o reasings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
|
||||||
|
|
||||||
# rlparser execution: [raygui.h] parse, generating some output files
|
# rlparser execution: [raygui.h] parse, generating some output files
|
||||||
raygui_api.$(EXTENSION): ../raygui.h rlparser
|
raygui_api.$(EXTENSION): ../../examples/core/raygui.h rlparser
|
||||||
./rlparser -i ../raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI -t "RAYGUI IMPLEMENTATION"
|
./rlparser -i ../../examples/core/raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI -t "RAYGUI IMPLEMENTATION"
|
||||||
|
|
||||||
# Target to generate required APIs output files
|
# Target to generate required APIs output files
|
||||||
parse: raylib_api.$(EXTENSION) raymath_api.$(EXTENSION) rlgl_api.$(EXTENSION) raygui_api.$(EXTENSION)
|
parse: raylib_api.$(EXTENSION) raymath_api.$(EXTENSION) rlgl_api.$(EXTENSION) raygui_api.$(EXTENSION)
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
{
|
{
|
||||||
"name": "RAYLIB_VERSION_MINOR",
|
"name": "RAYLIB_VERSION_MINOR",
|
||||||
"type": "INT",
|
"type": "INT",
|
||||||
"value": 2,
|
"value": 5,
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@
|
|||||||
{
|
{
|
||||||
"name": "RAYLIB_VERSION",
|
"name": "RAYLIB_VERSION",
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"value": "6.2",
|
"value": "6.5-dev",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -15,7 +15,7 @@ return {
|
|||||||
{
|
{
|
||||||
name = "RAYLIB_VERSION_MINOR",
|
name = "RAYLIB_VERSION_MINOR",
|
||||||
type = "INT",
|
type = "INT",
|
||||||
value = 2,
|
value = 5,
|
||||||
description = ""
|
description = ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -27,7 +27,7 @@ return {
|
|||||||
{
|
{
|
||||||
name = "RAYLIB_VERSION",
|
name = "RAYLIB_VERSION",
|
||||||
type = "STRING",
|
type = "STRING",
|
||||||
value = "6.2",
|
value = "6.5-dev",
|
||||||
description = ""
|
description = ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
(description ""))
|
(description ""))
|
||||||
((name "RAYLIB_VERSION_MINOR")
|
((name "RAYLIB_VERSION_MINOR")
|
||||||
(type "INT")
|
(type "INT")
|
||||||
(value 2)
|
(value 5)
|
||||||
(description ""))
|
(description ""))
|
||||||
((name "RAYLIB_VERSION_PATCH")
|
((name "RAYLIB_VERSION_PATCH")
|
||||||
(type "INT")
|
(type "INT")
|
||||||
@ -17,7 +17,7 @@
|
|||||||
(description ""))
|
(description ""))
|
||||||
((name "RAYLIB_VERSION")
|
((name "RAYLIB_VERSION")
|
||||||
(type "STRING")
|
(type "STRING")
|
||||||
(value "6.2")
|
(value "6.5-dev")
|
||||||
(description ""))
|
(description ""))
|
||||||
((name "__declspec(x)")
|
((name "__declspec(x)")
|
||||||
(type "MACRO")
|
(type "MACRO")
|
||||||
|
|||||||
@ -14,7 +14,7 @@ Define 002: RAYLIB_VERSION_MAJOR
|
|||||||
Define 003: RAYLIB_VERSION_MINOR
|
Define 003: RAYLIB_VERSION_MINOR
|
||||||
Name: RAYLIB_VERSION_MINOR
|
Name: RAYLIB_VERSION_MINOR
|
||||||
Type: INT
|
Type: INT
|
||||||
Value: 2
|
Value: 5
|
||||||
Description:
|
Description:
|
||||||
Define 004: RAYLIB_VERSION_PATCH
|
Define 004: RAYLIB_VERSION_PATCH
|
||||||
Name: RAYLIB_VERSION_PATCH
|
Name: RAYLIB_VERSION_PATCH
|
||||||
@ -24,7 +24,7 @@ Define 004: RAYLIB_VERSION_PATCH
|
|||||||
Define 005: RAYLIB_VERSION
|
Define 005: RAYLIB_VERSION
|
||||||
Name: RAYLIB_VERSION
|
Name: RAYLIB_VERSION
|
||||||
Type: STRING
|
Type: STRING
|
||||||
Value: "6.2"
|
Value: "6.5-dev"
|
||||||
Description:
|
Description:
|
||||||
Define 006: __declspec(x)
|
Define 006: __declspec(x)
|
||||||
Name: __declspec(x)
|
Name: __declspec(x)
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
<Defines count="56">
|
<Defines count="56">
|
||||||
<Define name="RAYLIB_H" type="GUARD" value="" desc="" />
|
<Define name="RAYLIB_H" type="GUARD" value="" desc="" />
|
||||||
<Define name="RAYLIB_VERSION_MAJOR" type="INT" value="6" desc="" />
|
<Define name="RAYLIB_VERSION_MAJOR" type="INT" value="6" desc="" />
|
||||||
<Define name="RAYLIB_VERSION_MINOR" type="INT" value="2" desc="" />
|
<Define name="RAYLIB_VERSION_MINOR" type="INT" value="5" desc="" />
|
||||||
<Define name="RAYLIB_VERSION_PATCH" type="INT" value="0" desc="" />
|
<Define name="RAYLIB_VERSION_PATCH" type="INT" value="0" desc="" />
|
||||||
<Define name="RAYLIB_VERSION" type="STRING" value="6.2" desc="" />
|
<Define name="RAYLIB_VERSION" type="STRING" value="6.5-dev" desc="" />
|
||||||
<Define name="__declspec(x)" type="MACRO" value="__attribute__((x))" desc="" />
|
<Define name="__declspec(x)" type="MACRO" value="__attribute__((x))" desc="" />
|
||||||
<Define name="RLAPI" type="UNKNOWN" value="__declspec(dllexport)" desc="Building the library as a Win32 shared library (.dll)" />
|
<Define name="RLAPI" type="UNKNOWN" value="__declspec(dllexport)" desc="Building the library as a Win32 shared library (.dll)" />
|
||||||
<Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" />
|
<Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" />
|
||||||
|
|||||||
Reference in New Issue
Block a user