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