diff --git a/.gitignore b/.gitignore
index a1ca6c009..9153a03ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,11 @@
# Ignore generated files
# ...
+# Ignore all without extensions
+*
+!*.*
+!*/
+
# Ignore VIM's backup generated files
*.swp
*.swo
diff --git a/BINDINGS.md b/BINDINGS.md
index 1c43d1871..87a076b00 100644
--- a/BINDINGS.md
+++ b/BINDINGS.md
@@ -1,13 +1,12 @@
-## raylib bindings
+# raylib bindings and wrappers
-Some people ported raylib to other languages in form of bindings or wrappers to the library.
+Some people ported raylib to other languages in form of bindings or wrappers to the library. Here it is alist with all the ports available. Feel free to send a PR if you know of any binding/wrapper not in this list.
-Here it is a list with the ones I'm aware of:
+### Language Bindings
| name | raylib version | language | repo |
|:------------------:|:-------------: | :--------:|----------------------------------------------------------------------|
-| raylib | **3.7** | [C](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib |
-| raylib-cpp | 3.7 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp |
+| raylib | **3.7** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib |
| Raylib-cs | 3.7 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs |
| raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp |
| raylib-boo | 3.7 | [Boo](http://boo-language.github.io/) | https://github.com/Rabios/raylib-boo |
@@ -28,6 +27,7 @@ Here it is a list with the ones I'm aware of:
| raylib-luamore | 3.0 | [Lua](http://www.lua.org/) | https://github.com/HDPLocust/raylib-luamore |
| raylua | 3.7 | [Lua](http://www.lua.org/) | https://github.com/Rabios/raylua |
| LuaJIT-Raylib | 2.6 | [Lua](http://www.lua.org/) | https://github.com/Bambofy/LuaJIT-Raylib |
+| raylib-nelua | 3.7 | [nelua](https://nelua.io/) | https://github.com/edubart/nelua-decl/tree/main/libs/raylib |
| raylib-nelua | 3.0 | [Nelua](https://nelua.io/) | https://github.com/Andre-LA/raylib-nelua |
| raylib-Nim | 1.7 | [Nim](https://nim-lang.org/) | https://gitlab.com/define-private-public/raylib-Nim |
| raylib-nim | 2.0 | [Nim](https://nim-lang.org/) | https://github.com/Skrylar/raylib-nim |
@@ -98,8 +98,13 @@ Here it is a list with the ones I'm aware of:
| Relib | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | https://github.com/RedCubeDev-ByteSpace/Relib |
| raylib.cbl | 2.0 | [COBOL](https://en.wikipedia.org/wiki/COBOL) | *[code examples](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)* |
+### Utility Wrapers
+
+| name | raylib version | language | repo |
+|:------------------:|:-------------: | :--------:|----------------------------------------------------------------------|
+| raylib-cpp | 3.7 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp |
-Missing some language? Feel free to create a new binding! :)
+Missing some language or wrapper? Feel free to create a new one! :)
Usually, raylib bindings follow the convention: `raylib-{language}`
diff --git a/SPONSORS.md b/SPONSORS.md
index c4822d0e0..c308a513c 100644
--- a/SPONSORS.md
+++ b/SPONSORS.md
@@ -27,6 +27,7 @@ Note that Sponsors donations vary between sponsors, I just decided not to make a
- Merlyn Morgan-Graham ([@kavika13](https://github.com/kavika13))
- Toby4213 ([@Toby4213](https://github.com/Toby4213))
- linus ([@hochbaum](https://github.com/hochbaum))
+ - Nawarian ([@nawarian](https://github.com/nawarian) - [thephp.website](https://thephp.website/))
### Past raylib GitHub Sponsors
diff --git a/examples/audio/resources/LICENSE.md b/examples/audio/resources/LICENSE.md
index c94731c94..67e65845a 100644
--- a/examples/audio/resources/LICENSE.md
+++ b/examples/audio/resources/LICENSE.md
@@ -3,8 +3,8 @@
| country.mp3 | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Originally created for "DART that TARGET" game |
| target.ogg | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Originally created for "DART that TARGET" game |
| target.flac | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Originally created for "DART that TARGET" game |
-| coin.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Created using [rFXGen](https://raylibtech.itch.io/rfxgen) |
-| sound.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Created using [rFXGen](https://raylibtech.itch.io/rfxgen) |
-| spring.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Created using [rFXGen](https://raylibtech.itch.io/rfxgen) |
-| weird.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Created using [rFXGen](https://raylibtech.itch.io/rfxgen) |
+| coin.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
+| sound.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
+| spring.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
+| weird.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
| mini1111.xm | [tPORt](https://modarchive.org/index.php?request=view_by_moduleid&query=51891) | [Mod Archive Distribution license](https://modarchive.org/index.php?terms-upload) | - |
diff --git a/examples/core/resources/LICENSE b/examples/core/resources/LICENSE.md
similarity index 100%
rename from examples/core/resources/LICENSE
rename to examples/core/resources/LICENSE.md
diff --git a/examples/models/resources/LICENSE.md b/examples/models/resources/LICENSE.md
new file mode 100644
index 000000000..6483ae849
--- /dev/null
+++ b/examples/models/resources/LICENSE.md
@@ -0,0 +1,20 @@
+| resource | author | licence | notes |
+| :------------------- | :---------: | :------ | :---- |
+| models/castle.obj,
models/castle_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/bridge.obj,
models/bridge_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/house.obj,
models/house_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/market.obj,
models/market_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/turret.obj,
models/turret_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/well.obj,
models/well_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/cube.obj,
models/cube_diffuse.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| models/vertex_colored_object.iqm | ❔ | ❔ | - |
+| billboard.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| cubicmap_atlas.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| heightmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| dresden_square_1k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
+| dresden_square_2k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
+| skybox.png | ❔ | ❔ | - |
+| **guy/...** | [@culacant](https://github.com/culacant) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) |
+| **plane/...** | [GiaHanLam](https://sketchfab.com/GiaHanLam) | [CC-BY](https://creativecommons.org/licenses/by/4.0/) | Used by: [`models_yaw_pitch_roll.c`](https://github.com/raysan5/raylib/blob/master/examples/models/models_yaw_pitch_roll.c)
+| **gltf/...** | _various_ | [LICENSE](https://github.com/raysan5/raylib/blob/master/examples/models/resources/gltf/LICENSE) | - |
diff --git a/examples/models/resources/models/LICENSE b/examples/models/resources/models/LICENSE
deleted file mode 100644
index 39cdd6144..000000000
--- a/examples/models/resources/models/LICENSE
+++ /dev/null
@@ -1,4 +0,0 @@
-Medieval City models and textures have been created by Alberto Cano,
-and licensed as Creative Commons Attribution-NonCommercial 4.0.
-
-Check for details: https://creativecommons.org/licenses/by-nc/4.0/legalcode
diff --git a/examples/network/network_ping_pong.c b/examples/network/network_ping_pong.c
index ec45f6445..7b5dd2dd6 100644
--- a/examples/network/network_ping_pong.c
+++ b/examples/network/network_ping_pong.c
@@ -12,7 +12,7 @@
#include "raylib.h"
#define RNET_IMPLEMENTATION
-#include "rnet.h"
+#include "extras/rnet.h"
float elapsed = 0.0f;
float delay = 1.0f;
diff --git a/examples/network/network_resolve_host.c b/examples/network/network_resolve_host.c
index a6e9ecdf4..a00ccb2d2 100644
--- a/examples/network/network_resolve_host.c
+++ b/examples/network/network_resolve_host.c
@@ -12,7 +12,7 @@
#include "raylib.h"
#define RNET_IMPLEMENTATION
-#include "rnet.h"
+#include "extras/rnet.h"
int main(void)
{
diff --git a/examples/network/network_tcp_client.c b/examples/network/network_tcp_client.c
index 1779a3a4a..ad78c691e 100644
--- a/examples/network/network_tcp_client.c
+++ b/examples/network/network_tcp_client.c
@@ -12,7 +12,7 @@
#include "raylib.h"
#define RNET_IMPLEMENTATION
-#include "rnet.h"
+#include "extras/rnet.h"
int main(void)
{
diff --git a/examples/network/network_tcp_server.c b/examples/network/network_tcp_server.c
index 5cbbe54bd..bffe03fa5 100644
--- a/examples/network/network_tcp_server.c
+++ b/examples/network/network_tcp_server.c
@@ -12,7 +12,7 @@
#include "raylib.h"
#define RNET_IMPLEMENTATION
-#include "rnet.h"
+#include "extras/rnet.h"
int main(void)
{
diff --git a/examples/network/network_test.c b/examples/network/network_test.c
index 957ed8ba0..70349e79c 100644
--- a/examples/network/network_test.c
+++ b/examples/network/network_test.c
@@ -12,7 +12,7 @@
#include "raylib.h"
#define RNET_IMPLEMENTATION
-#include "rnet.h"
+#include "extras/rnet.h"
#include
diff --git a/examples/network/network_udp_client.c b/examples/network/network_udp_client.c
index d351372b5..bcf9fc076 100644
--- a/examples/network/network_udp_client.c
+++ b/examples/network/network_udp_client.c
@@ -12,7 +12,7 @@
#include "raylib.h"
#define RNET_IMPLEMENTATION
-#include "rnet.h"
+#include "extras/rnet.h"
int main(void)
{
diff --git a/examples/network/network_udp_server.c b/examples/network/network_udp_server.c
index 29fffbe7b..eae1c6b33 100644
--- a/examples/network/network_udp_server.c
+++ b/examples/network/network_udp_server.c
@@ -12,7 +12,7 @@
#include "raylib.h"
#define RNET_IMPLEMENTATION
-#include "rnet.h"
+#include "extras/rnet.h"
int main(void)
{
diff --git a/examples/physics/physics_demo.c b/examples/physics/physics_demo.c
index fd4c1d25c..382a4ab37 100644
--- a/examples/physics/physics_demo.c
+++ b/examples/physics/physics_demo.c
@@ -14,7 +14,7 @@
#include "raylib.h"
#define PHYSAC_IMPLEMENTATION
-#include "physac.h"
+#include "extras/physac.h"
int main(void)
{
diff --git a/examples/physics/physics_friction.c b/examples/physics/physics_friction.c
index d1ade9796..f50eb67f2 100644
--- a/examples/physics/physics_friction.c
+++ b/examples/physics/physics_friction.c
@@ -14,7 +14,7 @@
#include "raylib.h"
#define PHYSAC_IMPLEMENTATION
-#include "physac.h"
+#include "extras/physac.h"
int main(void)
{
diff --git a/examples/physics/physics_movement.c b/examples/physics/physics_movement.c
index d6155da15..e13caec75 100644
--- a/examples/physics/physics_movement.c
+++ b/examples/physics/physics_movement.c
@@ -14,7 +14,7 @@
#include "raylib.h"
#define PHYSAC_IMPLEMENTATION
-#include "physac.h"
+#include "extras/physac.h"
#define VELOCITY 0.5f
diff --git a/examples/physics/physics_restitution.c b/examples/physics/physics_restitution.c
index 917ab8d09..91de5589f 100644
--- a/examples/physics/physics_restitution.c
+++ b/examples/physics/physics_restitution.c
@@ -14,7 +14,7 @@
#include "raylib.h"
#define PHYSAC_IMPLEMENTATION
-#include "physac.h"
+#include "extras/physac.h"
int main(void)
{
diff --git a/examples/physics/physics_shatter.c b/examples/physics/physics_shatter.c
index 6c5bebfda..493443863 100644
--- a/examples/physics/physics_shatter.c
+++ b/examples/physics/physics_shatter.c
@@ -14,7 +14,7 @@
#include "raylib.h"
#define PHYSAC_IMPLEMENTATION
-#include "physac.h"
+#include "extras/physac.h"
int main(void)
{
diff --git a/examples/shaders/resources/LICENSE.md b/examples/shaders/resources/LICENSE.md
new file mode 100644
index 000000000..b08a555ab
--- /dev/null
+++ b/examples/shaders/resources/LICENSE.md
@@ -0,0 +1,13 @@
+| resource | author | licence | notes |
+| :----------------- | :-----------: | :------ | :---- |
+| models/barracks.obj,
models/barracks_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/church.obj,
models/church_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| models/watermill.obj,
models/watermill_diffuse.png | [Alberto Cano](https://www.artstation.com/albertocano) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| fudesumi.png | [Eiden Marsal](https://www.artstation.com/marshall_z) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/) | - |
+| mask.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [EffectTextureMaker](https://mebiusbox.github.io/contents/EffectTextureMaker/) |
+| plasma.png | [@chriscamacho](https://github.com/chriscamacho) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| raysan.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
+| space.png | ❔ | ❔ | - |
+| texel_checker.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [UV Checker Map Maker](http://uvchecker.byvalle.com/) |
+| egg.png | [@GoldenThumbs](https://github.com/GoldenThumbs) |
+| torus.png | [@GoldenThumbs](https://github.com/GoldenThumbs) |
diff --git a/examples/shaders/resources/egg.png b/examples/shaders/resources/egg.png
new file mode 100644
index 000000000..c85249523
Binary files /dev/null and b/examples/shaders/resources/egg.png differ
diff --git a/examples/shaders/resources/models/LICENSE b/examples/shaders/resources/models/LICENSE
deleted file mode 100644
index 39cdd6144..000000000
--- a/examples/shaders/resources/models/LICENSE
+++ /dev/null
@@ -1,4 +0,0 @@
-Medieval City models and textures have been created by Alberto Cano,
-and licensed as Creative Commons Attribution-NonCommercial 4.0.
-
-Check for details: https://creativecommons.org/licenses/by-nc/4.0/legalcode
diff --git a/examples/shaders/resources/shaders/glsl100/outline.fs b/examples/shaders/resources/shaders/glsl100/outline.fs
new file mode 100644
index 000000000..67410b3a7
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/outline.fs
@@ -0,0 +1,35 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+uniform vec2 texScale;
+
+// Function for drawing outlines on alpha-blended textures
+vec4 DrawOutline(sampler2D tex, vec2 uv, vec2 lineScale, vec3 lineCol)
+{
+ vec2 texelScale = 1.0 / lineScale;
+ vec4 center = texture2D(tex, uv); // We sample the center texel, (with all color data)
+ // Next we sample four corner texels, but only for the alpha channel (this is for the outline)
+ vec4 corners;
+ corners.x = texture2D(tex, uv+vec2( texelScale.x, texelScale.y)).a;
+ corners.y = texture2D(tex, uv+vec2( texelScale.x,-texelScale.y)).a;
+ corners.z = texture2D(tex, uv+vec2(-texelScale.x, texelScale.y)).a;
+ corners.w = texture2D(tex, uv+vec2(-texelScale.x,-texelScale.y)).a;
+
+ float outline = min(dot(corners, vec4(1.0)), 1.0);
+ vec4 col = mix(vec4(0.0), vec4(lineCol, 1.0), outline);
+ col = mix(col, center, center.a);
+ return col;
+}
+
+void main()
+{
+ gl_FragColor = DrawOutline(texture0, fragTexCoord, texScale, vec3(0.0));
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl330/outline.fs b/examples/shaders/resources/shaders/glsl330/outline.fs
new file mode 100644
index 000000000..c1be1b5de
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl330/outline.fs
@@ -0,0 +1,36 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+uniform vec2 texScale;
+
+// Output fragment color
+out vec4 finalColor;
+
+// Function for drawing outlines on alpha-blended textures
+vec4 DrawOutline(sampler2D tex, vec2 uv, vec2 lineScale, vec3 lineCol)
+{
+ vec2 texelScale = 1.0 / lineScale;
+ vec4 center = texture(tex, uv); // We sample the center texel, (with all color data)
+ // Next we sample four corner texels, but only for the alpha channel (this is for the outline)
+ vec4 corners;
+ corners.x = texture(tex, uv+vec2( texelScale.x, texelScale.y)).a;
+ corners.y = texture(tex, uv+vec2( texelScale.x,-texelScale.y)).a;
+ corners.z = texture(tex, uv+vec2(-texelScale.x, texelScale.y)).a;
+ corners.w = texture(tex, uv+vec2(-texelScale.x,-texelScale.y)).a;
+
+ float outline = min(dot(corners, vec4(1.0)), 1.0);
+ vec4 col = mix(vec4(0.0), vec4(lineCol, 1.0), outline);
+ col = mix(col, center, center.a);
+ return col;
+}
+
+void main()
+{
+ finalColor = DrawOutline(texture0, fragTexCoord, texScale, vec3(0.0));
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/texel_checker.png b/examples/shaders/resources/texel_checker.png
index d413fc555..79d3832ac 100644
Binary files a/examples/shaders/resources/texel_checker.png and b/examples/shaders/resources/texel_checker.png differ
diff --git a/examples/shaders/resources/torus.png b/examples/shaders/resources/torus.png
new file mode 100644
index 000000000..399d78257
Binary files /dev/null and b/examples/shaders/resources/torus.png differ
diff --git a/examples/shaders/shaders_basic_lighting.c b/examples/shaders/shaders_basic_lighting.c
index 6ef09e4aa..347096fd7 100644
--- a/examples/shaders/shaders_basic_lighting.c
+++ b/examples/shaders/shaders_basic_lighting.c
@@ -7,21 +7,13 @@
*
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3).
*
-* This example has been created using raylib 2.5 (www.raylib.com)
+* This example has been created using raylib 3.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
-* Example contributed by Chris Camacho (@codifies) and reviewed by Ramon Santamaria (@raysan5)
+* Example contributed by Chris Camacho (@codifies, http://bedroomcoders.co.uk/) and
+* reviewed by Ramon Santamaria (@raysan5)
*
-* Chris Camacho (@codifies - http://bedroomcoders.co.uk/) notes:
-*
-* This is based on the PBR lighting example, but greatly simplified to aid learning...
-* actually there is very little of the PBR example left!
-* When I first looked at the bewildering complexity of the PBR example I feared
-* I would never understand how I could do simple lighting with raylib however its
-* a testement to the authors of raylib (including rlights.h) that the example
-* came together fairly quickly.
-*
-* Copyright (c) 2019 Chris Camacho (@codifies) and Ramon Santamaria (@raysan5)
+* Copyright (c) 2019-2021 Chris Camacho (@codifies) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
@@ -50,49 +42,39 @@ int main(void)
// Define the camera to look into our 3d world
Camera camera = { 0 };
- camera.position = (Vector3){ 2.0f, 2.0f, 6.0f }; // Camera position
+ camera.position = (Vector3){ 2.0f, 4.0f, 6.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
- camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
-
- // Load models
- Model modelA = LoadModelFromMesh(GenMeshTorus(0.4f, 1.0f, 16, 32));
- Model modelB = LoadModelFromMesh(GenMeshCube(1.0f, 1.0f, 1.0f));
- Model modelC = LoadModelFromMesh(GenMeshSphere(0.5f, 32, 32));
-
- // Load models texture
- Texture texture = LoadTexture("resources/texel_checker.png");
-
- // Assign texture to default model material
- modelA.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
- modelB.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
- modelC.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
+ camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
+ // Load plane model from a generated mesh
+ Model model = LoadModelFromMesh(GenMeshPlane(10.0f, 10.0f, 3, 3));
+ Model cube = LoadModelFromMesh(GenMeshCube(2.0f, 4.0f, 2.0f));
+
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/base_lighting.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/lighting.fs", GLSL_VERSION));
- // Get some shader loactions
- shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
+ // Get some required shader loactions
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
-
- // ambient light level
+ // NOTE: "matModel" location name is automatically assigned on shader loading,
+ // no need to get the location again if using that uniform name
+ //shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
+
+ // Ambient light level (some basic lighting)
int ambientLoc = GetShaderLocation(shader, "ambient");
- SetShaderValue(shader, ambientLoc, (float[4]){ 0.2f, 0.2f, 0.2f, 1.0f }, SHADER_UNIFORM_VEC4);
+ SetShaderValue(shader, ambientLoc, (float[4]){ 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4);
- float angle = 6.282f;
+ // Assign out lighting shader to model
+ model.materials[0].shader = shader;
+ cube.materials[0].shader = shader;
- // All models use the same shader
- modelA.materials[0].shader = shader;
- modelB.materials[0].shader = shader;
- modelC.materials[0].shader = shader;
-
- // Using 4 point lights, white, red, green and blue
+ // Using 4 point lights: gold, red, green and blue
Light lights[MAX_LIGHTS] = { 0 };
- lights[0] = CreateLight(LIGHT_POINT, (Vector3){ 4, 2, 4 }, Vector3Zero(), WHITE, shader);
- lights[1] = CreateLight(LIGHT_POINT, (Vector3){ 4, 2, 4 }, Vector3Zero(), RED, shader);
- lights[2] = CreateLight(LIGHT_POINT, (Vector3){ 0, 4, 2 }, Vector3Zero(), GREEN, shader);
- lights[3] = CreateLight(LIGHT_POINT, (Vector3){ 0, 4, 2 }, Vector3Zero(), BLUE, shader);
+ lights[0] = CreateLight(LIGHT_POINT, (Vector3){ -2, 1, -2 }, Vector3Zero(), YELLOW, shader);
+ lights[1] = CreateLight(LIGHT_POINT, (Vector3){ 2, 1, 2 }, Vector3Zero(), RED, shader);
+ lights[2] = CreateLight(LIGHT_POINT, (Vector3){ -2, 1, 2 }, Vector3Zero(), GREEN, shader);
+ lights[3] = CreateLight(LIGHT_POINT, (Vector3){ 2, 1, -2 }, Vector3Zero(), BLUE, shader);
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
@@ -104,34 +86,21 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
- if (IsKeyPressed(KEY_W)) { lights[0].enabled = !lights[0].enabled; }
+ UpdateCamera(&camera); // Update camera
+
+ // Check key inputs to enable/disable lights
+ if (IsKeyPressed(KEY_Y)) { lights[0].enabled = !lights[0].enabled; }
if (IsKeyPressed(KEY_R)) { lights[1].enabled = !lights[1].enabled; }
if (IsKeyPressed(KEY_G)) { lights[2].enabled = !lights[2].enabled; }
if (IsKeyPressed(KEY_B)) { lights[3].enabled = !lights[3].enabled; }
-
- UpdateCamera(&camera); // Update camera
-
- // Make the lights do differing orbits
- angle -= 0.02f;
- lights[0].position.x = cosf(angle)*4.0f;
- lights[0].position.z = sinf(angle)*4.0f;
- lights[1].position.x = cosf(-angle*0.6f)*4.0f;
- lights[1].position.z = sinf(-angle*0.6f)*4.0f;
- lights[2].position.y = cosf(angle*0.2f)*4.0f;
- lights[2].position.z = sinf(angle*0.2f)*4.0f;
- lights[3].position.y = cosf(-angle*0.35f)*4.0f;
- lights[3].position.z = sinf(-angle*0.35f)*4.0f;
-
+
+ // Update light values (actually, only enable/disable them)
UpdateLightValues(shader, lights[0]);
UpdateLightValues(shader, lights[1]);
UpdateLightValues(shader, lights[2]);
UpdateLightValues(shader, lights[3]);
- // Rotate the torus
- modelA.transform = MatrixMultiply(modelA.transform, MatrixRotateX(-0.025f));
- modelA.transform = MatrixMultiply(modelA.transform, MatrixRotateZ(0.012f));
-
- // Update the light shader with the camera view position
+ // Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
//----------------------------------------------------------------------------------
@@ -144,16 +113,18 @@ int main(void)
BeginMode3D(camera);
- // Draw the three models
- DrawModel(modelA, Vector3Zero(), 1.0f, WHITE);
- DrawModel(modelB, (Vector3){-1.6f,0.0f,0.0f}, 1.0f, WHITE);
- DrawModel(modelC, (Vector3){ 1.6f,0.0f,0.0f}, 1.0f, WHITE);
+ DrawModel(model, Vector3Zero(), 1.0f, WHITE);
+ DrawModel(cube, Vector3Zero(), 1.0f, WHITE);
// Draw markers to show where the lights are
- if (lights[0].enabled) { DrawSphereEx(lights[0].position, 0.2f, 8, 8, WHITE); }
- if (lights[1].enabled) { DrawSphereEx(lights[1].position, 0.2f, 8, 8, RED); }
- if (lights[2].enabled) { DrawSphereEx(lights[2].position, 0.2f, 8, 8, GREEN); }
- if (lights[3].enabled) { DrawSphereEx(lights[3].position, 0.2f, 8, 8, BLUE); }
+ if (lights[0].enabled) DrawSphereEx(lights[0].position, 0.2f, 8, 8, YELLOW);
+ else DrawSphereWires(lights[0].position, 0.2f, 8, 8, ColorAlpha(YELLOW, 0.3f));
+ if (lights[1].enabled) DrawSphereEx(lights[1].position, 0.2f, 8, 8, RED);
+ else DrawSphereWires(lights[1].position, 0.2f, 8, 8, ColorAlpha(RED, 0.3f));
+ if (lights[2].enabled) DrawSphereEx(lights[2].position, 0.2f, 8, 8, GREEN);
+ else DrawSphereWires(lights[2].position, 0.2f, 8, 8, ColorAlpha(GREEN, 0.3f));
+ if (lights[3].enabled) DrawSphereEx(lights[3].position, 0.2f, 8, 8, BLUE);
+ else DrawSphereWires(lights[3].position, 0.2f, 8, 8, ColorAlpha(BLUE, 0.3f));
DrawGrid(10, 1.0f);
@@ -161,7 +132,7 @@ int main(void)
DrawFPS(10, 10);
- DrawText("Use keys RGBW to toggle lights", 10, 30, 20, DARKGRAY);
+ DrawText("Use keys [Y][R][G][B] to toggle lights", 10, 40, 20, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
@@ -169,14 +140,11 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
- UnloadModel(modelA); // Unload the modelA
- UnloadModel(modelB); // Unload the modelB
- UnloadModel(modelC); // Unload the modelC
+ UnloadModel(model); // Unload the model
+ UnloadModel(cube); // Unload the model
+ UnloadShader(shader); // Unload shader
- UnloadTexture(texture); // Unload the texture
- UnloadShader(shader); // Unload shader
-
- CloseWindow(); // Close window and OpenGL context
+ CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
diff --git a/examples/shaders/shaders_basic_lighting.png b/examples/shaders/shaders_basic_lighting.png
index bae869a90..b88b8cf42 100644
Binary files a/examples/shaders/shaders_basic_lighting.png and b/examples/shaders/shaders_basic_lighting.png differ
diff --git a/examples/shaders/shaders_shapes_outline.c b/examples/shaders/shaders_shapes_outline.c
new file mode 100644
index 000000000..d70f7645d
--- /dev/null
+++ b/examples/shaders/shaders_shapes_outline.c
@@ -0,0 +1,84 @@
+/*******************************************************************************************
+*
+* raylib [shaders] example - Apply an shdrOutline to a texture
+*
+* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+*
+* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3).
+*
+* This example has been created using raylib 3.8 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Example contributed by Samuel Skiff (@GoldenThumbs)
+*
+* Copyright (c) 2021 Samuel SKiff (@GoldenThumbs) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#if defined(PLATFORM_DESKTOP)
+ #define GLSL_VERSION 330
+#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+ #define GLSL_VERSION 100
+#endif
+
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [shaders] example - Apply an shdrOutline to a texture");
+
+ Texture2D egg = LoadTexture("resources/egg.png");
+ Texture2D torus = LoadTexture("resources/torus.png");
+ Shader shdrOutline = LoadShader(0, TextFormat("resources/shaders/glsl%i/shdrOutline.fs", GLSL_VERSION));
+
+ float outlineScale = 16.0f;
+ float textureScale[2] = { 16.0f*4, 16.0f*4 };
+ SetShaderValue(shdrOutline, GetShaderLocation(shdrOutline, "texScale"), textureScale, SHADER_UNIFORM_VEC2);
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // TODO: Update your variables here
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginShaderMode(shdrOutline);
+ DrawTextureEx(egg, (Vector2){ 0, 230 }, 0.0, outlineScale, WHITE);
+ DrawTextureEx(torus, (Vector2){ 544, 230 }, 0.0, outlineScale, WHITE);
+ EndShaderMode();
+
+ DrawText("Shader-based shdrOutlines for textures", 190, 200, 20, LIGHTGRAY);
+
+ DrawFPS(710, 10);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadTexture(egg);
+ UnloadTexture(torus);
+ UnloadShader(shdrOutline);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/shapes/easings.h b/examples/shapes/easings.h
deleted file mode 100644
index 892ce3525..000000000
--- a/examples/shapes/easings.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*******************************************************************************************
-*
-* raylib easings (header only file)
-*
-* Useful easing functions for values animation
-*
-* This header uses:
-* #define EASINGS_STATIC_INLINE // Inlines all functions code, so it runs faster.
-* // This requires lots of memory on system.
-* How to use:
-* The four inputs t,b,c,d are defined as follows:
-* t = current time (in any unit measure, but same unit as duration)
-* b = starting value to interpolate
-* c = the total change in value of b that needs to occur
-* d = total time it should take to complete (duration)
-*
-* Example:
-*
-* int currentTime = 0;
-* int duration = 100;
-* float startPositionX = 0.0f;
-* float finalPositionX = 30.0f;
-* float currentPositionX = startPositionX;
-*
-* while (currentPositionX < finalPositionX)
-* {
-* currentPositionX = EaseSineIn(currentTime, startPositionX, finalPositionX - startPositionX, duration);
-* currentTime++;
-* }
-*
-* A port of Robert Penner's easing equations to C (http://robertpenner.com/easing/)
-*
-* Robert Penner License
-* ---------------------------------------------------------------------------------
-* Open source under the BSD License.
-*
-* Copyright (c) 2001 Robert Penner. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification,
-* are permitted provided that the following conditions are met:
-*
-* - Redistributions of source code must retain the above copyright notice,
-* this list of conditions and the following disclaimer.
-* - Redistributions in binary form must reproduce the above copyright notice,
-* this list of conditions and the following disclaimer in the documentation
-* and/or other materials provided with the distribution.
-* - Neither the name of the author nor the names of contributors may be used
-* to endorse or promote products derived from this software without specific
-* prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-* OF THE POSSIBILITY OF SUCH DAMAGE.
-* ---------------------------------------------------------------------------------
-*
-* Copyright (c) 2015 Ramon Santamaria
-*
-* This software is provided "as-is", without any express or implied warranty. In no event
-* will the authors be held liable for any damages arising from the use of this software.
-*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
-*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
-*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
-*
-* 3. This notice may not be removed or altered from any source distribution.
-*
-**********************************************************************************************/
-
-#ifndef EASINGS_H
-#define EASINGS_H
-
-#define EASINGS_STATIC_INLINE // NOTE: By default, compile functions as static inline
-
-#if defined(EASINGS_STATIC_INLINE)
- #define EASEDEF static inline
-#else
- #define EASEDEF extern
-#endif
-
-#include // Required for: sin(), cos(), sqrt(), pow()
-
-#ifndef PI
- #define PI 3.14159265358979323846f //Required as PI is not always defined in math.h
-#endif
-
-#ifdef __cplusplus
-extern "C" { // Prevents name mangling of functions
-#endif
-
-// Linear Easing functions
-EASEDEF float EaseLinearNone(float t, float b, float c, float d) { return (c*t/d + b); }
-EASEDEF float EaseLinearIn(float t, float b, float c, float d) { return (c*t/d + b); }
-EASEDEF float EaseLinearOut(float t, float b, float c, float d) { return (c*t/d + b); }
-EASEDEF float EaseLinearInOut(float t,float b, float c, float d) { return (c*t/d + b); }
-
-// Sine Easing functions
-EASEDEF float EaseSineIn(float t, float b, float c, float d) { return (-c*cos(t/d*(PI/2)) + c + b); }
-EASEDEF float EaseSineOut(float t, float b, float c, float d) { return (c*sin(t/d*(PI/2)) + b); }
-EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2*(cos(PI*t/d) - 1) + b); }
-
-// Circular Easing functions
-EASEDEF float EaseCircIn(float t, float b, float c, float d) { t /= d; return (-c*(sqrt(1 - t*t) - 1) + b); }
-EASEDEF float EaseCircOut(float t, float b, float c, float d) { t = t/d - 1; return (c*sqrt(1 - t*t) + b); }
-EASEDEF float EaseCircInOut(float t, float b, float c, float d)
-{
- if ((t/=d/2) < 1) return (-c/2*(sqrt(1 - t*t) - 1) + b);
- t -= 2; return (c/2*(sqrt(1 - t*t) + 1) + b);
-}
-
-// Cubic Easing functions
-EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + b); }
-EASEDEF float EaseCubicOut(float t, float b, float c, float d) { t = t/d-1; return (c*(t*t*t + 1) + b); }
-EASEDEF float EaseCubicInOut(float t, float b, float c, float d)
-{
- if ((t/=d/2) < 1) return (c/2*t*t*t + b);
- t -= 2; return (c/2*(t*t*t + 2) + b);
-}
-
-// Quadratic Easing functions
-EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); }
-EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2) + b); }
-EASEDEF float EaseQuadInOut(float t, float b, float c, float d)
-{
- if ((t/=d/2) < 1) return (((c/2)*(t*t)) + b);
- t--; return (-c/2*(((t - 2)*t) - 1) + b);
-}
-
-// Exponential Easing functions
-EASEDEF float EaseExpoIn(float t, float b, float c, float d) { return (t == 0) ? b : (c*pow(2, 10*(t/d - 1)) + b); }
-EASEDEF float EaseExpoOut(float t, float b, float c, float d) { return (t == d) ? (b + c) : (c*(-pow(2, -10*t/d) + 1) + b); }
-EASEDEF float EaseExpoInOut(float t, float b, float c, float d)
-{
- if (t == 0) return b;
- if (t == d) return (b + c);
- if ((t/=d/2) < 1) return (c/2*pow(2, 10*(t - 1)) + b);
-
- return (c/2*(-pow(2, -10*--t) + 2) + b);
-}
-
-// Back Easing functions
-EASEDEF float EaseBackIn(float t, float b, float c, float d)
-{
- float s = 1.70158f;
- float postFix = t/=d;
- return (c*(postFix)*t*((s + 1)*t - s) + b);
-}
-
-EASEDEF float EaseBackOut(float t, float b, float c, float d)
-{
- float s = 1.70158f;
- t = t/d - 1;
- return (c*(t*t*((s + 1)*t + s) + 1) + b);
-}
-
-EASEDEF float EaseBackInOut(float t, float b, float c, float d)
-{
- float s = 1.70158f;
- if ((t/=d/2) < 1)
- {
- s *= 1.525f;
- return (c/2*(t*t*((s + 1)*t - s)) + b);
- }
-
- float postFix = t-=2;
- s *= 1.525f;
- return (c/2*((postFix)*t*((s + 1)*t + s) + 2) + b);
-}
-
-// Bounce Easing functions
-EASEDEF float EaseBounceOut(float t, float b, float c, float d)
-{
- if ((t/=d) < (1/2.75f))
- {
- return (c*(7.5625f*t*t) + b);
- }
- else if (t < (2/2.75f))
- {
- float postFix = t-=(1.5f/2.75f);
- return (c*(7.5625f*(postFix)*t + 0.75f) + b);
- }
- else if (t < (2.5/2.75))
- {
- float postFix = t-=(2.25f/2.75f);
- return (c*(7.5625f*(postFix)*t + 0.9375f) + b);
- }
- else
- {
- float postFix = t-=(2.625f/2.75f);
- return (c*(7.5625f*(postFix)*t + 0.984375f) + b);
- }
-}
-
-EASEDEF float EaseBounceIn(float t, float b, float c, float d) { return (c - EaseBounceOut(d-t, 0, c, d) + b); }
-EASEDEF float EaseBounceInOut(float t, float b, float c, float d)
-{
- if (t < d/2) return (EaseBounceIn(t*2, 0, c, d)*0.5f + b);
- else return (EaseBounceOut(t*2-d, 0, c, d)*0.5f + c*0.5f + b);
-}
-
-// Elastic Easing functions
-EASEDEF float EaseElasticIn(float t, float b, float c, float d)
-{
- if (t == 0) return b;
- if ((t/=d) == 1) return (b + c);
-
- float p = d*0.3f;
- float a = c;
- float s = p/4;
- float postFix = a*pow(2, 10*(t-=1));
-
- return (-(postFix*sin((t*d-s)*(2*PI)/p )) + b);
-}
-
-EASEDEF float EaseElasticOut(float t, float b, float c, float d)
-{
- if (t == 0) return b;
- if ((t/=d) == 1) return (b + c);
-
- float p = d*0.3f;
- float a = c;
- float s = p/4;
-
- return (a*pow(2,-10*t)*sin((t*d-s)*(2*PI)/p) + c + b);
-}
-
-EASEDEF float EaseElasticInOut(float t, float b, float c, float d)
-{
- if (t == 0) return b;
- if ((t/=d/2) == 2) return (b + c);
-
- float p = d*(0.3f*1.5f);
- float a = c;
- float s = p/4;
-
- if (t < 1)
- {
- float postFix = a*pow(2, 10*(t-=1));
- return -0.5f*(postFix*sin((t*d-s)*(2*PI)/p)) + b;
- }
-
- float postFix = a*pow(2, -10*(t-=1));
-
- return (postFix*sin((t*d-s)*(2*PI)/p)*0.5f + c + b);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // EASINGS_H
diff --git a/examples/shapes/shapes_draw_circle_sector.c b/examples/shapes/shapes_draw_circle_sector.c
index 009288df6..787b1d4a6 100644
--- a/examples/shapes/shapes_draw_circle_sector.c
+++ b/examples/shapes/shapes_draw_circle_sector.c
@@ -14,7 +14,7 @@
#include
#define RAYGUI_IMPLEMENTATION
-#include "raygui.h" // Required for GUI controls
+#include "extras/raygui.h" // Required for GUI controls
int main(void)
{
diff --git a/examples/shapes/shapes_draw_rectangle_rounded.c b/examples/shapes/shapes_draw_rectangle_rounded.c
index b76e1264d..cc3649806 100644
--- a/examples/shapes/shapes_draw_rectangle_rounded.c
+++ b/examples/shapes/shapes_draw_rectangle_rounded.c
@@ -14,7 +14,7 @@
#include
#define RAYGUI_IMPLEMENTATION
-#include "raygui.h" // Required for GUI controls
+#include "extras/raygui.h" // Required for GUI controls
int main(void)
{
diff --git a/examples/shapes/shapes_draw_ring.c b/examples/shapes/shapes_draw_ring.c
index b60ed2b7e..cd4c1f090 100644
--- a/examples/shapes/shapes_draw_ring.c
+++ b/examples/shapes/shapes_draw_ring.c
@@ -14,7 +14,7 @@
#include
#define RAYGUI_IMPLEMENTATION
-#include "raygui.h" // Required for GUI controls
+#include "extras/raygui.h" // Required for GUI controls
int main(void)
{
diff --git a/examples/shapes/shapes_easings_ball_anim.c b/examples/shapes/shapes_easings_ball_anim.c
index 5bb2b4c66..579d04dd6 100644
--- a/examples/shapes/shapes_easings_ball_anim.c
+++ b/examples/shapes/shapes_easings_ball_anim.c
@@ -11,7 +11,7 @@
#include "raylib.h"
-#include "easings.h" // Required for easing functions
+#include "extras/easings.h" // Required for easing functions
int main(void)
{
diff --git a/examples/shapes/shapes_easings_box_anim.c b/examples/shapes/shapes_easings_box_anim.c
index 6805d5310..7812bd535 100644
--- a/examples/shapes/shapes_easings_box_anim.c
+++ b/examples/shapes/shapes_easings_box_anim.c
@@ -11,7 +11,7 @@
#include "raylib.h"
-#include "easings.h" // Required for easing functions
+#include "extras/easings.h" // Required for easing functions
int main(void)
{
diff --git a/examples/shapes/shapes_easings_rectangle_array.c b/examples/shapes/shapes_easings_rectangle_array.c
index 07de98a05..eb782cd1b 100644
--- a/examples/shapes/shapes_easings_rectangle_array.c
+++ b/examples/shapes/shapes_easings_rectangle_array.c
@@ -14,7 +14,7 @@
#include "raylib.h"
-#include "easings.h" // Required for easing functions
+#include "extras/easings.h" // Required for easing functions
#define RECS_WIDTH 50
#define RECS_HEIGHT 50
diff --git a/examples/shapes/shapes_logo_raylib_anim.c b/examples/shapes/shapes_logo_raylib_anim.c
index fe5eeffb4..f91b6c7d3 100644
--- a/examples/shapes/shapes_logo_raylib_anim.c
+++ b/examples/shapes/shapes_logo_raylib_anim.c
@@ -138,9 +138,9 @@ int main(void)
DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha));
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha));
- DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
+ DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
- DrawText(TextSubtext("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
+ DrawText(TextSubtext("raylib", 0, lettersCount), GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha));
}
else if (state == 4)
{
diff --git a/examples/text/resources/LICENSE b/examples/text/resources/LICENSE
deleted file mode 100644
index 25b154026..000000000
--- a/examples/text/resources/LICENSE
+++ /dev/null
@@ -1,16 +0,0 @@
-All fonts used in examples are provided under a free and permissive license.
-Check individual licenses for details:
-
- - [Alpha Beta] by Brian Kent (AEnigma) - https://www.dafont.com/es/alpha-beta.font
- - [Setback] by Brian Kent (AEnigma) - https://www.dafont.com/es/setback.font
- - [Jupiter Crash] by Brian Kent (AEnigma) - https://www.dafont.com/es/jupiter-crash.font
- - [Alagard] by Hewett Tsoi - https://www.dafont.com/es/alagard.font
- - [Romulus] by Hewett Tsoi - https://www.dafont.com/es/romulus.font
- - [Mecha] by Captain Falcon - https://www.dafont.com/es/mecha-cf.font
- - [PixelPlay] by Aleksander Shevchuk - https://www.dafont.com/es/pixelplay.font
- - [PixAntiqua] by Gerhard Großmann - https://www.dafont.com/es/pixantiqua.font
- - [Kaiserzeit Gotisch] by Dieter Steffmann - https://www.dafont.com/es/kaiserzeit-gotisch.font
- - [Noto CJK] by Google Fonts - https://www.google.com/get/noto/help/cjk/
- - [Anonymous Pro] by Mark Simonson - https://fonts.google.com/specimen/Anonymous+Pro
- - [DejaVu] by DejaVu Fonts - https://dejavu-fonts.github.io/
- - [Symbola] by George Douros - https://fontlibrary.org/en/font/symbola
diff --git a/examples/text/resources/LICENSE.md b/examples/text/resources/LICENSE.md
new file mode 100644
index 000000000..c2a3ad0c7
--- /dev/null
+++ b/examples/text/resources/LICENSE.md
@@ -0,0 +1,20 @@
+| resource | author | licence | notes |
+| :----------------------------- | :---------: | :------ | :---- |
+| fonts/alagard.png | Hewett Tsoi | [Freeware](https://www.dafont.com/es/alagard.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| fonts/romulus.png | Hewett Tsoi | [Freeware](https://www.dafont.com/es/romulus.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| fonts/alpha_beta.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/alpha-beta.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| fonts/setback.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/setback.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| fonts/jupiter_crash.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| fonts/mecha.png | Captain Falcon | [Freeware](https://www.dafont.com/es/mecha-cf.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| fonts/pixelplay.png | Aleksander Shevchuk | [Freeware](https://www.dafont.com/es/pixelplay.fon) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| fonts/pixantiqua.ttf | Gerhard Großmann | [Freeware](https://www.dafont.com/es/pixantiqua.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| anonymous_pro_bold.ttf | [Mark Simonson](https://fonts.google.com/specimen/Anonymous+Pro) | [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL) | - |
+| custom_alagard.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| custom_jupiter_crash.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| custom_mecha.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| dejavu.fnt, dejavu.png | [DejaVu Fonts](https://dejavu-fonts.github.io/) | [Free](https://dejavu-fonts.github.io/License.html) | Atlas made with [BMFont](https://www.angelcode.com/products/bmfont/) by [@raysan5](https://github.com/raysan5) |
+| KAISG.ttf | [Dieter Steffmann](http://www.steffmann.de/wordpress/) | [Freeware](https://www.1001fonts.com/users/steffmann/) | [Kaiserzeit Gotisch](https://www.dafont.com/es/kaiserzeit-gotisch.font) font |
+| noto_cjk.fnt, noto_cjk.png | [Google Fonts](https://www.google.com/get/noto/help/cjk/) | [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL) | Atlas made with [BMFont](https://www.angelcode.com/products/bmfont/) by [@raysan5](https://github.com/raysan5) |
+| pixantiqua.fnt, pixantiqua.png | Gerhard Großmann | [Freeware](https://www.dafont.com/es/pixantiqua.font) | Atlas made with [BMFont](https://www.angelcode.com/products/bmfont/) by [@raysan5](https://github.com/raysan5) |
+| pixantiqua.ttf | Gerhard Großmann | [Freeware](https://www.dafont.com/es/pixantiqua.font) | - |
+| symbola.fnt, symbola.png | George Douros | [Freeware](https://fontlibrary.org/en/font/symbola) | Atlas made with [BMFont](https://www.angelcode.com/products/bmfont/) by [@raysan5](https://github.com/raysan5) |
diff --git a/examples/text/text_draw_3d.c b/examples/text/text_draw_3d.c
index 8ce576b6b..04b6e18ca 100644
--- a/examples/text/text_draw_3d.c
+++ b/examples/text/text_draw_3d.c
@@ -5,14 +5,14 @@
* 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
* inside the font texture.
-* A more efficient approach, i believe, would be to render the text in a render texture and
-* map that texture to a plane and render that, or maybe a shader but my method allows more
-* flexibility...for example to change position of each letter individually to make somethink
-* like a wavy text effect.
-*
-* Special thanks to:
-* @Nighten for the DrawTextStyle() code https://github.com/NightenDushi/Raylib_DrawTextStyle
-* Chris Camacho (codifies - http://bedroomcoders.co.uk/) for the alpha discard shader
+* A more efficient approach, i believe, would be to render the text in a render texture and
+* map that texture to a plane and render that, or maybe a shader but my method allows more
+* flexibility...for example to change position of each letter individually to make somethink
+* like a wavy text effect.
+*
+* Special thanks to:
+* @Nighten for the DrawTextStyle() code https://github.com/NightenDushi/Raylib_DrawTextStyle
+* Chris Camacho (codifies - http://bedroomcoders.co.uk/) for the alpha discard shader
*
* This example has been created using raylib 3.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@@ -196,7 +196,7 @@ int main(void)
(Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }});
if (collision.hit)
{
- // Generate new random colors
+ // Generate new random colors
light = GenerateRandomColor(0.5f, 0.78f);
dark = GenerateRandomColor(0.4f, 0.58f);
}
diff --git a/examples/textures/resources/LICENSE b/examples/textures/resources/LICENSE
deleted file mode 100644
index 16cdfa342..000000000
--- a/examples/textures/resources/LICENSE
+++ /dev/null
@@ -1,8 +0,0 @@
-Art used in examples is provided under a free and permissive license.
-Check individual licenses for details:
-
- - [Jupiter Crash] font by Brian Kent (AEnigma) - https://www.dafont.com/es/jupiter-crash.font
- - [Kaiserzeit Gotisch] font by Dieter Steffmann - https://www.dafont.com/es/kaiserzeit-gotisch.font
- - [Scarfy spritesheet](scarfy.png) by [Eiden Marsal](https://www.artstation.com/artist/marshall_z), licensed as [Creative Commons Attribution-NonCommercial 3.0](https://creativecommons.org/licenses/by-nc/3.0/legalcode)
- - [Fudesumi image](fudesumi.png) by [Eiden Marsal](https://www.artstation.com/artist/marshall_z), licensed as [Creative Commons Attribution-NonCommercial 3.0](https://creativecommons.org/licenses/by-nc/3.0/legalcode)
- - [Cyberpunk Street Environment](https://ansimuz.itch.io/cyberpunk-street-environment) by Luis Zuno ([@ansimuz](https://twitter.com/ansimuz)), licensed as [CC-BY-3.0](http://creativecommons.org/licenses/by/3.0/)
diff --git a/examples/textures/resources/LICENSE.md b/examples/textures/resources/LICENSE.md
new file mode 100644
index 000000000..e4ee45304
--- /dev/null
+++ b/examples/textures/resources/LICENSE.md
@@ -0,0 +1,18 @@
+| resource | author | licence | notes |
+| :------------------- | :---------: | :------ | :---- |
+| boom.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
+| buttonfx.wav | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
+| button.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [rFXGen](https://raylibtech.itch.io/rfxgen) |
+| spark_flame.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [EffectTextureMaker](https://mebiusbox.github.io/contents/EffectTextureMaker/) |
+| ninepatch_button.png | [@overdev](https://github.com/overdev) | ❔ |
+| explosion.png | [Unity Labs Paris](https://blogs.unity3d.com/2016/11/28/free-vfx-image-sequences-flipbooks/) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) |
+| parrots.png | [Kodak set](http://r0k.us/graphics/kodak/) | ❔ | Original name: `kodim23.png`
+| cat.png | ❔ | ❔ | - |
+| wabbit_alpha.png | ❔ | ❔ | - |
+| custom_jupiter_crash.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
+| KAISG.ttf | [Dieter Steffmann](http://www.steffmann.de/wordpress/) | [Freeware](https://www.1001fonts.com/users/steffmann/) | [Kaiserzeit Gotisch](https://www.dafont.com/es/kaiserzeit-gotisch.font) font |
+| fudesumi.png | [Eiden Marsal](https://www.artstation.com/marshall_z) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/) | - |
+| scarfy.png | [Eiden Marsal](https://www.artstation.com/marshall_z) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode) | - |
+| cyberpunk_street_background.png | [Luis Zuno](http://ansimuz.com/site/) | [CC-BY-3.0](http://creativecommons.org/licenses/by/3.0/) | [Cyberpunk Street Environment](https://ansimuz.itch.io/cyberpunk-street-environment) |
+| cyberpunk_street_foreground.png | [Luis Zuno](http://ansimuz.com/site/) | [CC-BY-3.0](http://creativecommons.org/licenses/by/3.0/) | [Cyberpunk Street Environment](https://ansimuz.itch.io/cyberpunk-street-environment) |
+| cyberpunk_street_midground.png | [Luis Zuno](http://ansimuz.com/site/) | [CC-BY-3.0](http://creativecommons.org/licenses/by/3.0/) | [Cyberpunk Street Environment](https://ansimuz.itch.io/cyberpunk-street-environment) |
diff --git a/parser/raylib_parser.c b/parser/raylib_parser.c
index e38dde679..4720af912 100644
--- a/parser/raylib_parser.c
+++ b/parser/raylib_parser.c
@@ -482,7 +482,7 @@ int main(int argc, char* argv[])
}
}
- //for (int i = 0; i < linesCount; i++) free(lines[i]);
+ for (int i = 0; i < linesCount; i++) free(lines[i]);
free(lines);
free(funcLines);
diff --git a/projects/VS2019/raylib/raylib.vcxproj b/projects/VS2019/raylib/raylib.vcxproj
index fe92877ca..eae70f92f 100644
--- a/projects/VS2019/raylib/raylib.vcxproj
+++ b/projects/VS2019/raylib/raylib.vcxproj
@@ -313,6 +313,7 @@
+
diff --git a/src/config.h b/src/config.h
index 8b5e4e8df..06643b8ba 100644
--- a/src/config.h
+++ b/src/config.h
@@ -224,4 +224,3 @@
// utils: Configuration values
//------------------------------------------------------------------------------------
#define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message
-#define MAX_UWP_MESSAGES 512 // Max UWP messages to process
diff --git a/src/core.c b/src/core.c
index 380d3936c..90bf1529f 100644
--- a/src/core.c
+++ b/src/core.c
@@ -355,7 +355,7 @@ typedef struct CoreData {
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
#if defined(PLATFORM_DRM)
- int fd; // File descriptor for /dev/dri/...
+ int fd; // File descriptor for /dev/dri/...
drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector
drmModeCrtc *crtc; // CRT Controller
int modeIndex; // Index of the used mode of connector->modes
@@ -417,6 +417,10 @@ typedef struct CoreData {
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
int defaultMode; // Default keyboard mode
+#if defined(SUPPORT_SSH_KEYBOARD_RPI)
+ bool evtMode; // Keyboard in event mode
+#endif
+ int defaultFileFlags; // Default IO file flags
struct termios defaultSettings; // Default keyboard settings
int fd; // File descriptor for the evdev keyboard
#endif
@@ -734,7 +738,7 @@ void InitWindow(int width, int height, const char *title)
// Initialize App command system
// NOTE: On APP_CMD_INIT_WINDOW -> InitGraphicsDevice(), InitTimer(), LoadFontDefault()...
CORE.Android.app->onAppCmd = AndroidCommandCallback;
-
+
// Initialize input events system
CORE.Android.app->onInputEvent = AndroidInputCallback;
@@ -4545,7 +4549,7 @@ void PollInputEvents(void)
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
// Register previous keys states
- for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
+ for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
PollKeyboardEvents();
@@ -4573,7 +4577,7 @@ void PollInputEvents(void)
// Keyboard/Mouse input polling (automatically managed by GLFW3 through callback)
// Register previous keys states
- for (int i = 0; i < 512; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
+ for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i];
// Register previous mouse states
for (int i = 0; i < 3; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
@@ -4773,9 +4777,10 @@ void PollInputEvents(void)
#endif
#if (defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) && defined(SUPPORT_SSH_KEYBOARD_RPI)
- // NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here.
+ // NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here.
// stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console
- ProcessKeyboard();
+
+ if (!CORE.Input.Keyboard.evtMode) ProcessKeyboard();
// NOTE: Mouse input events polling is done asynchronously in another pthread - EventThread()
// NOTE: Gamepad (Joystick) input events polling is done asynchonously in another pthread - GamepadThread()
@@ -4817,7 +4822,7 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *
CORE.Window.screen.height = height;
// NOTE: Postprocessing texture is not scaled to new size
-
+
return 0;
}
#endif
@@ -5259,6 +5264,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0);
CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0);
+ unsigned int touchCount = AMotionEvent_getPointerCount(event);
+ for (int i = 1; i < touchCount && i < MAX_TOUCH_POINTS; i++)
+ {
+ CORE.Input.Touch.position[i].x = AMotionEvent_getX(event, i);
+ CORE.Input.Touch.position[i].y = AMotionEvent_getY(event, i);
+ }
+
int32_t action = AMotionEvent_getAction(event);
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
@@ -5409,7 +5421,7 @@ static void InitKeyboard(void)
// Save terminal keyboard settings
tcgetattr(STDIN_FILENO, &CORE.Input.Keyboard.defaultSettings);
-
+
// Reconfigure terminal with new settings
struct termios keyboardNewSettings = { 0 };
keyboardNewSettings = CORE.Input.Keyboard.defaultSettings;
@@ -5425,9 +5437,12 @@ static void InitKeyboard(void)
tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings);
// Save old keyboard mode to restore it at the end
+ CORE.Input.Keyboard.defaultFileFlags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags
+ fcntl(STDIN_FILENO, F_SETFL, CORE.Input.Keyboard.defaultFileFlags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified
+
// NOTE: If ioctl() returns -1, it means the call failed for some reason (error code set in errno)
int result = ioctl(STDIN_FILENO, KDGKBMODE, &CORE.Input.Keyboard.defaultMode);
-
+
// In case of failure, it could mean a remote keyboard is used (SSH)
if (result < 0) TRACELOG(LOG_WARNING, "RPI: Failed to change keyboard mode, an SSH keyboard is probably used");
else
@@ -5451,6 +5466,7 @@ static void RestoreKeyboard(void)
tcsetattr(STDIN_FILENO, TCSANOW, &CORE.Input.Keyboard.defaultSettings);
// Reconfigure keyboard to default mode
+ fcntl(STDIN_FILENO, F_SETFL, CORE.Input.Keyboard.defaultFileFlags);
ioctl(STDIN_FILENO, KDSKBMODE, CORE.Input.Keyboard.defaultMode);
}
@@ -5469,10 +5485,7 @@ static void ProcessKeyboard(void)
bufferByteCount = read(STDIN_FILENO, keysBuffer, MAX_KEYBUFFER_SIZE); // POSIX system call
// Reset pressed keys array (it will be filled below)
- if (bufferByteCount > 0) for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
-
- // Check keys from event input workers (This is the new keyboard reading method)
- //for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.currentKeyState[i] = CORE.Input.Keyboard.currentKeyStateEvdev[i];
+ for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
// Fill all read bytes (looking for keys)
for (int i = 0; i < bufferByteCount; i++)
@@ -5588,7 +5601,7 @@ static void InitEvdevInput(void)
}
// Reset keyboard key state
- for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
+ for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.currentKeyState[i] = 0;
// Open the linux directory of "/dev/input"
directory = opendir(DEFAULT_EVDEV_PATH);
@@ -5817,20 +5830,20 @@ static void PollKeyboardEvents(void)
// TODO: Probably replace this with a keymap from the X11 to get the correct regional map for the keyboard:
// Currently non US keyboards will have the wrong mapping for some keys
static const int keymapUS[] = {
- 0, 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 258, 81, 87, 69, 82, 84,
- 89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59, 39, 96,
- 340, 92, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 344, 332, 342, 32, 280, 290, 291,
- 292, 293, 294, 295, 296, 297, 298, 299, 282, 281, 327, 328, 329, 333, 324, 325,
- 326, 334, 321, 322, 323, 320, 330, 0, 85, 86, 300, 301, 89, 90, 91, 92, 93, 94, 95,
- 335, 345, 331, 283, 346, 101, 268, 265, 266, 263, 262, 269, 264, 267, 260, 261,
- 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 347, 127,
- 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
- 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
- 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
- 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
- 192, 193, 194, 0, 0, 0, 0, 0, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
- 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
- 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+ 0, 256, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 259, 258, 81, 87, 69, 82, 84,
+ 89, 85, 73, 79, 80, 91, 93, 257, 341, 65, 83, 68, 70, 71, 72, 74, 75, 76, 59, 39, 96,
+ 340, 92, 90, 88, 67, 86, 66, 78, 77, 44, 46, 47, 344, 332, 342, 32, 280, 290, 291,
+ 292, 293, 294, 295, 296, 297, 298, 299, 282, 281, 327, 328, 329, 333, 324, 325,
+ 326, 334, 321, 322, 323, 320, 330, 0, 85, 86, 300, 301, 89, 90, 91, 92, 93, 94, 95,
+ 335, 345, 331, 283, 346, 101, 268, 265, 266, 263, 262, 269, 264, 267, 260, 261,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 347, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 0, 0, 0, 0, 0, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210,
+ 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
+ 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
243, 244, 245, 246, 247, 248, 0, 0, 0, 0, 0, 0, 0
};
@@ -5846,6 +5859,10 @@ static void PollKeyboardEvents(void)
// Button parsing
if (event.type == EV_KEY)
{
+#if defined(SUPPORT_SSH_KEYBOARD_RPI)
+ // Change keyboard mode to events
+ CORE.Input.Keyboard.evtMode = true;
+#endif
// Keyboard button parsing
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
{
@@ -6346,7 +6363,7 @@ static void ExportAutomationEvents(const char *fileName)
// Check event in current frame and save into the events[i] array
static void RecordAutomationEvent(unsigned int frame)
{
- for (int key = 0; key < 512; key++)
+ for (int key = 0; key < MAX_KEYBOARD_KEYS; key++)
{
// INPUT_KEY_UP (only saved once)
if (CORE.Input.Keyboard.previousKeyState[key] && !CORE.Input.Keyboard.currentKeyState[key])
diff --git a/examples/shapes/raygui.h b/src/extras/raygui.h
similarity index 99%
rename from examples/shapes/raygui.h
rename to src/extras/raygui.h
index 4629e04fe..fdc8feeb1 100644
--- a/examples/shapes/raygui.h
+++ b/src/extras/raygui.h
@@ -516,8 +516,8 @@ RAYGUIDEF bool GuiCheckIconPixel(int iconId, int x, int y); // Check icon pi
#endif
#include // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf()
-#include // Required for: strlen() on GuiTextBox()
-#include // Required for: roundf() on GuiColorPicker()
+#include // Required for: strlen() [GuiTextBox()]
+#include // Required for: roundf() [GuiColorPicker()]
#if defined(RAYGUI_STANDALONE)
#include // Required for: va_list, va_start(), vfprintf(), va_end()
@@ -1373,7 +1373,7 @@ bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMo
// NOTE 2: Returns if KEY_ENTER pressed (useful for data validation)
bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
{
- static int framesCounter = 0; // Required for blinking cursor
+ static int framesCounter = 0; // Blinking cursor counter
GuiControlState state = guiState;
bool pressed = false;
@@ -1561,7 +1561,7 @@ bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, i
#define VALUEBOX_MAX_CHARS 32
#endif
- static int framesCounter = 0; // Required for blinking cursor
+ static int framesCounter = 0; // Blinking cursor counter
GuiControlState state = guiState;
bool pressed = false;
@@ -1678,7 +1678,7 @@ bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, i
// Text Box control with multiple lines
bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
{
- static int framesCounter = 0; // Required for blinking cursor
+ static int framesCounter = 0; // Blinking cursor counter
GuiControlState state = guiState;
bool pressed = false;
@@ -3083,9 +3083,10 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName)
for (int i = 0; i < iconsCount; i++)
{
guiIconsName[i] = (char *)RAYGUI_MALLOC(RICON_MAX_NAME_LENGTH);
- fread(guiIconsName[i], 32, 1, rgiFile);
+ fread(guiIconsName[i], RICON_MAX_NAME_LENGTH, 1, rgiFile);
}
}
+ else fseek(rgiFile, iconsCount*RICON_MAX_NAME_LENGTH, SEEK_CUR);
// Read icons data directly over guiIcons data array
fread(guiIcons, iconsCount*(iconsSize*iconsSize/32), sizeof(unsigned int), rgiFile);
diff --git a/examples/shapes/ricons.h b/src/extras/ricons.h
similarity index 99%
rename from examples/shapes/ricons.h
rename to src/extras/ricons.h
index 6befa36ba..121cf5432 100644
--- a/examples/shapes/ricons.h
+++ b/src/extras/ricons.h
@@ -22,7 +22,7 @@
// Icons data is defined by bit array (every bit represents one pixel)
// Those arrays are stored as unsigned int data arrays, so every array
// element defines 32 pixels (bits) of information
-// Number of elemens depend on RICON_SIZE (by default 16x16 pixels)
+// Number of elemens depend on RICON_SIZE (by default 16x16 pixels)
#define RICON_DATA_ELEMENTS (RICON_SIZE*RICON_SIZE/32)
//----------------------------------------------------------------------------------
diff --git a/src/models.c b/src/models.c
index 532dd1788..3d200d2ae 100644
--- a/src/models.c
+++ b/src/models.c
@@ -819,6 +819,35 @@ void UnloadModelKeepMeshes(Model model)
TRACELOG(LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM");
}
+// Compute model bounding box limits (considers all meshes)
+BoundingBox GetModelBoundingBox(Model model)
+{
+ BoundingBox bounds = { 0 };
+
+ if (model.meshCount > 0)
+ {
+ Vector3 temp = { 0 };
+ bounds = GetMeshBoundingBox(model.meshes[0]);
+
+ for (int i = 1; i < model.meshCount; i++)
+ {
+ BoundingBox tempBounds = GetMeshBoundingBox(model.meshes[i]);
+
+ temp.x = (bounds.min.x < tempBounds.min.x)? bounds.min.x : tempBounds.min.x;
+ temp.y = (bounds.min.y < tempBounds.min.y)? bounds.min.y : tempBounds.min.y;
+ temp.z = (bounds.min.z < tempBounds.min.z)? bounds.min.z : tempBounds.min.z;
+ bounds.min = temp;
+
+ temp.x = (bounds.max.x > tempBounds.max.x)? bounds.max.x : tempBounds.max.x;
+ temp.y = (bounds.max.y > tempBounds.max.y)? bounds.max.y : tempBounds.max.y;
+ temp.z = (bounds.max.z > tempBounds.max.z)? bounds.max.z : tempBounds.max.z;
+ bounds.max = temp;
+ }
+ }
+
+ return bounds;
+}
+
// Upload vertex data into a VAO (if supported) and VBO
void UploadMesh(Mesh *mesh, bool dynamic)
{
@@ -860,7 +889,7 @@ void UploadMesh(Mesh *mesh, bool dynamic)
if (mesh->normals != NULL)
{
// Enable vertex attributes: normals (shader-location = 2)
- void *normals = mesh->animNormals != NULL ? mesh->animNormals : mesh->vertices;
+ void *normals = mesh->animNormals != NULL ? mesh->animNormals : mesh->normals;
mesh->vboId[2] = rlLoadVertexBuffer(normals, mesh->vertexCount*3*sizeof(float), dynamic);
rlSetVertexAttribute(2, 3, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(2);
@@ -1021,8 +1050,9 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
// NOTE: At this point the modelview matrix just contains the view matrix (camera)
// That's because BeginMode3D() sets it and there is no model-drawing function
// that modifies it, all use rlPushMatrix() and rlPopMatrix()
+ Matrix matModel = MatrixIdentity();
Matrix matView = rlGetMatrixModelview();
- Matrix matModelView = matView;
+ Matrix matModelView = MatrixIdentity();
Matrix matProjection = rlGetMatrixProjection();
// Upload view and projection matrices (if locations available)
@@ -1066,15 +1096,17 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
// Model transformation matrix is send to shader uniform location: SHADER_LOC_MATRIX_MODEL
if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], transforms[0]);
- // Accumulate several transformations:
- // matView: rlgl internal modelview matrix (actually, just view matrix)
+ // Accumulate several model transformations:
+ // transforms[0]: model transformation provided (includes DrawModel() params combined with model.transform)
// rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack
- // transform: function parameter transformation
- matModelView = MatrixMultiply(transforms[0], MatrixMultiply(rlGetMatrixTransform(), matView));
+ matModel = MatrixMultiply(transforms[0], rlGetMatrixTransform());
+
+ // Get model-view matrix
+ matModelView = MatrixMultiply(matModel, matView);
}
// Upload model normal matrix (if locations available)
- if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModelView)));
+ if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
//-----------------------------------------------------
// Bind active texture maps (if available)
@@ -1161,17 +1193,17 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
for (int eye = 0; eye < eyesCount; eye++)
{
// Calculate model-view-projection matrix (MVP)
- Matrix matMVP = MatrixIdentity();
- if (eyesCount == 1) matMVP = MatrixMultiply(matModelView, matProjection);
+ Matrix matModelViewProjection = MatrixIdentity();
+ if (eyesCount == 1) matModelViewProjection = MatrixMultiply(matModelView, matProjection);
else
{
// Setup current eye viewport (half screen width)
rlViewport(eye*rlGetFramebufferWidth()/2, 0, rlGetFramebufferWidth()/2, rlGetFramebufferHeight());
- matMVP = MatrixMultiply(MatrixMultiply(matModelView, rlGetMatrixViewOffsetStereo(eye)), rlGetMatrixProjectionStereo(eye));
+ matModelViewProjection = MatrixMultiply(MatrixMultiply(matModelView, rlGetMatrixViewOffsetStereo(eye)), rlGetMatrixProjectionStereo(eye));
}
// Send combined model-view-projection matrix to shader
- rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matMVP);
+ rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matModelViewProjection);
if (instancing) // Draw mesh instanced
{
@@ -2650,7 +2682,11 @@ BoundingBox GetMeshBoundingBox(Mesh mesh)
void GenMeshTangents(Mesh *mesh)
{
if (mesh->tangents == NULL) mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
- else TRACELOG(LOG_WARNING, "MESH: Tangents data already available, re-writting");
+ else
+ {
+ RL_FREE(mesh->tangents);
+ mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
+ }
Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
@@ -2695,35 +2731,51 @@ void GenMeshTangents(Mesh *mesh)
}
// Compute tangents considering normals
- for (int i = 0; i < mesh->vertexCount; ++i)
+ for (int i = 0; i < mesh->vertexCount; i++)
{
Vector3 normal = { mesh->normals[i*3 + 0], mesh->normals[i*3 + 1], mesh->normals[i*3 + 2] };
Vector3 tangent = tan1[i];
// TODO: Review, not sure if tangent computation is right, just used reference proposed maths...
- #if defined(COMPUTE_TANGENTS_METHOD_01)
+#if defined(COMPUTE_TANGENTS_METHOD_01)
Vector3 tmp = Vector3Subtract(tangent, Vector3Scale(normal, Vector3DotProduct(normal, tangent)));
tmp = Vector3Normalize(tmp);
mesh->tangents[i*4 + 0] = tmp.x;
mesh->tangents[i*4 + 1] = tmp.y;
mesh->tangents[i*4 + 2] = tmp.z;
mesh->tangents[i*4 + 3] = 1.0f;
- #else
+#else
Vector3OrthoNormalize(&normal, &tangent);
mesh->tangents[i*4 + 0] = tangent.x;
mesh->tangents[i*4 + 1] = tangent.y;
mesh->tangents[i*4 + 2] = tangent.z;
mesh->tangents[i*4 + 3] = (Vector3DotProduct(Vector3CrossProduct(normal, tangent), tan2[i]) < 0.0f)? -1.0f : 1.0f;
- #endif
+#endif
}
RL_FREE(tan1);
RL_FREE(tan2);
- // Load a new tangent attributes buffer
- mesh->vboId[SHADER_LOC_VERTEX_TANGENT] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
-
- TRACELOG(LOG_INFO, "MESH: Tangents data computed for provided mesh");
+ if (mesh->vboId != NULL)
+ {
+ if (mesh->vboId[SHADER_LOC_VERTEX_TANGENT] != 0)
+ {
+ // Upate existing vertex buffer
+ rlUpdateVertexBuffer(mesh->vboId[SHADER_LOC_VERTEX_TANGENT], mesh->tangents, mesh->vertexCount*4*sizeof(float), 0);
+ }
+ else
+ {
+ // Load a new tangent attributes buffer
+ mesh->vboId[SHADER_LOC_VERTEX_TANGENT] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
+ }
+
+ rlEnableVertexArray(mesh->vaoId);
+ rlSetVertexAttribute(4, 4, RL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(4);
+ rlDisableVertexArray();
+ }
+
+ TRACELOG(LOG_INFO, "MESH: Tangents data computed and uploaded for provided mesh");
}
// Compute mesh binormals (aka bitangent)
@@ -4374,12 +4426,12 @@ static void *ReadGLTFValuesAs(cgltf_accessor* acc, cgltf_component_type type, bo
} break;
case cgltf_component_type_r_32f:
{
- float* typedArray = (float*) array;
+ float *typedArray = (float *)array;
for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (float)typedAdditionalArray[i];
} break;
case cgltf_component_type_r_32u:
{
- unsigned int* typedArray = (unsigned int*) array;
+ unsigned int *typedArray = (unsigned int *)array;
for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned int)typedAdditionalArray[i];
} break;
default:
diff --git a/src/raudio.c b/src/raudio.c
index 8f6d32e0a..e35215bfa 100644
--- a/src/raudio.c
+++ b/src/raudio.c
@@ -1724,9 +1724,9 @@ void UpdateMusicStream(Music music)
case MUSIC_MODULE_XM:
{
// NOTE: Internally we consider 2 channels generation, so samplesCount/2
- if (AUDIO_DEVICE_FORMAT == ma_format_f32) jar_xm_generate_samples((jar_xm_context_t*)music.ctxData, (float *)pcm, samplesCount/2);
- else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit((jar_xm_context_t*)music.ctxData, (short *)pcm, samplesCount/2);
- else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit((jar_xm_context_t*)music.ctxData, (char *)pcm, samplesCount/2);
+ if (AUDIO_DEVICE_FORMAT == ma_format_f32) jar_xm_generate_samples((jar_xm_context_t *)music.ctxData, (float *)pcm, samplesCount/2);
+ else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit((jar_xm_context_t *)music.ctxData, (short *)pcm, samplesCount/2);
+ else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit((jar_xm_context_t *)music.ctxData, (char *)pcm, samplesCount/2);
} break;
#endif
diff --git a/src/raylib.h b/src/raylib.h
index 3b4688875..8f8cfa571 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -1382,19 +1382,45 @@ RLAPI void DrawGrid(int slices, float spacing);
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
-// Model loading/unloading functions
+// Model management functions
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
RLAPI void UnloadModelKeepMeshes(Model model); // Unload model (but not meshes) from memory (RAM and/or VRAM)
+RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
-// Mesh loading/unloading functions
+// Model drawing functions
+RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
+RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
+RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
+RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
+RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
+RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture
+RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
+RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation
+
+// Mesh management functions
RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids
RLAPI void UpdateMeshBuffer(Mesh mesh, int index, void *data, int dataSize, int offset); // Update mesh vertex data in GPU for a specific buffer index
+RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU
RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
RLAPI void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms
-RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU
RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
+RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
+RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents
+RLAPI void GenMeshBinormals(Mesh *mesh); // Compute mesh binormals
+
+// Mesh generation functions
+RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
+RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
+RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
+RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere)
+RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap)
+RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh
+RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh
+RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh
+RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
+RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
// Material loading/unloading functions
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
@@ -1410,33 +1436,6 @@ RLAPI void UnloadModelAnimation(ModelAnimation anim);
RLAPI void UnloadModelAnimations(ModelAnimation* animations, unsigned int count); // Unload animation array data
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
-// Mesh generation functions
-RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
-RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
-RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
-RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere)
-RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap)
-RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh
-RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh
-RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh
-RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
-RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
-
-// Mesh manipulation functions
-RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
-RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents
-RLAPI void GenMeshBinormals(Mesh *mesh); // Compute mesh binormals
-
-// Model drawing functions
-RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
-RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
-RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
-RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
-RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
-RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture
-RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
-RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation
-
// Collision detection functions
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes
diff --git a/src/raymath.h b/src/raymath.h
index ea888cf01..cc2cda822 100644
--- a/src/raymath.h
+++ b/src/raymath.h
@@ -282,7 +282,11 @@ RMDEF Vector2 Vector2Divide(Vector2 v1, Vector2 v2)
// Normalize provided vector
RMDEF Vector2 Vector2Normalize(Vector2 v)
{
- Vector2 result = Vector2Scale(v, 1/Vector2Length(v));
+ float length = Vector2Length(v);
+ if (length <= 0)
+ return v;
+
+ Vector2 result = Vector2Scale(v, 1/length);
return result;
}
@@ -1422,20 +1426,21 @@ RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
if (Vector3Length(axis) != 0.0f)
+ {
+ angle *= 0.5f;
- angle *= 0.5f;
+ axis = Vector3Normalize(axis);
- axis = Vector3Normalize(axis);
+ float sinres = sinf(angle);
+ float cosres = cosf(angle);
- float sinres = sinf(angle);
- float cosres = cosf(angle);
+ result.x = axis.x*sinres;
+ result.y = axis.y*sinres;
+ result.z = axis.z*sinres;
+ result.w = cosres;
- result.x = axis.x*sinres;
- result.y = axis.y*sinres;
- result.z = axis.z*sinres;
- result.w = cosres;
-
- result = QuaternionNormalize(result);
+ result = QuaternionNormalize(result);
+ }
return result;
}
diff --git a/src/rlgl.h b/src/rlgl.h
index a2d890e60..93227c2be 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -3121,7 +3121,7 @@ void rlDrawVertexArray(int offset, int count)
void rlDrawVertexArrayElements(int offset, int count, void *buffer)
{
- glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (unsigned short*)buffer + offset);
+ glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (unsigned short *)buffer + offset);
}
void rlDrawVertexArrayInstanced(int offset, int count, int instances)
@@ -3134,7 +3134,7 @@ void rlDrawVertexArrayInstanced(int offset, int count, int instances)
void rlDrawVertexArrayElementsInstanced(int offset, int count, void *buffer, int instances)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (unsigned short*)buffer + offset, instances);
+ glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (unsigned short *)buffer + offset, instances);
#endif
}
@@ -3760,7 +3760,7 @@ const char *rlGetPixelFormatName(unsigned int format)
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: return "PVRT_RGBA"; break; // 4 bpp
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: return "ASTC_4x4_RGBA"; break; // 8 bpp
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: return "ASTC_8x8_RGBA"; break; // 2 bpp
- default: return "\0"; break;
+ default: return "UNKNOWN"; break;
}
}
diff --git a/src/textures.c b/src/textures.c
index 9bef90c4c..94da3c8ca 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -331,12 +331,15 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
int comp = 0;
image.data = stbi_load_from_memory(fileData, dataSize, &image.width, &image.height, &comp, 0);
- image.mipmaps = 1;
+ if (image.data != NULL)
+ {
+ image.mipmaps = 1;
- if (comp == 1) image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
- else if (comp == 2) image.format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA;
- else if (comp == 3) image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
- else if (comp == 4) image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
+ if (comp == 1) image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
+ else if (comp == 2) image.format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA;
+ else if (comp == 3) image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
+ else if (comp == 4) image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
+ }
}
#endif
}
@@ -380,8 +383,9 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
#endif
else TRACELOG(LOG_WARNING, "IMAGE: Data format not supported");
- TRACELOG(LOG_INFO, "IMAGE: Data loaded successfully (%ix%i | %s | %i mipmaps)", image.width, image.height, rlGetPixelFormatName(image.format), image.mipmaps);
-
+ if (image.data != NULL) TRACELOG(LOG_INFO, "IMAGE: Data loaded successfully (%ix%i | %s | %i mipmaps)", image.width, image.height, rlGetPixelFormatName(image.format), image.mipmaps);
+ else TRACELOG(LOG_WARNING, "IMAGE: Failed to load image data");
+
return image;
}
@@ -2418,19 +2422,91 @@ void ImageDrawPixelV(Image *dst, Vector2 position, Color color)
// Draw line within an image
void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color)
{
- int m = 2*(endPosY - startPosY);
- int slopeError = m - (endPosX - startPosX);
-
- for (int x = startPosX, y = startPosY; x <= endPosX; x++)
+ // Using Bresenham's algorithm as described in
+ // Drawing Lines with Pixels - Joshua Scott - March 2012
+ // https://classic.csunplugged.org/wp-content/uploads/2014/12/Lines.pdf
+
+ int changeInX = (endPosX - startPosX);
+ int absChangeInX = (changeInX < 0)? -changeInX : changeInX;
+ int changeInY = (endPosY - startPosY);
+ int absChangeInY = (changeInY < 0)? -changeInY : changeInY;
+
+ int startU, startV, endU, stepV; // Substitutions, either U = X, V = Y or vice versa. See loop at end of function
+ //int endV; // Not needed but left for better understanding, check code below
+ int A, B, P; // See linked paper above, explained down in the main loop
+ int reversedXY = (absChangeInY < absChangeInX);
+
+ if (reversedXY)
{
- ImageDrawPixel(dst, x, y, color);
- slopeError += m;
+ A = 2*absChangeInY;
+ B = A - 2*absChangeInX;
+ P = A - absChangeInX;
- if (slopeError >= 0)
- {
- y++;
- slopeError -= 2*(endPosX - startPosX);
+ if (changeInX > 0)
+ {
+ startU = startPosX;
+ startV = startPosY;
+ endU = endPosX;
+ //endV = endPosY;
}
+ else
+ {
+ startU = endPosX;
+ startV = endPosY;
+ endU = startPosX;
+ //endV = startPosY;
+
+ // Since start and end are reversed
+ changeInX = -changeInX;
+ changeInY = -changeInY;
+ }
+
+ stepV = (changeInY < 0)? -1 : 1;
+
+ ImageDrawPixel(dst, startU, startV, color); // At this point they are correctly ordered...
+ }
+ else
+ {
+ A = 2*absChangeInX;
+ B = A - 2*absChangeInY;
+ P = A - absChangeInY;
+
+ if (changeInY > 0)
+ {
+ startU = startPosY;
+ startV = startPosX;
+ endU = endPosY;
+ //endV = endPosX;
+ }
+ else
+ {
+ startU = endPosY;
+ startV = endPosX;
+ endU = startPosY;
+ //endV = startPosX;
+
+ // Since start and end are reversed
+ changeInX = -changeInX;
+ changeInY = -changeInY;
+ }
+
+ stepV = (changeInX < 0)? -1 : 1;
+
+ ImageDrawPixel(dst, startV, startU, color); // ... but need to be reversed here. Repeated in the main loop below
+ }
+
+ // We already drew the start point. If we started at startU + 0, the line would be crooked and too short
+ for (int u = startU + 1, v = startV; u <= endU; u++)
+ {
+ if (P >= 0)
+ {
+ v += stepV; // Adjusts whenever we stray too far from the direct line. Details in the linked paper above
+ P += B; // Remembers that we corrected our path
+ }
+ else P += A; // Remembers how far we are from the direct line
+
+ if (reversedXY) ImageDrawPixel(dst, u, v, color);
+ else ImageDrawPixel(dst, v, u, color);
}
}
diff --git a/src/utils.c b/src/utils.c
index 2e3e4fd31..dbf4b3bbb 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -56,9 +56,6 @@
#ifndef MAX_TRACELOG_MSG_LENGTH
#define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message
#endif
-#ifndef MAX_UWP_MESSAGES
- #define MAX_UWP_MESSAGES 512 // Max UWP messages to process
-#endif
//----------------------------------------------------------------------------------
// Global Variables Definition