Compare commits
235 Commits
43d8933404
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| dfbaafa337 | |||
| 019cc889fc | |||
| 034ffda887 | |||
| 970531d112 | |||
| 99eaf72362 | |||
| 1339ec637e | |||
| 44e5126d08 | |||
| 51d693607e | |||
| a5427bc38f | |||
| 605303f62b | |||
| b3592631b0 | |||
| ddfbe973d4 | |||
| fe5271c568 | |||
| de95b3aa70 | |||
| fbcc8cdb55 | |||
| ca6f188233 | |||
| 8e54b19d9f | |||
| e24b01bb28 | |||
| 68d519910a | |||
| 53915d77e6 | |||
| b202421e08 | |||
| 05a14456ae | |||
| c5fc771622 | |||
| d3c6f426b4 | |||
| c4bd4faab5 | |||
| 4a6ceb9c76 | |||
| 6ef0044381 | |||
| 1122add3ee | |||
| 92f82b4add | |||
| cdff3d7bea | |||
| 138ef838d9 | |||
| 6ff51d3a2a | |||
| ea6292e27a | |||
| bb7b8d70e9 | |||
| f36533cbd8 | |||
| 5c2dee0862 | |||
| 12140cd444 | |||
| 3f7f040c7e | |||
| 4799cab772 | |||
| eb4f1a6da0 | |||
| 449182bb51 | |||
| 4ca9170f5b | |||
| 78797757f0 | |||
| a6dc9f9e92 | |||
| c7df641aa2 | |||
| 63beefd0de | |||
| b3bf537fab | |||
| 8743e11285 | |||
| 04f81538b7 | |||
| 8d70f1007b | |||
| 6c0134bb5c | |||
| e9231bc4f1 | |||
| 4c79c6837b | |||
| e5f0c9f8b1 | |||
| d5326fe880 | |||
| adc4c9b875 | |||
| b09da8fce8 | |||
| 0b87a35e5a | |||
| a1bf8d9c75 | |||
| d3cc78d9d7 | |||
| e3dcb144bc | |||
| da93ec4a21 | |||
| fb0f83bc91 | |||
| 29ded51ea4 | |||
| bb78e98a71 | |||
| 5915584cd6 | |||
| 8c44ea5032 | |||
| 5fad835ff1 | |||
| 4142c89baa | |||
| 990a5e0cb4 | |||
| 8a7aff509d | |||
| ba83bd33f3 | |||
| 98d6e24c44 | |||
| 51f4741912 | |||
| d7bd56ef1b | |||
| a693365bf2 | |||
| bd3a35ca21 | |||
| 0f0983c065 | |||
| 5dd4036ed0 | |||
| cb05ef7f03 | |||
| 52d2158f49 | |||
| 0f1e14a600 | |||
| 6cf71f565c | |||
| e71633a0be | |||
| ca1baca7c2 | |||
| 7e8aca00b6 | |||
| c1dbfc87f3 | |||
| 644e4adbe2 | |||
| 1e74aba7c3 | |||
| 83e35ba170 | |||
| 22cc2554b1 | |||
| 1b084ff9f2 | |||
| 8a685877eb | |||
| 8783e66e21 | |||
| 7ae46fb2e6 | |||
| 04c5dc4493 | |||
| bca4f83a02 | |||
| 7fef65a3fe | |||
| da9e881092 | |||
| 2a3b28b67a | |||
| 2fd058c1e4 | |||
| 528caf8b9d | |||
| 85df4e7de5 | |||
| f23319db3c | |||
| 29e4b77580 | |||
| 2c39703d13 | |||
| d657e86043 | |||
| 0de2e8092b | |||
| 48a34d63ed | |||
| fbce5e7541 | |||
| 18756bb79d | |||
| 6ddf9a1885 | |||
| e7d999e3c7 | |||
| 93be463322 | |||
| 5cd7202777 | |||
| 22e1e86c52 | |||
| 1eea511070 | |||
| e0d3037e15 | |||
| 483d687900 | |||
| 7401214e92 | |||
| d2be4ac2c9 | |||
| 19ec2588be | |||
| e2aed43410 | |||
| 4a16dc9b09 | |||
| ceeaf57a8b | |||
| dfc3f58a06 | |||
| 26f329a5e7 | |||
| 1d9e24eb58 | |||
| 29280971be | |||
| fd017c0b2d | |||
| fbec6b0593 | |||
| 8395374e3d | |||
| 116191fd80 | |||
| a6d5a7ffbc | |||
| f89d38b086 | |||
| 38ed50c07b | |||
| 4b9d802d4e | |||
| 70cb8d15e0 | |||
| 7763da41d7 | |||
| 6ba6df3af3 | |||
| 7b9a2a4145 | |||
| f83590aa37 | |||
| c5712db1e0 | |||
| f9ea607385 | |||
| 8a93587eaa | |||
| 64e8bfcfb6 | |||
| 4e360c97f4 | |||
| ee4f4a29c2 | |||
| 6cebf63cba | |||
| 7b1096dc53 | |||
| e40ddfabbb | |||
| 2b207be11e | |||
| d604cd7f65 | |||
| 78023ffca5 | |||
| 32005b9edf | |||
| 99cab6d3a7 | |||
| 1839b3edb0 | |||
| eed30b6f90 | |||
| a0ffefcb9d | |||
| 12039ba7d0 | |||
| c8d1f3e750 | |||
| 54f630774d | |||
| 3e926d65a0 | |||
| f9ee714c76 | |||
| ea00b97c59 | |||
| 02b592cd7b | |||
| 84dc56ba89 | |||
| d6926eb46a | |||
| eb1e85e400 | |||
| 2eaac95df0 | |||
| de720a8d4c | |||
| 28288fafb1 | |||
| 71677765c5 | |||
| e1959a4e5c | |||
| faf42366ec | |||
| 23c06bc6f1 | |||
| 5ada84cc6d | |||
| d0f899721b | |||
| 23f86689dc | |||
| 1cf278b8b4 | |||
| 1d85071372 | |||
| b4746469d4 | |||
| 70a1a57a12 | |||
| 37a852a7ae | |||
| b68dbaa8af | |||
| 9ae34d2c4b | |||
| 8e705b19e4 | |||
| bf830c3f7b | |||
| 23c8ee855d | |||
| 416da9aca6 | |||
| 936e8ae0db | |||
| ea92677902 | |||
| 3bea7f518d | |||
| e1113c8833 | |||
| 2c5e7f8db6 | |||
| 8596c940ae | |||
| 0b9239eca2 | |||
| 70a58a6ec6 | |||
| 950c064448 | |||
| f583674327 | |||
| 28e40d502a | |||
| 178aca0fd0 | |||
| f3958cae5d | |||
| 2b3218c3db | |||
| 05a34b09ea | |||
| d8861cc35f | |||
| c686e087b3 | |||
| 92a1b80465 | |||
| d869db1572 | |||
| f23a900e91 | |||
| 72b206624f | |||
| 7a3cecc010 | |||
| 5361265a7d | |||
| 304e489edd | |||
| b57526d71e | |||
| 006216bfcb | |||
| ecaa1d3d18 | |||
| ad82393bb8 | |||
| 4ebe7d6215 | |||
| 29b5844119 | |||
| aec6e85ec3 | |||
| 25e521553d | |||
| d504e400ea | |||
| 406861a4a1 | |||
| ace4d77bfa | |||
| 7f0cedba63 | |||
| 592cac56f8 | |||
| ade81248c3 | |||
| 149062f715 | |||
| d4dc038e2e | |||
| bee3dc6673 | |||
| 770677da1f | |||
| 3f36c2d3f5 | |||
| 73cb1d5b64 | |||
| e4cbf6b79c |
2
.github/workflows/build_webassembly.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
|||||||
- name: Setup emsdk
|
- name: Setup emsdk
|
||||||
uses: mymindstorm/setup-emsdk@v14
|
uses: mymindstorm/setup-emsdk@v14
|
||||||
with:
|
with:
|
||||||
version: 3.1.71
|
version: 5.0.3
|
||||||
actions-cache-folder: 'emsdk-cache'
|
actions-cache-folder: 'emsdk-cache'
|
||||||
|
|
||||||
- name: Setup Release Version
|
- name: Setup Release Version
|
||||||
|
|||||||
6
.gitignore
vendored
@ -118,6 +118,7 @@ GTAGS
|
|||||||
# Zig programming language
|
# Zig programming language
|
||||||
.zig-cache/
|
.zig-cache/
|
||||||
zig-cache/
|
zig-cache/
|
||||||
|
zig-pkg/
|
||||||
zig-out/
|
zig-out/
|
||||||
build/
|
build/
|
||||||
build-*/
|
build-*/
|
||||||
@ -132,3 +133,8 @@ tools/rexm/rexm
|
|||||||
# CI
|
# CI
|
||||||
emsdk-cache/
|
emsdk-cache/
|
||||||
raylib.com/
|
raylib.com/
|
||||||
|
|
||||||
|
# Wayland files
|
||||||
|
src/*protocol.h
|
||||||
|
src/*protocol-code.h
|
||||||
|
src/*protocol-code.c
|
||||||
|
|||||||
@ -6,7 +6,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||||||
|
|
||||||
| Name | raylib Version | Language | License |
|
| Name | raylib Version | Language | License |
|
||||||
| :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: |
|
| :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: |
|
||||||
| [raylib](https://github.com/raysan5/raylib) | **5.5** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
| [raylib](https://github.com/raysan5/raylib) | **6.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
||||||
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **5.5** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
|
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **5.5** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
|
||||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
|
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
|
||||||
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||||
@ -32,7 +32,8 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||||||
| [DenoRaylib550](https://github.com/JJLDonley/DenoRaylib550) | **5.5** | [Deno](https://deno.land) | MIT |
|
| [DenoRaylib550](https://github.com/JJLDonley/DenoRaylib550) | **5.5** | [Deno](https://deno.land) | MIT |
|
||||||
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||||
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
||||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |
|
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 5.5 | [Factor](https://factorcode.org) | BSD |
|
||||||
|
| [raylib4fb](https://github.com/mudhairless/raylib4fb) | **5.5** | [FreeBASIC](https://www.freebasic.net) | Zlib |
|
||||||
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
||||||
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
||||||
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
|
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
|
||||||
@ -59,7 +60,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||||||
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib |
|
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib |
|
||||||
| [naylib](https://github.com/planetis-m/naylib) | **5.6-dev** | [Nim](https://nim-lang.org) | MIT |
|
| [naylib](https://github.com/planetis-m/naylib) | **5.6-dev** | [Nim](https://nim-lang.org) | MIT |
|
||||||
| [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib |
|
| [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib |
|
||||||
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | BSD-3Clause |
|
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | Zlib |
|
||||||
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
|
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
|
||||||
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **5.0** | [OCaml](https://ocaml.org) | MIT |
|
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **5.0** | [OCaml](https://ocaml.org) | MIT |
|
||||||
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
||||||
@ -103,6 +104,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||||||
| [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **5.5** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT |
|
| [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **5.5** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT |
|
||||||
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
|
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
|
||||||
| [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** |
|
| [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** |
|
||||||
|
| [Target](https://github.com/FinnDemonCat/Target/tree/main/libs/raylib) | **5.5** | [Dart](https://dart.dev/) | Apache-2.0 license |
|
||||||
|
|
||||||
|
|
||||||
### Utility Wrapers
|
### Utility Wrapers
|
||||||
|
|||||||
@ -6,7 +6,7 @@ if(EMSCRIPTEN)
|
|||||||
# When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default
|
# When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default
|
||||||
SET(PLATFORM Web CACHE STRING "Platform to build for.")
|
SET(PLATFORM Web CACHE STRING "Platform to build for.")
|
||||||
endif()
|
endif()
|
||||||
enum_option(PLATFORM "Desktop;Web;WebRGFW;Android;Raspberry Pi;DRM;SDL;RGFW" "Platform to build for.")
|
enum_option(PLATFORM "Desktop;Web;WebRGFW;Android;Raspberry Pi;DRM;SDL;RGFW;Memory" "Platform to build for.")
|
||||||
|
|
||||||
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")
|
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")
|
||||||
|
|
||||||
|
|||||||
82
HISTORY.md
@ -419,7 +419,7 @@ Highlights for `raylib 4.5`:
|
|||||||
|
|
||||||
- **`NEW` Support QOA audio format (import/export)**: Just a couple of months ago the new [QOA file format](https://qoaformat.org/) was published, a very simple, portable and open source quite-ok-audio file format. raylib already supports it, added to `raudio` module and including audio loading from file, loading from memory, streaming from file, streaming from memory and **exporting to QOA** audio format. **Because simplicity really matters to raylib!**
|
- **`NEW` Support QOA audio format (import/export)**: Just a couple of months ago the new [QOA file format](https://qoaformat.org/) was published, a very simple, portable and open source quite-ok-audio file format. raylib already supports it, added to `raudio` module and including audio loading from file, loading from memory, streaming from file, streaming from memory and **exporting to QOA** audio format. **Because simplicity really matters to raylib!**
|
||||||
|
|
||||||
- **`NEW` Module for compressed textures loading**: [`rl_gputex`](https://github.com/raysan5/raylib/blob/master/src/external/rl_gputex.h), a portable single-file header-only small library to load compressed texture file-formats (DDS, PKM, KTX, PVR, ASTC). Provided functionality is not new to raylib but it was part of the raylib `rtextures` module, now it has been moved into a separate self-contained library, **improving portability**. Note that this module is only intended to **load compressed data from files, ready to be uploaded to GPU**, no compression/decompression functionality is provided. This change is a first step towards a better modularization of raylib library.
|
- **`NEW` Module for compressed textures loading**: [`rl_gputex`](https://github.com/raysan5/raylib/blob/master/src/external/rltexgpu.h), a portable single-file header-only small library to load compressed texture file-formats (DDS, PKM, KTX, PVR, ASTC). Provided functionality is not new to raylib but it was part of the raylib `rtextures` module, now it has been moved into a separate self-contained library, **improving portability**. Note that this module is only intended to **load compressed data from files, ready to be uploaded to GPU**, no compression/decompression functionality is provided. This change is a first step towards a better modularization of raylib library.
|
||||||
|
|
||||||
- **Reviewed `rlgl` module for automatic limits checking**: Again, [`rlgl`](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been reviewed to simplify usage. Now users do not need to worry about reaching the internal render-batch limits when they send their triangles to draw 2d/3d, `rlgl` manages it automatically! This change allows a **great simplification for other modules** like `rshapes`, `rtextures` and `rmodels` that do not need to worry about bufffer overflows and can just define as many vertex as desired!
|
- **Reviewed `rlgl` module for automatic limits checking**: Again, [`rlgl`](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been reviewed to simplify usage. Now users do not need to worry about reaching the internal render-batch limits when they send their triangles to draw 2d/3d, `rlgl` manages it automatically! This change allows a **great simplification for other modules** like `rshapes`, `rtextures` and `rmodels` that do not need to worry about bufffer overflows and can just define as many vertex as desired!
|
||||||
|
|
||||||
@ -522,3 +522,83 @@ Last but not least, I want to thank **raylib sponsors and all the raylib communi
|
|||||||
**After 11 years of development, `raylib 5.5` is the best raylib ever.**
|
**After 11 years of development, `raylib 5.5` is the best raylib ever.**
|
||||||
|
|
||||||
**Enjoy programming with raylib!** :)
|
**Enjoy programming with raylib!** :)
|
||||||
|
|
||||||
|
notes on raylib 6.0
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
A new `raylib` release is finally ready and, again, this is the **biggest `raylib` release ever**! Thanks to the support of many amazing contributors this release comes packed with many new features and improvements, also thanks to the financial support of [NLnet](https://nlnet.nl/) and the [NGI Zero Commond Fund](https://nlnet.nl/NGI0/) that allow me to work on this project mostly fulltime for the past few months.
|
||||||
|
|
||||||
|
Some astonishing numbers for this release:
|
||||||
|
|
||||||
|
- **+320** closed issues (for a TOTAL of **+2140**!)
|
||||||
|
- **+1950** commits since previous RELEASE (for a TOTAL of **+9700**!)
|
||||||
|
- **+20** new functions ADDED to raylib API (for a TOTAL of **600**!)
|
||||||
|
- **+50** new examples to learn from (for a TOTAL of **+210**!)
|
||||||
|
- **+210** new contributors (for a TOTAL of **+850**!)
|
||||||
|
|
||||||
|
Highlights for `raylib 6.0`:
|
||||||
|
|
||||||
|
- **`NEW` Software Renderer - [`rlsw`](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h)**: The biggest addition of this new release. A new software renderer backend, that allows raylib to run purely on CPU, with no neeed for a GPU. It finally closes the circle of my search for a portable self-contained, with **no-external-dependencies**, graphics library, able to run on any device providing some CPU-power and some RAM memory. It has been possible thanks to the amazing work of **Le Juez Victor** ([@Bigfoot71](https://github.com/Bigfoot71)), who created [`rlsw`](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h), a single-file header-only library implementing OpenGL 1.1+ specification, tailored to fit into raylib [`rlgl`](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) OpenGL wrapper, and allowing to run raylib seamlessly over CPU with **no code changes required on user side**. As expected, software rendering is slower than hardware-accelerated rendering but it is still fast enough to run basic application at 30-60 fps. Actually, it already proved it usefulness on a new [raylib port for ESP32](https://components.espressif.com/components/georgik/raylib/versions/6.0.0/readme) microcontroller by Espressif, useful for industrial applications, and opens the door to the upcoming RISC-V powered devices that start arriving to the marked, and many times come with no GPU. Along the new software renderer, some of the existing platform backends have been adapted to support it (SDL, RGFW, DRM) and also **new platforms backends have been created** to accomodate it (Win32, Emscripten), incluing a new `PLATFORM_MEMORY`, that allows direct rendering to a memory framebuffer.
|
||||||
|
|
||||||
|
- **`NEW` Platform backend: Memory - [`rcore_memory`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_memory.c)**: This new platform has been added along the **software renderer** backend, allowing 2d and 3d rendering over a **platform-agnostic memory framebuffer**, it can run headless and output frames can be directly exported to images. This new backend could also be useful for graphics rendering on servers or process images directly using the memory buffer.
|
||||||
|
|
||||||
|
- **`NEW` Platform backend: Win32 - [`rcore_desktop_win32`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_win32.c)**: A new **Windows platform backend** and the first step towards a potential replacement/alternative to the platform libraries currently used by raylib (GLFW/SDL/RGFW). This backend follows same API template structure than the other raylib backends, but directly implementing Win32 API calls. It allows initializing OpenGL GPU-accelerated windows and also GDI based windows, useful for the software renderer backend. This new backend approach, following a common template-structure and separating the platform logic by specific OS/Windowing system, will simplify code, improve maintenance, readability and portability for raylib, setting some bases for the future. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
|
||||||
|
|
||||||
|
- **`NEW` Platform backend: Emscripten - [`rcore_web_emscripten`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_web_emscripten.c)**: In the same line as Win32 backend, this new web backend moves away from `libglfw.js` and **directly implements Emscripten/JS functionality**, with **no other dependencies**, adding support for the new software renderer to draw directly on a **non-accelerated 2d canvas** but also supporting a WebGL-hardware-accelerated canvas when required. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
|
||||||
|
|
||||||
|
- **`REDESIGNED` Fullscreen modes and High-DPI content scaling**: After many years and many related issues, the full-screen and high-dpi content scaling support has been **completely redesigned** from scratch. New design prioritizes **borderless fullscreen modes** and automatically detects current monitor content scaling configuration to scale window and framebuffer accordingly when required. Still, High-DPI support must be requested by user if desired enabling `FLAG_WINDOW_HIGHDPI` on window creation. This new system has been carefully tested on Windows, Linux (X11, Wayland), macOS with multiple monitors and multiple resolutions, including 4K monitors.
|
||||||
|
|
||||||
|
- **`REDESIGNED` Skeletal Animation System**: A new animation system for 3d models has been created to support animation blending, between single frames but also between differents frames on different animations, to allow easy **timed transitions** between animations. This redesign implied reviewing several raylib structures to better accomodate animation data: `Model`, `ModelSkeleton`, `ModelAnimation`, but the API was simplified and support for GPU-skinning was improved with multiple optimizations.
|
||||||
|
|
||||||
|
- **`REDESIGNED` Build Config System - [`config.h`](https://github.com/raysan5/raylib/blob/master/src/config.h)**: raylib allows lot of customization for specific needs (i.e. disabling modules not needed for specific applications like rmodels or raudio) but previous implementation did not allow easely disabling some features from **custom build systems**. New design not only allows disabling features with simple `-DSUPPORT_FILEFORMAT_OBJ=0` on building command-line but also the full system has been reviewed, removing useless flags and exposing new ones.
|
||||||
|
|
||||||
|
- **`NEW` File System API**: Along the years, multiple filesystem functions have been added to raylib API as required but it felt somewhat inconsistent with some pieces missing. In this new release, the full filesystem API has beeen reviewed and reorganized, compiling all the functionality single module: [rcore](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1126), consequently `utils` module has been removed and build system has been simplified even more; **only 6-7 modules (.c) need to be compiled containing the full raylib library**. This new filesystem API will allow raylib to be used on the creation of custom build systems, as already demostrated with the new `rexm` tool for examples management. At the moment raylib includes **+40 file system management functions**, here a list with the new functions added:
|
||||||
|
```c
|
||||||
|
int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists)
|
||||||
|
int FileRemove(const char *fileName); // Remove file (if exists)
|
||||||
|
int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist
|
||||||
|
int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist
|
||||||
|
int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file
|
||||||
|
int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`NEW` Text Management API**: Along with the new file system functionality, a new set of text management functions has been added, also very useful for text procesing and also used in custom build systems creation using raylib. At the moment raylib includes **+30 text management functions**, here a list with the new functions added:
|
||||||
|
```c
|
||||||
|
char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
|
||||||
|
void UnloadTextLines(char **text, int lineCount); // Unload text lines
|
||||||
|
const char *TextRemoveSpaces(const char *text); // Remove text spaces, concat words
|
||||||
|
char *GetTextBetween(const char *text, const char *begin, const char *end); // Get text between two strings
|
||||||
|
char *TextReplace(const char *text, const char *search, const char *replacement); // Replace text string with new string
|
||||||
|
char *TextReplaceAlloc(const char *text, const char *search, const char *replacement); // Replace text string with new string, memory must be MemFree()
|
||||||
|
char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings
|
||||||
|
char *TextReplaceBetweenAlloc(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings, memory must be MemFree()
|
||||||
|
char *TextInsertAlloc(const char *text, const char *insert, int position); // Insert text in a defined byte position, memory must be MemFree()
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`NEW` tool: raylib examples manager - [rexm](https://github.com/raysan5/raylib/tree/master/tools/rexm)**: raylib examples collection is huge, with **more than 200 examples** it was quite difficult to manage: adding, removing, renaming examples was a very costly process involving many files to be modified (including build systems), also the examples did not follow a common header convention neither a structure conventions. For that reason, a new support tool has been created: **rexm**, a raylib examples manager that allows to easely add/remove/rename examples, automatically fix inconsistencies and even **building and automated testing** on multiple platforms.
|
||||||
|
```
|
||||||
|
USAGE:
|
||||||
|
> rexm <command> <example_name> [<example_rename>]
|
||||||
|
|
||||||
|
COMMANDS:
|
||||||
|
create <new_example_name> : Creates an empty example, from internal template
|
||||||
|
add <example_name> : Add existing example to collection
|
||||||
|
rename <old_examples_name> <new_example_name> : Rename an existing example
|
||||||
|
remove <example_name> : Remove an existing example from collection
|
||||||
|
build <example_name> : Build example for Desktop and Web platforms
|
||||||
|
test <example_name> : Build and Test example for Desktop and Web platforms
|
||||||
|
validate : Validate examples collection, generates report
|
||||||
|
update : Validate and update examples collection, generates report
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`NEW` +50 new examples**: Thanks to `rexm` and the simplification on examples management, this new raylib release includes +50 new examples to leearn from, most of them contributed by community.
|
||||||
|
|
||||||
|
Make sure to check raylib [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) for a detailed list of changes!
|
||||||
|
|
||||||
|
I want to **thank all the contributors (+850!**) that along the years have **greatly improved raylib** and pushed it further and better day after day. And **many thanks to raylib community and all raylib users** for supporting the library along those many years.
|
||||||
|
|
||||||
|
Finally, I want to thank [puffer.ai](https://puffer.ai/) and [comma.ai](https://comma.ai/) for **supporting and sponsoring the project** as platinum sponsors, along many others individuals that have been sponsoring raylib along the years. Thanks to all of you for allowing me to keep working on this library!
|
||||||
|
|
||||||
|
**After +12 years of development, `raylib 6.0` is today one of the bests libraries to enjoy games/tools/graphic programming!**
|
||||||
|
|
||||||
|
**Enjoy graphics programming with raylib!** :)
|
||||||
|
|||||||
@ -40,6 +40,7 @@ features
|
|||||||
- Written in plain C code (C99) using PascalCase/camelCase notation
|
- Written in plain C code (C99) using PascalCase/camelCase notation
|
||||||
- Hardware accelerated with OpenGL: **1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**
|
- Hardware accelerated with OpenGL: **1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**
|
||||||
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
|
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
|
||||||
|
- **Software Renderer** backend (no OpenGL required!): [rlsw](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h)
|
||||||
- Multiple **Fonts** formats supported (TTF, OTF, FNT, BDF, sprite fonts)
|
- Multiple **Fonts** formats supported (TTF, OTF, FNT, BDF, sprite fonts)
|
||||||
- Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC)
|
- Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC)
|
||||||
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
|
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
|
||||||
@ -61,7 +62,7 @@ This is a basic raylib example, it creates a window and draws the text `"Congrat
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
InitWindow(800, 450, "raylib [core] example - basic window");
|
InitWindow(800, 450, "raylib example - basic window");
|
||||||
|
|
||||||
while (!WindowShouldClose())
|
while (!WindowShouldClose())
|
||||||
{
|
{
|
||||||
|
|||||||
34
ROADMAP.md
@ -6,6 +6,7 @@ Here is a wishlist with features and ideas to improve the library. Note that fea
|
|||||||
- [GitHub PRs](https://github.com/raysan5/raylib/pulls) open with improvements to be reviewed.
|
- [GitHub PRs](https://github.com/raysan5/raylib/pulls) open with improvements to be reviewed.
|
||||||
- [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve.
|
- [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve.
|
||||||
- raylib wishlists discussions are open to everyone to ask for improvements, feel free to check and comment:
|
- raylib wishlists discussions are open to everyone to ask for improvements, feel free to check and comment:
|
||||||
|
- [raylib 7.0 wishlist](https://github.com/raysan5/raylib/discussions/5710)
|
||||||
- [raylib 6.0 wishlist](https://github.com/raysan5/raylib/discussions/4660)
|
- [raylib 6.0 wishlist](https://github.com/raysan5/raylib/discussions/4660)
|
||||||
- [raylib 5.0 wishlist](https://github.com/raysan5/raylib/discussions/2952)
|
- [raylib 5.0 wishlist](https://github.com/raysan5/raylib/discussions/2952)
|
||||||
- [raylib wishlist 2022](https://github.com/raysan5/raylib/discussions/2272)
|
- [raylib wishlist 2022](https://github.com/raysan5/raylib/discussions/2272)
|
||||||
@ -13,17 +14,29 @@ Here is a wishlist with features and ideas to improve the library. Note that fea
|
|||||||
|
|
||||||
_Current version of raylib is complete and functional but there is always room for improvements._
|
_Current version of raylib is complete and functional but there is always room for improvements._
|
||||||
|
|
||||||
**raylib 5.x**
|
**raylib 7.0**
|
||||||
- [ ] `rcore`: Support additional platforms: iOS, consoles?
|
- [ ] `rcore_desktop_win32`: Improve new Windows platform backend - inputs, highdpi
|
||||||
- [x] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK
|
- [ ] `rcore_desktop_emscripten`: Improve new Web platform backend - inputs, highdpi
|
||||||
- [ ] `rlgl`: Review GLSL shaders naming conventions for consistency
|
- [ ] `rcore_desktop_cocoa`: Create additional platform backend: macOS
|
||||||
- [ ] `textures`: Improve compressed textures support, loading and saving
|
- [ ] `rcore_desktop_x11`: Create additional platform backend: Linux/X11
|
||||||
- [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
|
- [ ] `rcore_desktop_wayland`: Create additional platform backend: Linux/Wayland
|
||||||
- [ ] `raudio`: Implement miniaudio high-level provided features
|
- [ ] `rcore`: Investigate alternative embedded platforms and realtime OSs
|
||||||
- [x] `examples`: Review all examples, add more and better code explanations
|
- [ ] `rlsw`: Software renderer optimizations: mipmaps, platform-specific SIMD
|
||||||
- [x] Software renderer backend? Maybe using `Image` provided API
|
- [ ] `rtextures`: Consider removing N-patch system, provide as separate example
|
||||||
|
- [ ] `rtextures`: Review blending modes system, provide more options or better samples
|
||||||
|
- [ ] `rtext`: Investigate the recently opened [`Slug`](https://sluglibrary.com/) font rendering algorithm
|
||||||
|
- [ ] `raudio`: Support microphone input, basic API to read microphone
|
||||||
|
- [ ] `rltexgpu`: Improve compressed textures support, loading and saving, improve KTX 2.0
|
||||||
|
- [ ] `rlobj`: Create OBJ loader, supporting material file separately (low priority)
|
||||||
|
|
||||||
**raylib 4.x**
|
**raylib 6.0**
|
||||||
|
- [x] `rlsw`: New Software Renderer backend, pseudo-OpenGL 1.1 implementation
|
||||||
|
- [x] `rcore_emscripten`: New emscripten-only backend, avoiding GLFW dependency
|
||||||
|
- [x] `rlgl`: Review GLSL shaders naming conventions for consistency, redesigned shader API
|
||||||
|
- [x] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
|
||||||
|
- [x] `examples`: Review all examples, add more and better code explanations
|
||||||
|
|
||||||
|
**raylib 5.0**
|
||||||
- [x] Split core module into separate platforms?
|
- [x] Split core module into separate platforms?
|
||||||
- [x] Redesign gestures system, improve touch inputs management
|
- [x] Redesign gestures system, improve touch inputs management
|
||||||
- [x] Redesign camera module (more flexible) ([#1143](https://github.com/raysan5/raylib/issues/1143), https://github.com/raysan5/raylib/discussions/2507)
|
- [x] Redesign camera module (more flexible) ([#1143](https://github.com/raysan5/raylib/issues/1143), https://github.com/raysan5/raylib/discussions/2507)
|
||||||
@ -31,7 +44,6 @@ _Current version of raylib is complete and functional but there is always room f
|
|||||||
- [x] Focus on HTML5 ([raylib 5k gamejam](https://itch.io/jam/raylib-5k-gamejam)) and embedded platforms (RPI and similar SOCs)
|
- [x] Focus on HTML5 ([raylib 5k gamejam](https://itch.io/jam/raylib-5k-gamejam)) and embedded platforms (RPI and similar SOCs)
|
||||||
- [x] Additional support libraries: [raygui](https://github.com/raysan5/raygui), [rres](https://github.com/raysan5/rres)
|
- [x] Additional support libraries: [raygui](https://github.com/raysan5/raygui), [rres](https://github.com/raysan5/rres)
|
||||||
|
|
||||||
|
|
||||||
**raylib 4.0**
|
**raylib 4.0**
|
||||||
- [x] Improved consistency and coherency in raylib API
|
- [x] Improved consistency and coherency in raylib API
|
||||||
- [x] Continuous Deployment using GitHub Actions
|
- [x] Continuous Deployment using GitHub Actions
|
||||||
|
|||||||
133
build.zig
@ -1,19 +1,9 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
/// Minimum supported version of Zig
|
|
||||||
const min_ver = "0.16.0-dev.2349+204fa8959";
|
|
||||||
|
|
||||||
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
|
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
|
||||||
const emccOutputFile = "index.html";
|
const emccOutputFile = "index.html";
|
||||||
|
|
||||||
comptime {
|
|
||||||
const order = std.SemanticVersion.order;
|
|
||||||
const parse = std.SemanticVersion.parse;
|
|
||||||
if (order(builtin.zig_version, parse(min_ver) catch unreachable) == .lt)
|
|
||||||
@compileError("Raylib requires zig version " ++ min_ver);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const emsdk = struct {
|
pub const emsdk = struct {
|
||||||
const zemscripten = @import("zemscripten");
|
const zemscripten = @import("zemscripten");
|
||||||
|
|
||||||
@ -90,41 +80,7 @@ fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A list of all flags from `src/config.h` that one may override
|
|
||||||
const config_h_flags = outer: {
|
|
||||||
// Set this value higher if compile errors happen as `src/config.h` gets larger
|
|
||||||
@setEvalBranchQuota(1 << 20);
|
|
||||||
|
|
||||||
const config_h = @embedFile("src/config.h");
|
|
||||||
var flags: [std.mem.count(u8, config_h, "\n") + 1][]const u8 = undefined;
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
var lines = std.mem.tokenizeScalar(u8, config_h, '\n');
|
|
||||||
while (lines.next()) |line| {
|
|
||||||
if (!std.mem.containsAtLeast(u8, line, 1, "SUPPORT")) continue;
|
|
||||||
if (std.mem.containsAtLeast(u8, line, 1, "MODULE")) continue;
|
|
||||||
if (std.mem.startsWith(u8, line, "//")) continue;
|
|
||||||
if (std.mem.startsWith(u8, line, "#if")) continue;
|
|
||||||
|
|
||||||
var flag = std.mem.trimStart(u8, line, " \t"); // Trim whitespace
|
|
||||||
flag = flag["#define ".len - 1 ..]; // Remove #define
|
|
||||||
flag = std.mem.trimStart(u8, flag, " \t"); // Trim whitespace
|
|
||||||
flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
|
|
||||||
flag = "-D" ++ flag; // Prepend with -D
|
|
||||||
|
|
||||||
flags[i] = flag;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uncomment this to check what flags normally get passed
|
|
||||||
//@compileLog(flags[0..i].*);
|
|
||||||
break :outer flags[0..i].*;
|
|
||||||
};
|
|
||||||
|
|
||||||
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||||
var raylib_flags_arr: std.ArrayList([]const u8) = .empty;
|
|
||||||
defer raylib_flags_arr.deinit(b.allocator);
|
|
||||||
|
|
||||||
const raylib = b.addLibrary(.{
|
const raylib = b.addLibrary(.{
|
||||||
.name = "raylib",
|
.name = "raylib",
|
||||||
.linkage = options.linkage,
|
.linkage = options.linkage,
|
||||||
@ -135,29 +91,27 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
try raylib_flags_arr.appendSlice(
|
raylib.root_module.addCMacro("_GNU_SOURCE", "");
|
||||||
|
raylib.root_module.addCMacro("GL_SILENCE_DEPRECATION", "199309L");
|
||||||
|
|
||||||
|
var raylib_flags_arr: std.ArrayList([]const u8) = .empty;
|
||||||
|
defer raylib_flags_arr.deinit(b.allocator);
|
||||||
|
|
||||||
|
try raylib_flags_arr.append(
|
||||||
b.allocator,
|
b.allocator,
|
||||||
&[_][]const u8{
|
"-std=gnu99",
|
||||||
"-std=gnu99",
|
|
||||||
"-D_GNU_SOURCE",
|
|
||||||
"-DGL_SILENCE_DEPRECATION=199309L",
|
|
||||||
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (options.linkage == .dynamic) {
|
if (options.linkage == .dynamic) {
|
||||||
try raylib_flags_arr.appendSlice(
|
try raylib_flags_arr.append(
|
||||||
b.allocator,
|
b.allocator,
|
||||||
&[_][]const u8{
|
"-fPIC",
|
||||||
"-fPIC",
|
|
||||||
"-DBUILD_LIBTYPE_SHARED",
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
raylib.root_module.addCMacro("BUILD_LIBTYPE_SHARED", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.config.len > 0) {
|
if (options.config.len > 0) {
|
||||||
// Sets a flag indicating the use of a custom `config.h`
|
|
||||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
|
||||||
// Splits a space-separated list of config flags into multiple flags
|
// Splits a space-separated list of config flags into multiple flags
|
||||||
//
|
//
|
||||||
// Note: This means certain flags like `-x c++` won't be processed properly.
|
// Note: This means certain flags like `-x c++` won't be processed properly.
|
||||||
@ -165,30 +119,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||||||
var config_iter = std.mem.tokenizeScalar(u8, options.config, ' ');
|
var config_iter = std.mem.tokenizeScalar(u8, options.config, ' ');
|
||||||
|
|
||||||
// Apply config flags supplied by the user
|
// Apply config flags supplied by the user
|
||||||
while (config_iter.next()) |config_flag|
|
while (config_iter.next()) |config_flag| {
|
||||||
try raylib_flags_arr.append(b.allocator, config_flag);
|
try raylib_flags_arr.append(b.allocator, config_flag);
|
||||||
|
|
||||||
// Apply all relevant configs from `src/config.h` *except* the user-specified ones
|
|
||||||
//
|
|
||||||
// Note: Currently using a suboptimal `O(m*n)` time algorithm where:
|
|
||||||
// `m` corresponds roughly to the number of lines in `src/config.h`
|
|
||||||
// `n` corresponds to the number of user-specified flags
|
|
||||||
outer: for (config_h_flags) |flag| {
|
|
||||||
// If a user already specified the flag, skip it
|
|
||||||
config_iter.reset();
|
|
||||||
while (config_iter.next()) |config_flag| {
|
|
||||||
// For a user-specified flag to match, it must share the same prefix and have the
|
|
||||||
// same length or be followed by an equals sign
|
|
||||||
if (!std.mem.startsWith(u8, config_flag, flag)) continue;
|
|
||||||
if (config_flag.len == flag.len or config_flag[flag.len] == '=') continue :outer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, append default value from config.h to compile flags
|
|
||||||
try raylib_flags_arr.append(b.allocator, flag);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Set default config if no custom config got set
|
|
||||||
try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No GLFW required on PLATFORM_DRM
|
// No GLFW required on PLATFORM_DRM
|
||||||
@ -200,24 +133,38 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||||||
c_source_files.appendSliceAssumeCapacity(&.{"src/rcore.c"});
|
c_source_files.appendSliceAssumeCapacity(&.{"src/rcore.c"});
|
||||||
|
|
||||||
if (options.rshapes) {
|
if (options.rshapes) {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RSHAPES", "1");
|
||||||
try c_source_files.append(b.allocator, "src/rshapes.c");
|
try c_source_files.append(b.allocator, "src/rshapes.c");
|
||||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RSHAPES");
|
} else {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RSHAPES", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.rtextures) {
|
if (options.rtextures) {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RTEXTURES", "1");
|
||||||
try c_source_files.append(b.allocator, "src/rtextures.c");
|
try c_source_files.append(b.allocator, "src/rtextures.c");
|
||||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RTEXTURES");
|
} else {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RTEXTURES", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.rtext) {
|
if (options.rtext) {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RTEXT", "1");
|
||||||
try c_source_files.append(b.allocator, "src/rtext.c");
|
try c_source_files.append(b.allocator, "src/rtext.c");
|
||||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RTEXT");
|
} else {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RTEXT", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.rmodels) {
|
if (options.rmodels) {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RMODELS", "1");
|
||||||
try c_source_files.append(b.allocator, "src/rmodels.c");
|
try c_source_files.append(b.allocator, "src/rmodels.c");
|
||||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RMODELS");
|
} else {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RMODELS", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.raudio) {
|
if (options.raudio) {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RAUDIO", "1");
|
||||||
try c_source_files.append(b.allocator, "src/raudio.c");
|
try c_source_files.append(b.allocator, "src/raudio.c");
|
||||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RAUDIO");
|
} else {
|
||||||
|
raylib.root_module.addCMacro("SUPPORT_MODULE_RAUDIO", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.opengl_version != .auto) {
|
if (options.opengl_version != .auto) {
|
||||||
@ -245,8 +192,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||||||
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
|
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
raylib.root_module.linkSystemLibrary("EGL", .{});
|
if (options.opengl_version != .gl_soft) {
|
||||||
raylib.root_module.linkSystemLibrary("gbm", .{});
|
raylib.root_module.linkSystemLibrary("EGL", .{});
|
||||||
|
raylib.root_module.linkSystemLibrary("gbm", .{});
|
||||||
|
}
|
||||||
raylib.root_module.linkSystemLibrary("libdrm", .{ .use_pkg_config = .force });
|
raylib.root_module.linkSystemLibrary("libdrm", .{ .use_pkg_config = .force });
|
||||||
|
|
||||||
raylib.root_module.addCMacro("PLATFORM_DRM", "");
|
raylib.root_module.addCMacro("PLATFORM_DRM", "");
|
||||||
@ -307,7 +256,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||||||
|
|
||||||
setDesktopPlatform(raylib, .android);
|
setDesktopPlatform(raylib, .android);
|
||||||
} else {
|
} else {
|
||||||
try c_source_files.append(b.allocator, "src/rglfw.c");
|
switch (options.platform) {
|
||||||
|
.glfw => try c_source_files.append(b.allocator, "src/rglfw.c"),
|
||||||
|
.rgfw, .sdl, .drm, .android => {},
|
||||||
|
}
|
||||||
|
|
||||||
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
||||||
raylib.root_module.addCMacro("_GLFW_X11", "");
|
raylib.root_module.addCMacro("_GLFW_X11", "");
|
||||||
@ -456,6 +408,7 @@ pub const Options = struct {
|
|||||||
|
|
||||||
pub const OpenglVersion = enum {
|
pub const OpenglVersion = enum {
|
||||||
auto,
|
auto,
|
||||||
|
gl_soft,
|
||||||
gl_1_1,
|
gl_1_1,
|
||||||
gl_2_1,
|
gl_2_1,
|
||||||
gl_3_3,
|
gl_3_3,
|
||||||
@ -466,6 +419,7 @@ pub const OpenglVersion = enum {
|
|||||||
pub fn toCMacroStr(self: @This()) []const u8 {
|
pub fn toCMacroStr(self: @This()) []const u8 {
|
||||||
switch (self) {
|
switch (self) {
|
||||||
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
|
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
|
||||||
|
.gl_soft => return "GRAPHICS_API_OPENGL_SOFTWARE",
|
||||||
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
|
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
|
||||||
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
|
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
|
||||||
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
|
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
|
||||||
@ -477,6 +431,7 @@ pub const OpenglVersion = enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const LinuxDisplayBackend = enum {
|
pub const LinuxDisplayBackend = enum {
|
||||||
|
None,
|
||||||
X11,
|
X11,
|
||||||
Wayland,
|
Wayland,
|
||||||
Both,
|
Both,
|
||||||
@ -524,7 +479,7 @@ fn addExamples(
|
|||||||
const all = b.step(module, "All " ++ module ++ " examples");
|
const all = b.step(module, "All " ++ module ++ " examples");
|
||||||
const module_subpath = b.pathJoin(&.{ "examples", module });
|
const module_subpath = b.pathJoin(&.{ "examples", module });
|
||||||
|
|
||||||
var dir = try std.Io.Dir.cwd().openDir(b.graph.io, b.pathFromRoot(module_subpath), .{ .iterate = true });
|
var dir = try b.build_root.handle.openDir(b.graph.io, module_subpath, .{ .iterate = true });
|
||||||
defer dir.close(b.graph.io);
|
defer dir.close(b.graph.io);
|
||||||
|
|
||||||
var iter = dir.iterate();
|
var iter = dir.iterate();
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
.{
|
.{
|
||||||
.name = .raylib,
|
.name = .raylib,
|
||||||
.version = "5.6.0-dev",
|
.version = "6.0.0",
|
||||||
.minimum_zig_version = "0.15.1",
|
.minimum_zig_version = "0.16.0",
|
||||||
|
|
||||||
.fingerprint = 0x13035e5cb8bc1ac2, // Changing this has security and trust implications.
|
.fingerprint = 0x13035e5cb8bc1ac2, // Changing this has security and trust implications.
|
||||||
|
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.xcode_frameworks = .{
|
.xcode_frameworks = .{
|
||||||
.url = "git+https://github.com/hexops/xcode-frameworks#9a45f3ac977fd25dff77e58c6de1870b6808c4a7",
|
.url = "https://pkg.machengine.org/xcode-frameworks/8a1cfb373587ea4c9bb1468b7c986462d8d4e10e.tar.gz",
|
||||||
.hash = "N-V-__8AABHMqAWYuRdIlflwi8gksPnlUMQBiSxAqQAAZFms",
|
.hash = "N-V-__8AALShqgXkvqYU6f__FrA22SMWmi2TXCJjNTO1m8XJ",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.emsdk = .{
|
.emsdk = .{
|
||||||
|
|||||||
@ -9,7 +9,7 @@ endif()
|
|||||||
|
|
||||||
set(RAYLIB_DEPENDENCIES "include(CMakeFindDependencyMacro)")
|
set(RAYLIB_DEPENDENCIES "include(CMakeFindDependencyMacro)")
|
||||||
|
|
||||||
if (${PLATFORM} MATCHES "Desktop")
|
if (${PLATFORM} STREQUAL "Desktop")
|
||||||
set(PLATFORM_CPP "PLATFORM_DESKTOP")
|
set(PLATFORM_CPP "PLATFORM_DESKTOP")
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
@ -67,14 +67,14 @@ if (${PLATFORM} MATCHES "Desktop")
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
elseif (${PLATFORM} MATCHES "Web")
|
elseif (${PLATFORM} STREQUAL "Web")
|
||||||
set(PLATFORM_CPP "PLATFORM_WEB")
|
set(PLATFORM_CPP "PLATFORM_WEB")
|
||||||
if(NOT GRAPHICS)
|
if(NOT GRAPHICS)
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||||
|
|
||||||
elseif (${PLATFORM} MATCHES "Android")
|
elseif (${PLATFORM} STREQUAL "Android")
|
||||||
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
@ -94,26 +94,35 @@ elseif (${PLATFORM} MATCHES "Android")
|
|||||||
set(LIBS_PRIVATE log android EGL GLESv2 OpenSLES atomic c)
|
set(LIBS_PRIVATE log android EGL GLESv2 OpenSLES atomic c)
|
||||||
set(LIBS_PUBLIC m)
|
set(LIBS_PUBLIC m)
|
||||||
|
|
||||||
elseif ("${PLATFORM}" MATCHES "DRM")
|
elseif ("${PLATFORM}" STREQUAL "DRM")
|
||||||
set(PLATFORM_CPP "PLATFORM_DRM")
|
set(PLATFORM_CPP "PLATFORM_DRM")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
|
||||||
|
|
||||||
add_definitions(-D_DEFAULT_SOURCE)
|
add_definitions(-D_DEFAULT_SOURCE)
|
||||||
add_definitions(-DEGL_NO_X11)
|
|
||||||
add_definitions(-DPLATFORM_DRM)
|
add_definitions(-DPLATFORM_DRM)
|
||||||
|
|
||||||
find_library(GLESV2 GLESv2)
|
|
||||||
find_library(EGL EGL)
|
|
||||||
find_library(DRM drm)
|
find_library(DRM drm)
|
||||||
find_library(GBM gbm)
|
|
||||||
|
|
||||||
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
|
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
|
||||||
include_directories(/usr/include/libdrm)
|
include_directories(/usr/include/libdrm)
|
||||||
endif ()
|
endif ()
|
||||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
|
||||||
|
if ("${OPENGL_VERSION}" STREQUAL "Software")
|
||||||
|
# software rendering does not require EGL/GBM.
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||||
|
set(LIBS_PRIVATE ${DRM} atomic pthread dl)
|
||||||
|
else ()
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
|
add_definitions(-DEGL_NO_X11)
|
||||||
|
|
||||||
|
find_library(GLESV2 GLESv2)
|
||||||
|
find_library(EGL EGL)
|
||||||
|
find_library(GBM gbm)
|
||||||
|
|
||||||
|
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
||||||
|
endif ()
|
||||||
set(LIBS_PUBLIC m)
|
set(LIBS_PUBLIC m)
|
||||||
|
|
||||||
elseif ("${PLATFORM}" MATCHES "SDL")
|
elseif ("${PLATFORM}" STREQUAL "SDL")
|
||||||
# First, check if SDL is included as a subdirectory
|
# First, check if SDL is included as a subdirectory
|
||||||
if(TARGET SDL3::SDL3)
|
if(TARGET SDL3::SDL3)
|
||||||
message(STATUS "Using SDL3 from subdirectory")
|
message(STATUS "Using SDL3 from subdirectory")
|
||||||
@ -143,11 +152,12 @@ elseif ("${PLATFORM}" MATCHES "SDL")
|
|||||||
message(STATUS "Found SDL2 via find_package()")
|
message(STATUS "Found SDL2 via find_package()")
|
||||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||||
set(LIBS_PUBLIC SDL2::SDL2)
|
set(LIBS_PUBLIC SDL2::SDL2)
|
||||||
set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL3 REQUIRED)")
|
set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL2 REQUIRED)")
|
||||||
add_compile_definitions(USING_SDL2_PACKAGE)
|
add_compile_definitions(USING_SDL2_PACKAGE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
elseif ("${PLATFORM}" MATCHES "RGFW")
|
|
||||||
|
elseif ("${PLATFORM}" STREQUAL "RGFW")
|
||||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW")
|
set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW")
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
@ -168,10 +178,19 @@ elseif ("${PLATFORM}" MATCHES "RGFW")
|
|||||||
set(LIBS_PRIVATE ${X11_LIBRARIES} ${OPENGL_LIBRARIES})
|
set(LIBS_PRIVATE ${X11_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
elseif ("${PLATFORM}" MATCHES "WebRGFW")
|
elseif ("${PLATFORM}" STREQUAL "WebRGFW")
|
||||||
set(PLATFORM_CPP "PLATFORM_WEB_RGFW")
|
set(PLATFORM_CPP "PLATFORM_WEB_RGFW")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||||
|
|
||||||
|
elseif ("${PLATFORM}" STREQUAL "Memory")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_MEMORY")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||||
|
set(OPENGL_VERSION "Software")
|
||||||
|
|
||||||
|
if(WIN32 OR CMAKE_C_COMPILER MATCHES "mingw|mingw32|mingw64")
|
||||||
|
set(LIBS_PRIVATE winmm)
|
||||||
|
endif()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||||
@ -190,7 +209,7 @@ if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
|||||||
elseif (${OPENGL_VERSION} MATCHES "ES 3.0")
|
elseif (${OPENGL_VERSION} MATCHES "ES 3.0")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES3")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES3")
|
||||||
elseif (${OPENGL_VERSION} MATCHES "Software")
|
elseif (${OPENGL_VERSION} MATCHES "Software")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_11_SOFTWARE")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||||
endif ()
|
endif ()
|
||||||
if (NOT "${SUGGESTED_GRAPHICS}" STREQUAL "" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
if (NOT "${SUGGESTED_GRAPHICS}" STREQUAL "" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
||||||
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail.")
|
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail.")
|
||||||
|
|||||||
@ -105,6 +105,9 @@ elseif ("${PLATFORM}" STREQUAL "DRM")
|
|||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||||
|
|
||||||
|
elseif ("${PLATFORM}" MATCHES "Memory")
|
||||||
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||||
|
|
||||||
elseif ("${OPENGL_VERSION}" STREQUAL "Software")
|
elseif ("${OPENGL_VERSION}" STREQUAL "Software")
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||||
|
|||||||
@ -69,7 +69,7 @@ endif
|
|||||||
|
|
||||||
# Define required raylib variables
|
# Define required raylib variables
|
||||||
PROJECT_NAME ?= raylib_examples
|
PROJECT_NAME ?= raylib_examples
|
||||||
RAYLIB_VERSION ?= 5.5.0
|
RAYLIB_VERSION ?= 6.0.0
|
||||||
RAYLIB_PATH ?= ..
|
RAYLIB_PATH ?= ..
|
||||||
|
|
||||||
# Define raylib source code path
|
# Define raylib source code path
|
||||||
@ -90,6 +90,16 @@ BUILD_MODE ?= RELEASE
|
|||||||
# Use external GLFW library instead of rglfw module
|
# Use external GLFW library instead of rglfw module
|
||||||
USE_EXTERNAL_GLFW ?= FALSE
|
USE_EXTERNAL_GLFW ?= FALSE
|
||||||
|
|
||||||
|
# Enable support for X11 by default on Linux when using GLFW
|
||||||
|
# NOTE: Wayland is disabled by default, only enable if you are sure
|
||||||
|
GLFW_LINUX_ENABLE_WAYLAND ?= FALSE
|
||||||
|
GLFW_LINUX_ENABLE_X11 ?= TRUE
|
||||||
|
|
||||||
|
# Enable support for X11 by default on Linux when using RGFW
|
||||||
|
# NOTE: Wayland is disabled by default, only enable if you are sure
|
||||||
|
RGFW_LINUX_ENABLE_WAYLAND ?= FALSE
|
||||||
|
RGFW_LINUX_ENABLE_X11 ?= TRUE
|
||||||
|
|
||||||
# PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally
|
# PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally
|
||||||
# WARNING: Library is not included in raylib, it MUST be configured by users
|
# WARNING: Library is not included in raylib, it MUST be configured by users
|
||||||
SDL_INCLUDE_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/include
|
SDL_INCLUDE_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/include
|
||||||
@ -145,15 +155,6 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# RAYLIB_PATH adjustment for LINUX platform
|
|
||||||
# TODO: Do we really need this?
|
|
||||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
|
||||||
ifeq ($(PLATFORM_OS),LINUX)
|
|
||||||
RAYLIB_PREFIX ?= ..
|
|
||||||
RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Default path for raylib on Raspberry Pi
|
# Default path for raylib on Raspberry Pi
|
||||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||||
RAYLIB_PATH ?= /home/pi/raylib
|
RAYLIB_PATH ?= /home/pi/raylib
|
||||||
@ -168,8 +169,8 @@ ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_R
|
|||||||
EMSDK_PATH ?= C:/raylib/emsdk
|
EMSDK_PATH ?= C:/raylib/emsdk
|
||||||
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
|
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
|
||||||
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
|
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
|
||||||
PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
|
PYTHON_PATH = $(EMSDK_PATH)/python/3.13.3_64bit
|
||||||
NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
|
NODE_PATH = $(EMSDK_PATH)/node/22.16.0_64bit/bin
|
||||||
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
|
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@ -294,7 +295,7 @@ endif
|
|||||||
|
|
||||||
# Define library paths containing required libs: LDFLAGS
|
# Define library paths containing required libs: LDFLAGS
|
||||||
#------------------------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------------------------
|
||||||
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
|
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH)
|
||||||
|
|
||||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||||
@ -394,9 +395,11 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
|||||||
LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
|
LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
|
||||||
|
|
||||||
# On Wayland, additional libraries requires
|
# On Wayland, additional libraries requires
|
||||||
ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
|
ifeq ($(GLFW_LINUX_ENABLE_WAYLAND),TRUE)
|
||||||
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
|
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
|
||||||
else
|
endif
|
||||||
|
|
||||||
|
ifeq ($(GLFW_LINUX_ENABLE_X11),TRUE)
|
||||||
# On X11, additional libraries required
|
# On X11, additional libraries required
|
||||||
LDLIBS += -lX11
|
LDLIBS += -lX11
|
||||||
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
|
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
|
||||||
@ -468,7 +471,15 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
|
|||||||
# Libraries for Debian GNU/Linux desktop compipling
|
# Libraries for Debian GNU/Linux desktop compipling
|
||||||
# NOTE: Required packages: libegl1-mesa-dev
|
# NOTE: Required packages: libegl1-mesa-dev
|
||||||
LDFLAGS += -L../src
|
LDFLAGS += -L../src
|
||||||
LDLIBS = -lraylib -lGL -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -lpthread -ldl -lrt
|
LDLIBS = -lraylib -lm
|
||||||
|
|
||||||
|
ifeq ($(RGFW_LINUX_ENABLE_X11),TRUE)
|
||||||
|
LDLIBS += -lGL -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lpthread -ldl -lrt
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(RGFW_LINUX_ENABLE_WAYLAND),TRUE)
|
||||||
|
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
|
||||||
|
endif
|
||||||
|
|
||||||
# Explicit link to libc
|
# Explicit link to libc
|
||||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||||
@ -611,6 +622,7 @@ TEXTURES = \
|
|||||||
textures/textures_blend_modes \
|
textures/textures_blend_modes \
|
||||||
textures/textures_bunnymark \
|
textures/textures_bunnymark \
|
||||||
textures/textures_cellular_automata \
|
textures/textures_cellular_automata \
|
||||||
|
textures/textures_clipboard_image \
|
||||||
textures/textures_fog_of_war \
|
textures/textures_fog_of_war \
|
||||||
textures/textures_framebuffer_rendering \
|
textures/textures_framebuffer_rendering \
|
||||||
textures/textures_gif_player \
|
textures/textures_gif_player \
|
||||||
@ -623,6 +635,7 @@ TEXTURES = \
|
|||||||
textures/textures_image_rotate \
|
textures/textures_image_rotate \
|
||||||
textures/textures_image_text \
|
textures/textures_image_text \
|
||||||
textures/textures_logo_raylib \
|
textures/textures_logo_raylib \
|
||||||
|
textures/textures_magnifying_glass \
|
||||||
textures/textures_mouse_painting \
|
textures/textures_mouse_painting \
|
||||||
textures/textures_npatch_drawing \
|
textures/textures_npatch_drawing \
|
||||||
textures/textures_particles_blending \
|
textures/textures_particles_blending \
|
||||||
@ -660,7 +673,7 @@ MODELS = \
|
|||||||
models/models_animation_blend_custom \
|
models/models_animation_blend_custom \
|
||||||
models/models_animation_blending \
|
models/models_animation_blending \
|
||||||
models/models_animation_gpu_skinning \
|
models/models_animation_gpu_skinning \
|
||||||
models/models_animation_timming \
|
models/models_animation_timing \
|
||||||
models/models_basic_voxel \
|
models/models_basic_voxel \
|
||||||
models/models_billboard_rendering \
|
models/models_billboard_rendering \
|
||||||
models/models_bone_socket \
|
models/models_bone_socket \
|
||||||
@ -692,6 +705,7 @@ SHADERS = \
|
|||||||
shaders/shaders_ascii_rendering \
|
shaders/shaders_ascii_rendering \
|
||||||
shaders/shaders_basic_lighting \
|
shaders/shaders_basic_lighting \
|
||||||
shaders/shaders_basic_pbr \
|
shaders/shaders_basic_pbr \
|
||||||
|
shaders/shaders_cel_shading \
|
||||||
shaders/shaders_color_correction \
|
shaders/shaders_color_correction \
|
||||||
shaders/shaders_custom_uniform \
|
shaders/shaders_custom_uniform \
|
||||||
shaders/shaders_deferred_rendering \
|
shaders/shaders_deferred_rendering \
|
||||||
@ -733,6 +747,7 @@ AUDIO = \
|
|||||||
audio/audio_sound_multi \
|
audio/audio_sound_multi \
|
||||||
audio/audio_sound_positioning \
|
audio/audio_sound_positioning \
|
||||||
audio/audio_spectrum_visualizer \
|
audio/audio_spectrum_visualizer \
|
||||||
|
audio/audio_stream_callback \
|
||||||
audio/audio_stream_effects
|
audio/audio_stream_effects
|
||||||
#EXAMPLES_LIST_END
|
#EXAMPLES_LIST_END
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# raylib makefile for Android project (APK building)
|
# raylib makefile for Android project (APK building)
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
|
# Copyright (c) 2017-2026 Ramon Santamaria (@raysan5)
|
||||||
#
|
#
|
||||||
# This software is provided "as-is", without any express or implied warranty. In no event
|
# This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
# will the authors be held liable for any damages arising from the use of this software.
|
# will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
|||||||
@ -69,7 +69,7 @@ endif
|
|||||||
|
|
||||||
# Define required raylib variables
|
# Define required raylib variables
|
||||||
PROJECT_NAME ?= raylib_examples
|
PROJECT_NAME ?= raylib_examples
|
||||||
RAYLIB_VERSION ?= 5.5.0
|
RAYLIB_VERSION ?= 6.0.0
|
||||||
RAYLIB_PATH ?= ..
|
RAYLIB_PATH ?= ..
|
||||||
|
|
||||||
# Define raylib source code path
|
# Define raylib source code path
|
||||||
@ -168,8 +168,8 @@ ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_R
|
|||||||
EMSDK_PATH ?= C:/raylib/emsdk
|
EMSDK_PATH ?= C:/raylib/emsdk
|
||||||
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
|
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
|
||||||
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
|
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
|
||||||
PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
|
PYTHON_PATH = $(EMSDK_PATH)/python/3.13.3_64bit
|
||||||
NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
|
NODE_PATH = $(EMSDK_PATH)/node/22.16.0_64bit/bin
|
||||||
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
|
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@ -596,6 +596,7 @@ TEXTURES = \
|
|||||||
textures/textures_blend_modes \
|
textures/textures_blend_modes \
|
||||||
textures/textures_bunnymark \
|
textures/textures_bunnymark \
|
||||||
textures/textures_cellular_automata \
|
textures/textures_cellular_automata \
|
||||||
|
textures/textures_clipboard_image \
|
||||||
textures/textures_fog_of_war \
|
textures/textures_fog_of_war \
|
||||||
textures/textures_framebuffer_rendering \
|
textures/textures_framebuffer_rendering \
|
||||||
textures/textures_gif_player \
|
textures/textures_gif_player \
|
||||||
@ -608,6 +609,7 @@ TEXTURES = \
|
|||||||
textures/textures_image_rotate \
|
textures/textures_image_rotate \
|
||||||
textures/textures_image_text \
|
textures/textures_image_text \
|
||||||
textures/textures_logo_raylib \
|
textures/textures_logo_raylib \
|
||||||
|
textures/textures_magnifying_glass \
|
||||||
textures/textures_mouse_painting \
|
textures/textures_mouse_painting \
|
||||||
textures/textures_npatch_drawing \
|
textures/textures_npatch_drawing \
|
||||||
textures/textures_particles_blending \
|
textures/textures_particles_blending \
|
||||||
@ -645,7 +647,7 @@ MODELS = \
|
|||||||
models/models_animation_blend_custom \
|
models/models_animation_blend_custom \
|
||||||
models/models_animation_blending \
|
models/models_animation_blending \
|
||||||
models/models_animation_gpu_skinning \
|
models/models_animation_gpu_skinning \
|
||||||
models/models_animation_timming \
|
models/models_animation_timing \
|
||||||
models/models_basic_voxel \
|
models/models_basic_voxel \
|
||||||
models/models_billboard_rendering \
|
models/models_billboard_rendering \
|
||||||
models/models_bone_socket \
|
models/models_bone_socket \
|
||||||
@ -677,6 +679,7 @@ SHADERS = \
|
|||||||
shaders/shaders_ascii_rendering \
|
shaders/shaders_ascii_rendering \
|
||||||
shaders/shaders_basic_lighting \
|
shaders/shaders_basic_lighting \
|
||||||
shaders/shaders_basic_pbr \
|
shaders/shaders_basic_pbr \
|
||||||
|
shaders/shaders_cel_shading \
|
||||||
shaders/shaders_color_correction \
|
shaders/shaders_color_correction \
|
||||||
shaders/shaders_custom_uniform \
|
shaders/shaders_custom_uniform \
|
||||||
shaders/shaders_deferred_rendering \
|
shaders/shaders_deferred_rendering \
|
||||||
@ -718,6 +721,7 @@ AUDIO = \
|
|||||||
audio/audio_sound_multi \
|
audio/audio_sound_multi \
|
||||||
audio/audio_sound_positioning \
|
audio/audio_sound_positioning \
|
||||||
audio/audio_spectrum_visualizer \
|
audio/audio_spectrum_visualizer \
|
||||||
|
audio/audio_stream_callback \
|
||||||
audio/audio_stream_effects
|
audio/audio_stream_effects
|
||||||
|
|
||||||
# Default target entry
|
# Default target entry
|
||||||
@ -1023,6 +1027,9 @@ textures/textures_bunnymark: textures/textures_bunnymark.c
|
|||||||
textures/textures_cellular_automata: textures/textures_cellular_automata.c
|
textures/textures_cellular_automata: textures/textures_cellular_automata.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
textures/textures_clipboard_image: textures/textures_clipboard_image.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
textures/textures_fog_of_war: textures/textures_fog_of_war.c
|
textures/textures_fog_of_war: textures/textures_fog_of_war.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
@ -1071,6 +1078,11 @@ textures/textures_logo_raylib: textures/textures_logo_raylib.c
|
|||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png
|
--preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png
|
||||||
|
|
||||||
|
textures/textures_magnifying_glass: textures/textures_magnifying_glass.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file textures/resources/raybunny.png@resources/raybunny.png \
|
||||||
|
--preload-file textures/resources/parrots.png@resources/parrots.png
|
||||||
|
|
||||||
textures/textures_mouse_painting: textures/textures_mouse_painting.c
|
textures/textures_mouse_painting: textures/textures_mouse_painting.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
@ -1141,7 +1153,10 @@ text/text_font_filters: text/text_font_filters.c
|
|||||||
--preload-file text/resources/KAISG.ttf@resources/KAISG.ttf
|
--preload-file text/resources/KAISG.ttf@resources/KAISG.ttf
|
||||||
|
|
||||||
text/text_font_loading: text/text_font_loading.c
|
text/text_font_loading: text/text_font_loading.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file text/resources/pixantiqua.fnt@resources/pixantiqua.fnt \
|
||||||
|
--preload-file text/resources/pixantiqua.png@resources/pixantiqua.png \
|
||||||
|
--preload-file text/resources/pixantiqua.ttf@resources/pixantiqua.ttf
|
||||||
|
|
||||||
text/text_font_sdf: text/text_font_sdf.c
|
text/text_font_sdf: text/text_font_sdf.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
@ -1218,7 +1233,7 @@ models/models_animation_gpu_skinning: models/models_animation_gpu_skinning.c
|
|||||||
--preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \
|
--preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \
|
||||||
--preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs
|
--preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs
|
||||||
|
|
||||||
models/models_animation_timming: models/models_animation_timming.c
|
models/models_animation_timing: models/models_animation_timing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb
|
--preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb
|
||||||
|
|
||||||
@ -1365,6 +1380,14 @@ shaders/shaders_basic_pbr: shaders/shaders_basic_pbr.c
|
|||||||
--preload-file shaders/resources/road_mra.png@resources/road_mra.png \
|
--preload-file shaders/resources/road_mra.png@resources/road_mra.png \
|
||||||
--preload-file shaders/resources/road_n.png@resources/road_n.png
|
--preload-file shaders/resources/road_n.png@resources/road_n.png
|
||||||
|
|
||||||
|
shaders/shaders_cel_shading: shaders/shaders_cel_shading.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file shaders/resources/models/old_car_new.glb@resources/models/old_car_new.glb \
|
||||||
|
--preload-file shaders/resources/shaders/glsl100/cel.vs@resources/shaders/glsl100/cel.vs \
|
||||||
|
--preload-file shaders/resources/shaders/glsl100/cel.fs@resources/shaders/glsl100/cel.fs \
|
||||||
|
--preload-file shaders/resources/shaders/glsl100/outline_hull.vs@resources/shaders/glsl100/outline_hull.vs \
|
||||||
|
--preload-file shaders/resources/shaders/glsl100/outline_hull.fs@resources/shaders/glsl100/outline_hull.fs
|
||||||
|
|
||||||
shaders/shaders_color_correction: shaders/shaders_color_correction.c
|
shaders/shaders_color_correction: shaders/shaders_color_correction.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file shaders/resources/parrots.png@resources/parrots.png \
|
--preload-file shaders/resources/parrots.png@resources/parrots.png \
|
||||||
@ -1550,7 +1573,8 @@ audio/audio_mixed_processor: audio/audio_mixed_processor.c
|
|||||||
--preload-file audio/resources/coin.wav@resources/coin.wav
|
--preload-file audio/resources/coin.wav@resources/coin.wav
|
||||||
|
|
||||||
audio/audio_module_playing: audio/audio_module_playing.c
|
audio/audio_module_playing: audio/audio_module_playing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file audio/resources/mini1111.xm@resources/mini1111.xm
|
||||||
|
|
||||||
audio/audio_music_stream: audio/audio_music_stream.c
|
audio/audio_music_stream: audio/audio_music_stream.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
@ -1577,6 +1601,9 @@ audio/audio_spectrum_visualizer: audio/audio_spectrum_visualizer.c
|
|||||||
--preload-file audio/resources/shaders/glsl100/fft.fs@resources/shaders/glsl100/fft.fs \
|
--preload-file audio/resources/shaders/glsl100/fft.fs@resources/shaders/glsl100/fft.fs \
|
||||||
--preload-file audio/resources/country.mp3@resources/country.mp3
|
--preload-file audio/resources/country.mp3@resources/country.mp3
|
||||||
|
|
||||||
|
audio/audio_stream_callback: audio/audio_stream_callback.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
audio/audio_stream_effects: audio/audio_stream_effects.c
|
audio/audio_stream_effects: audio/audio_stream_effects.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file audio/resources/country.mp3@resources/country.mp3
|
--preload-file audio/resources/country.mp3@resources/country.mp3
|
||||||
|
|||||||
@ -17,7 +17,7 @@ You may find it easier to use than other toolchains, especially when it comes to
|
|||||||
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
|
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
|
||||||
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
|
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
|
||||||
|
|
||||||
## EXAMPLES COLLECTION [TOTAL: 208]
|
## EXAMPLES COLLECTION [TOTAL: 212]
|
||||||
|
|
||||||
### category: core [49]
|
### category: core [49]
|
||||||
|
|
||||||
@ -26,14 +26,14 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
|||||||
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
| [core_basic_window](core/core_basic_window.c) | <img src="core/core_basic_window.png" alt="core_basic_window" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_basic_window](core/core_basic_window.c) | <img src="core/core_basic_window.png" alt="core_basic_window" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_delta_time](core/core_delta_time.c) | <img src="core/core_delta_time.png" alt="core_delta_time" width="80"> | ⭐☆☆☆ | 5.5 | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
| [core_delta_time](core/core_delta_time.c) | <img src="core/core_delta_time.png" alt="core_delta_time" width="80"> | ⭐☆☆☆ | 5.5 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||||
| [core_input_keys](core/core_input_keys.c) | <img src="core/core_input_keys.png" alt="core_input_keys" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_input_keys](core/core_input_keys.c) | <img src="core/core_input_keys.png" alt="core_input_keys" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_input_mouse](core/core_input_mouse.c) | <img src="core/core_input_mouse.png" alt="core_input_mouse" width="80"> | ⭐☆☆☆ | 1.0 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_input_mouse](core/core_input_mouse.c) | <img src="core/core_input_mouse.png" alt="core_input_mouse" width="80"> | ⭐☆☆☆ | 1.0 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_input_mouse_wheel](core/core_input_mouse_wheel.c) | <img src="core/core_input_mouse_wheel.png" alt="core_input_mouse_wheel" width="80"> | ⭐☆☆☆ | 1.1 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_input_mouse_wheel](core/core_input_mouse_wheel.c) | <img src="core/core_input_mouse_wheel.png" alt="core_input_mouse_wheel" width="80"> | ⭐☆☆☆ | 1.1 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐☆☆☆ | 1.1 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐☆☆☆ | 1.1 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) |
|
| [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) |
|
||||||
| [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐⭐☆☆ | 1.4 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐⭐☆☆ | 1.4 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_input_gestures_testbed](core/core_input_gestures_testbed.c) | <img src="core/core_input_gestures_testbed.png" alt="core_input_gestures_testbed" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.6-dev | [ubkp](https://github.com/ubkp) |
|
| [core_input_gestures_testbed](core/core_input_gestures_testbed.c) | <img src="core/core_input_gestures_testbed.png" alt="core_input_gestures_testbed" width="80"> | ⭐⭐⭐☆ | 5.0 | 6.0 | [ubkp](https://github.com/ubkp) |
|
||||||
| [core_input_virtual_controls](core/core_input_virtual_controls.c) | <img src="core/core_input_virtual_controls.png" alt="core_input_virtual_controls" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [GreenSnakeLinux](https://github.com/GreenSnakeLinux) |
|
| [core_input_virtual_controls](core/core_input_virtual_controls.c) | <img src="core/core_input_virtual_controls.png" alt="core_input_virtual_controls" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [GreenSnakeLinux](https://github.com/GreenSnakeLinux) |
|
||||||
| [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐⭐☆☆ | 1.5 | 3.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐⭐☆☆ | 1.5 | 3.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐⭐☆☆ | 4.2 | 4.2 | [Jeffery Myers](https://github.com/JeffM2501) |
|
| [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐⭐☆☆ | 4.2 | 4.2 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||||
@ -62,16 +62,16 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
|||||||
| [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐☆☆☆ | 5.0 | 5.0 | [Dalton Overmyer](https://github.com/REDl3east) |
|
| [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐☆☆☆ | 5.0 | 5.0 | [Dalton Overmyer](https://github.com/REDl3east) |
|
||||||
| [core_automation_events](core/core_automation_events.c) | <img src="core/core_automation_events.png" alt="core_automation_events" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_automation_events](core/core_automation_events.c) | <img src="core/core_automation_events.png" alt="core_automation_events" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_highdpi_demo](core/core_highdpi_demo.c) | <img src="core/core_highdpi_demo.png" alt="core_highdpi_demo" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) |
|
| [core_highdpi_demo](core/core_highdpi_demo.c) | <img src="core/core_highdpi_demo.png" alt="core_highdpi_demo" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) |
|
||||||
| [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_undo_redo](core/core_undo_redo.c) | <img src="core/core_undo_redo.png" alt="core_undo_redo" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_undo_redo](core/core_undo_redo.c) | <img src="core/core_undo_redo.png" alt="core_undo_redo" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_viewport_scaling](core/core_viewport_scaling.c) | <img src="core/core_viewport_scaling.png" alt="core_viewport_scaling" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
| [core_viewport_scaling](core/core_viewport_scaling.c) | <img src="core/core_viewport_scaling.png" alt="core_viewport_scaling" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
||||||
| [core_input_actions](core/core_input_actions.c) | <img src="core/core_input_actions.png" alt="core_input_actions" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) |
|
| [core_input_actions](core/core_input_actions.c) | <img src="core/core_input_actions.png" alt="core_input_actions" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) |
|
||||||
| [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
|
| [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
|
||||||
| [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) |
|
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Ananth S](https://github.com/Ananth1839) |
|
||||||
| [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
|
| [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
|
||||||
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_keyboard_testbed](core/core_keyboard_testbed.c) | <img src="core/core_keyboard_testbed.png" alt="core_keyboard_testbed" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_keyboard_testbed](core/core_keyboard_testbed.c) | <img src="core/core_keyboard_testbed.png" alt="core_keyboard_testbed" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_window_web](core/core_window_web.c) | <img src="core/core_window_web.png" alt="core_window_web" width="80"> | ⭐☆☆☆ | 1.3 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_window_web](core/core_window_web.c) | <img src="core/core_window_web.png" alt="core_window_web" width="80"> | ⭐☆☆☆ | 1.3 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
|||||||
| [shapes_easings_ball](shapes/shapes_easings_ball.c) | <img src="shapes/shapes_easings_ball.png" alt="shapes_easings_ball" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_easings_ball](shapes/shapes_easings_ball.c) | <img src="shapes/shapes_easings_ball.png" alt="shapes_easings_ball" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shapes_easings_box](shapes/shapes_easings_box.c) | <img src="shapes/shapes_easings_box.png" alt="shapes_easings_box" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_easings_box](shapes/shapes_easings_box.c) | <img src="shapes/shapes_easings_box.png" alt="shapes_easings_box" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shapes_easings_rectangles](shapes/shapes_easings_rectangles.c) | <img src="shapes/shapes_easings_rectangles.png" alt="shapes_easings_rectangles" width="80"> | ⭐⭐⭐☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_easings_rectangles](shapes/shapes_easings_rectangles.c) | <img src="shapes/shapes_easings_rectangles.png" alt="shapes_easings_rectangles" width="80"> | ⭐⭐⭐☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shapes_recursive_tree](shapes/shapes_recursive_tree.c) | <img src="shapes/shapes_recursive_tree.png" alt="shapes_recursive_tree" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
| [shapes_recursive_tree](shapes/shapes_recursive_tree.c) | <img src="shapes/shapes_recursive_tree.png" alt="shapes_recursive_tree" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Jopestpe](https://github.com/jopestpe) |
|
||||||
| [shapes_ring_drawing](shapes/shapes_ring_drawing.c) | <img src="shapes/shapes_ring_drawing.png" alt="shapes_ring_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| [shapes_ring_drawing](shapes/shapes_ring_drawing.c) | <img src="shapes/shapes_ring_drawing.png" alt="shapes_ring_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| [shapes_circle_sector_drawing](shapes/shapes_circle_sector_drawing.c) | <img src="shapes/shapes_circle_sector_drawing.png" alt="shapes_circle_sector_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| [shapes_circle_sector_drawing](shapes/shapes_circle_sector_drawing.c) | <img src="shapes/shapes_circle_sector_drawing.png" alt="shapes_circle_sector_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| [shapes_rounded_rectangle_drawing](shapes/shapes_rounded_rectangle_drawing.c) | <img src="shapes/shapes_rounded_rectangle_drawing.png" alt="shapes_rounded_rectangle_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| [shapes_rounded_rectangle_drawing](shapes/shapes_rounded_rectangle_drawing.c) | <img src="shapes/shapes_rounded_rectangle_drawing.png" alt="shapes_rounded_rectangle_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
@ -104,30 +104,32 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
|||||||
| [shapes_digital_clock](shapes/shapes_digital_clock.c) | <img src="shapes/shapes_digital_clock.png" alt="shapes_digital_clock" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
| [shapes_digital_clock](shapes/shapes_digital_clock.c) | <img src="shapes/shapes_digital_clock.png" alt="shapes_digital_clock" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
||||||
| [shapes_double_pendulum](shapes/shapes_double_pendulum.c) | <img src="shapes/shapes_double_pendulum.png" alt="shapes_double_pendulum" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) |
|
| [shapes_double_pendulum](shapes/shapes_double_pendulum.c) | <img src="shapes/shapes_double_pendulum.png" alt="shapes_double_pendulum" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) |
|
||||||
| [shapes_dashed_line](shapes/shapes_dashed_line.c) | <img src="shapes/shapes_dashed_line.png" alt="shapes_dashed_line" width="80"> | ⭐☆☆☆ | 5.5 | 5.5 | [Luís Almeida](https://github.com/luis605) |
|
| [shapes_dashed_line](shapes/shapes_dashed_line.c) | <img src="shapes/shapes_dashed_line.png" alt="shapes_dashed_line" width="80"> | ⭐☆☆☆ | 5.5 | 5.5 | [Luís Almeida](https://github.com/luis605) |
|
||||||
| [shapes_triangle_strip](shapes/shapes_triangle_strip.c) | <img src="shapes/shapes_triangle_strip.png" alt="shapes_triangle_strip" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
| [shapes_triangle_strip](shapes/shapes_triangle_strip.c) | <img src="shapes/shapes_triangle_strip.png" alt="shapes_triangle_strip" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Jopestpe](https://github.com/jopestpe) |
|
||||||
| [shapes_vector_angle](shapes/shapes_vector_angle.c) | <img src="shapes/shapes_vector_angle.png" alt="shapes_vector_angle" width="80"> | ⭐⭐☆☆ | 1.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_vector_angle](shapes/shapes_vector_angle.c) | <img src="shapes/shapes_vector_angle.png" alt="shapes_vector_angle" width="80"> | ⭐⭐☆☆ | 1.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shapes_pie_chart](shapes/shapes_pie_chart.c) | <img src="shapes/shapes_pie_chart.png" alt="shapes_pie_chart" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Gideon Serfontein](https://github.com/GideonSerf) |
|
| [shapes_pie_chart](shapes/shapes_pie_chart.c) | <img src="shapes/shapes_pie_chart.png" alt="shapes_pie_chart" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Gideon Serfontein](https://github.com/GideonSerf) |
|
||||||
| [shapes_kaleidoscope](shapes/shapes_kaleidoscope.c) | <img src="shapes/shapes_kaleidoscope.png" alt="shapes_kaleidoscope" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
|
| [shapes_kaleidoscope](shapes/shapes_kaleidoscope.c) | <img src="shapes/shapes_kaleidoscope.png" alt="shapes_kaleidoscope" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
|
||||||
| [shapes_clock_of_clocks](shapes/shapes_clock_of_clocks.c) | <img src="shapes/shapes_clock_of_clocks.png" alt="shapes_clock_of_clocks" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
| [shapes_clock_of_clocks](shapes/shapes_clock_of_clocks.c) | <img src="shapes/shapes_clock_of_clocks.png" alt="shapes_clock_of_clocks" width="80"> | ⭐⭐☆☆ | 5.5 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||||
| [shapes_math_sine_cosine](shapes/shapes_math_sine_cosine.c) | <img src="shapes/shapes_math_sine_cosine.png" alt="shapes_math_sine_cosine" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
| [shapes_math_sine_cosine](shapes/shapes_math_sine_cosine.c) | <img src="shapes/shapes_math_sine_cosine.png" alt="shapes_math_sine_cosine" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Jopestpe](https://github.com/jopestpe) |
|
||||||
| [shapes_mouse_trail](shapes/shapes_mouse_trail.c) | <img src="shapes/shapes_mouse_trail.png" alt="shapes_mouse_trail" width="80"> | ⭐☆☆☆ | 5.6 | 5.6-dev | [Balamurugan R](https://github.com/Bala050814) |
|
| [shapes_mouse_trail](shapes/shapes_mouse_trail.c) | <img src="shapes/shapes_mouse_trail.png" alt="shapes_mouse_trail" width="80"> | ⭐☆☆☆ | 5.6 | 6.0 | [Balamurugan R](https://github.com/Bala050814) |
|
||||||
| [shapes_simple_particles](shapes/shapes_simple_particles.c) | <img src="shapes/shapes_simple_particles.png" alt="shapes_simple_particles" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
| [shapes_simple_particles](shapes/shapes_simple_particles.c) | <img src="shapes/shapes_simple_particles.png" alt="shapes_simple_particles" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||||
| [shapes_starfield_effect](shapes/shapes_starfield_effect.c) | <img src="shapes/shapes_starfield_effect.png" alt="shapes_starfield_effect" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
| [shapes_starfield_effect](shapes/shapes_starfield_effect.c) | <img src="shapes/shapes_starfield_effect.png" alt="shapes_starfield_effect" width="80"> | ⭐⭐☆☆ | 5.5 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||||
| [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | <img src="shapes/shapes_lines_drawing.png" alt="shapes_lines_drawing" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
| [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | <img src="shapes/shapes_lines_drawing.png" alt="shapes_lines_drawing" width="80"> | ⭐☆☆☆ | 6.0 | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
||||||
| [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | <img src="shapes/shapes_math_angle_rotation.png" alt="shapes_math_angle_rotation" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6 | [Kris](https://github.com/krispy-snacc) |
|
| [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | <img src="shapes/shapes_math_angle_rotation.png" alt="shapes_math_angle_rotation" width="80"> | ⭐☆☆☆ | 6.0 | 5.6 | [Kris](https://github.com/krispy-snacc) |
|
||||||
| [shapes_rlgl_color_wheel](shapes/shapes_rlgl_color_wheel.c) | <img src="shapes/shapes_rlgl_color_wheel.png" alt="shapes_rlgl_color_wheel" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
| [shapes_rlgl_color_wheel](shapes/shapes_rlgl_color_wheel.c) | <img src="shapes/shapes_rlgl_color_wheel.png" alt="shapes_rlgl_color_wheel" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||||
| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||||
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [David Buzatto](https://github.com/davidbuzatto) |
|
||||||
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [David Buzatto](https://github.com/davidbuzatto) |
|
||||||
| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | <img src="shapes/shapes_hilbert_curve.png" alt="shapes_hilbert_curve" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | <img src="shapes/shapes_hilbert_curve.png" alt="shapes_hilbert_curve" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
||||||
| [shapes_easings_testbed](shapes/shapes_easings_testbed.c) | <img src="shapes/shapes_easings_testbed.png" alt="shapes_easings_testbed" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Juan Miguel López](https://github.com/flashback-fx) |
|
| [shapes_easings_testbed](shapes/shapes_easings_testbed.c) | <img src="shapes/shapes_easings_testbed.png" alt="shapes_easings_testbed" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||||
|
|
||||||
### category: textures [30]
|
### category: textures [32]
|
||||||
|
|
||||||
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
|
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
|
||||||
|
|
||||||
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
|
| [textures_clipboard_image](textures/textures_clipboard_image.c) | <img src="textures/textures_clipboard_image.png" alt="textures_clipboard_image" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Maicon Santana](https://github.com/maiconpintoabreu) |
|
||||||
|
| [textures_magnifying_glass](textures/textures_magnifying_glass.c) | <img src="textures/textures_magnifying_glass.png" alt="textures_magnifying_glass" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Luke Vaughan](https://github.com/badram) |
|
||||||
| [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐⭐⭐☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐⭐⭐☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐⭐☆☆ | 1.4 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐⭐☆☆ | 1.4 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
@ -155,7 +157,7 @@ Examples using raylib textures functionality, including image/textures loading/g
|
|||||||
| [textures_image_rotate](textures/textures_image_rotate.c) | <img src="textures/textures_image_rotate.png" alt="textures_image_rotate" width="80"> | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [textures_image_rotate](textures/textures_image_rotate.c) | <img src="textures/textures_image_rotate.png" alt="textures_image_rotate" width="80"> | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [textures_screen_buffer](textures/textures_screen_buffer.c) | <img src="textures/textures_screen_buffer.png" alt="textures_screen_buffer" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
| [textures_screen_buffer](textures/textures_screen_buffer.c) | <img src="textures/textures_screen_buffer.png" alt="textures_screen_buffer" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
||||||
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
|
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||||
| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||||
| [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
| [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||||
| [textures_framebuffer_rendering](textures/textures_framebuffer_rendering.c) | <img src="textures/textures_framebuffer_rendering.png" alt="textures_framebuffer_rendering" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jack Boakes](https://github.com/jackboakes) |
|
| [textures_framebuffer_rendering](textures/textures_framebuffer_rendering.c) | <img src="textures/textures_framebuffer_rendering.png" alt="textures_framebuffer_rendering" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jack Boakes](https://github.com/jackboakes) |
|
||||||
|
|
||||||
@ -178,9 +180,9 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
|||||||
| [text_unicode_ranges](text/text_unicode_ranges.c) | <img src="text/text_unicode_ranges.png" alt="text_unicode_ranges" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Vadim Gunko](https://github.com/GuvaCode) |
|
| [text_unicode_ranges](text/text_unicode_ranges.c) | <img src="text/text_unicode_ranges.png" alt="text_unicode_ranges" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Vadim Gunko](https://github.com/GuvaCode) |
|
||||||
| [text_3d_drawing](text/text_3d_drawing.c) | <img src="text/text_3d_drawing.png" alt="text_3d_drawing" width="80"> | ⭐⭐⭐⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
| [text_3d_drawing](text/text_3d_drawing.c) | <img src="text/text_3d_drawing.png" alt="text_3d_drawing" width="80"> | ⭐⭐⭐⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| [text_codepoints_loading](text/text_codepoints_loading.c) | <img src="text/text_codepoints_loading.png" alt="text_codepoints_loading" width="80"> | ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [text_codepoints_loading](text/text_codepoints_loading.c) | <img src="text/text_codepoints_loading.png" alt="text_codepoints_loading" width="80"> | ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [text_inline_styling](text/text_inline_styling.c) | <img src="text/text_inline_styling.png" alt="text_inline_styling" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Wagner Barongello](https://github.com/SultansOfCode) |
|
| [text_inline_styling](text/text_inline_styling.c) | <img src="text/text_inline_styling.png" alt="text_inline_styling" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Wagner Barongello](https://github.com/SultansOfCode) |
|
||||||
| [text_words_alignment](text/text_words_alignment.c) | <img src="text/text_words_alignment.png" alt="text_words_alignment" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
| [text_words_alignment](text/text_words_alignment.c) | <img src="text/text_words_alignment.png" alt="text_words_alignment" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||||
| [text_strings_management](text/text_strings_management.c) | <img src="text/text_strings_management.png" alt="text_strings_management" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
| [text_strings_management](text/text_strings_management.c) | <img src="text/text_strings_management.png" alt="text_strings_management" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [David Buzatto](https://github.com/davidbuzatto) |
|
||||||
|
|
||||||
### category: models [30]
|
### category: models [30]
|
||||||
|
|
||||||
@ -210,22 +212,22 @@ Examples using raylib models functionality, including models loading/generation
|
|||||||
| [models_textured_cube](models/models_textured_cube.c) | <img src="models/models_textured_cube.png" alt="models_textured_cube" width="80"> | ⭐⭐☆☆ | 4.5 | 4.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [models_textured_cube](models/models_textured_cube.c) | <img src="models/models_textured_cube.png" alt="models_textured_cube" width="80"> | ⭐⭐☆☆ | 4.5 | 4.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [models_animation_gpu_skinning](models/models_animation_gpu_skinning.c) | <img src="models/models_animation_gpu_skinning.png" alt="models_animation_gpu_skinning" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Daniel Holden](https://github.com/orangeduck) |
|
| [models_animation_gpu_skinning](models/models_animation_gpu_skinning.c) | <img src="models/models_animation_gpu_skinning.png" alt="models_animation_gpu_skinning" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Daniel Holden](https://github.com/orangeduck) |
|
||||||
| [models_bone_socket](models/models_bone_socket.c) | <img src="models/models_bone_socket.png" alt="models_bone_socket" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
|
| [models_bone_socket](models/models_bone_socket.c) | <img src="models/models_bone_socket.png" alt="models_bone_socket" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
|
||||||
| [models_tesseract_view](models/models_tesseract_view.c) | <img src="models/models_tesseract_view.png" alt="models_tesseract_view" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) |
|
| [models_tesseract_view](models/models_tesseract_view.c) | <img src="models/models_tesseract_view.png" alt="models_tesseract_view" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Timothy van der Valk](https://github.com/arceryz) |
|
||||||
| [models_basic_voxel](models/models_basic_voxel.c) | <img src="models/models_basic_voxel.png" alt="models_basic_voxel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) |
|
| [models_basic_voxel](models/models_basic_voxel.c) | <img src="models/models_basic_voxel.png" alt="models_basic_voxel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) |
|
||||||
| [models_rotating_cube](models/models_rotating_cube.c) | <img src="models/models_rotating_cube.png" alt="models_rotating_cube" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
| [models_rotating_cube](models/models_rotating_cube.c) | <img src="models/models_rotating_cube.png" alt="models_rotating_cube" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Jopestpe](https://github.com/jopestpe) |
|
||||||
| [models_decals](models/models_decals.c) | <img src="models/models_decals.png" alt="models_decals" width="80"> | ⭐⭐⭐⭐️ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
| [models_decals](models/models_decals.c) | <img src="models/models_decals.png" alt="models_decals" width="80"> | ⭐⭐⭐⭐️ | 6.0 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||||
| [models_directional_billboard](models/models_directional_billboard.c) | <img src="models/models_directional_billboard.png" alt="models_directional_billboard" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
| [models_directional_billboard](models/models_directional_billboard.c) | <img src="models/models_directional_billboard.png" alt="models_directional_billboard" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||||
| [models_animation_blend_custom](models/models_animation_blend_custom.c) | <img src="models/models_animation_blend_custom.png" alt="models_animation_blend_custom" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.5 | [dmitrii-brand](https://github.com/dmitrii-brand) |
|
| [models_animation_blend_custom](models/models_animation_blend_custom.c) | <img src="models/models_animation_blend_custom.png" alt="models_animation_blend_custom" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [dmitrii-brand](https://github.com/dmitrii-brand) |
|
||||||
| [models_animation_blending](models/models_animation_blending.c) | <img src="models/models_animation_blending.png" alt="models_animation_blending" width="80"> | ☆☆☆☆ | 5.5 | 5.6-dev | [Kirandeep](https://github.com/Kirandeep-Singh-Khehra) |
|
| [models_animation_blending](models/models_animation_blending.c) | <img src="models/models_animation_blending.png" alt="models_animation_blending" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [Kirandeep](https://github.com/Kirandeep-Singh-Khehra) |
|
||||||
| [models_animation_timming](models/models_animation_timming.c) | <img src="models/models_animation_timming.png" alt="models_animation_timming" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [models_animation_timing](models/models_animation_timing.c) | <img src="models/models_animation_timing.png" alt="models_animation_timing" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
|
||||||
### category: shaders [34]
|
### category: shaders [35]
|
||||||
|
|
||||||
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module.
|
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.h) module.
|
||||||
|
|
||||||
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
| [shaders_ascii_rendering](shaders/shaders_ascii_rendering.c) | <img src="shaders/shaders_ascii_rendering.png" alt="shaders_ascii_rendering" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Maicon Santana](https://github.com/maiconpintoabreu) |
|
| [shaders_ascii_rendering](shaders/shaders_ascii_rendering.c) | <img src="shaders/shaders_ascii_rendering.png" alt="shaders_ascii_rendering" width="80"> | ⭐⭐☆☆ | 5.5 | 6.0 | [Maicon Santana](https://github.com/maiconpintoabreu) |
|
||||||
| [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐⭐⭐⭐️ | 3.0 | 4.2 | [Chris Camacho](https://github.com/chriscamacho) |
|
| [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐⭐⭐⭐️ | 3.0 | 4.2 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||||
| [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐⭐☆☆ | 1.3 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐⭐☆☆ | 1.3 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐⭐☆☆ | 1.7 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐⭐☆☆ | 1.7 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
@ -237,15 +239,15 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
|||||||
| [shaders_texture_outline](shaders/shaders_texture_outline.c) | <img src="shaders/shaders_texture_outline.png" alt="shaders_texture_outline" width="80"> | ⭐⭐⭐☆ | 4.0 | 4.0 | [Serenity Skiff](https://github.com/GoldenThumbs) |
|
| [shaders_texture_outline](shaders/shaders_texture_outline.c) | <img src="shaders/shaders_texture_outline.png" alt="shaders_texture_outline" width="80"> | ⭐⭐⭐☆ | 4.0 | 4.0 | [Serenity Skiff](https://github.com/GoldenThumbs) |
|
||||||
| [shaders_texture_waves](shaders/shaders_texture_waves.c) | <img src="shaders/shaders_texture_waves.png" alt="shaders_texture_waves" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) |
|
| [shaders_texture_waves](shaders/shaders_texture_waves.c) | <img src="shaders/shaders_texture_waves.png" alt="shaders_texture_waves" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) |
|
||||||
| [shaders_julia_set](shaders/shaders_julia_set.c) | <img src="shaders/shaders_julia_set.png" alt="shaders_julia_set" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [Josh Colclough](https://github.com/joshcol9232) |
|
| [shaders_julia_set](shaders/shaders_julia_set.c) | <img src="shaders/shaders_julia_set.png" alt="shaders_julia_set" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [Josh Colclough](https://github.com/joshcol9232) |
|
||||||
| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | <img src="shaders/shaders_mandelbrot_set.png" alt="shaders_mandelbrot_set" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | <img src="shaders/shaders_mandelbrot_set.png" alt="shaders_mandelbrot_set" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Jordi Santonja](https://github.com/JordSant) |
|
||||||
| [shaders_color_correction](shaders/shaders_color_correction.c) | <img src="shaders/shaders_color_correction.png" alt="shaders_color_correction" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
| [shaders_color_correction](shaders/shaders_color_correction.c) | <img src="shaders/shaders_color_correction.png" alt="shaders_color_correction" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Jordi Santonja](https://github.com/JordSant) |
|
||||||
| [shaders_eratosthenes_sieve](shaders/shaders_eratosthenes_sieve.c) | <img src="shaders/shaders_eratosthenes_sieve.png" alt="shaders_eratosthenes_sieve" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [ProfJski](https://github.com/ProfJski) |
|
| [shaders_eratosthenes_sieve](shaders/shaders_eratosthenes_sieve.c) | <img src="shaders/shaders_eratosthenes_sieve.png" alt="shaders_eratosthenes_sieve" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [ProfJski](https://github.com/ProfJski) |
|
||||||
| [shaders_fog_rendering](shaders/shaders_fog_rendering.c) | <img src="shaders/shaders_fog_rendering.png" alt="shaders_fog_rendering" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
| [shaders_fog_rendering](shaders/shaders_fog_rendering.c) | <img src="shaders/shaders_fog_rendering.png" alt="shaders_fog_rendering" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||||
| [shaders_simple_mask](shaders/shaders_simple_mask.c) | <img src="shaders/shaders_simple_mask.png" alt="shaders_simple_mask" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
| [shaders_simple_mask](shaders/shaders_simple_mask.c) | <img src="shaders/shaders_simple_mask.png" alt="shaders_simple_mask" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||||
| [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐⭐⭐☆ | 3.0 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐⭐⭐☆ | 3.0 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐⭐⭐⭐️ | 3.7 | 4.2 | [seanpringle](https://github.com/seanpringle) |
|
| [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐⭐⭐⭐️ | 3.7 | 4.2 | [seanpringle](https://github.com/seanpringle) |
|
||||||
| [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐⭐☆☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐⭐☆☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shaders_normalmap_rendering](shaders/shaders_normalmap_rendering.c) | <img src="shaders/shaders_normalmap_rendering.png" alt="shaders_normalmap_rendering" width="80"> | ⭐⭐⭐⭐️ | 5.6 | 5.6 | [Jeremy Montgomery](https://github.com/Sir_Irk) |
|
| [shaders_normalmap_rendering](shaders/shaders_normalmap_rendering.c) | <img src="shaders/shaders_normalmap_rendering.png" alt="shaders_normalmap_rendering" width="80"> | ⭐⭐⭐⭐️ | 6.0 | 6.0 | [Jeremy Montgomery](https://github.com/Sir_Irk) |
|
||||||
| [shaders_spotlight_rendering](shaders/shaders_spotlight_rendering.c) | <img src="shaders/shaders_spotlight_rendering.png" alt="shaders_spotlight_rendering" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
| [shaders_spotlight_rendering](shaders/shaders_spotlight_rendering.c) | <img src="shaders/shaders_spotlight_rendering.png" alt="shaders_spotlight_rendering" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||||
| [shaders_deferred_rendering](shaders/shaders_deferred_rendering.c) | <img src="shaders/shaders_deferred_rendering.png" alt="shaders_deferred_rendering" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
|
| [shaders_deferred_rendering](shaders/shaders_deferred_rendering.c) | <img src="shaders/shaders_deferred_rendering.png" alt="shaders_deferred_rendering" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
|
||||||
| [shaders_hybrid_rendering](shaders/shaders_hybrid_rendering.c) | <img src="shaders/shaders_hybrid_rendering.png" alt="shaders_hybrid_rendering" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
|
| [shaders_hybrid_rendering](shaders/shaders_hybrid_rendering.c) | <img src="shaders/shaders_hybrid_rendering.png" alt="shaders_hybrid_rendering" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
|
||||||
@ -256,11 +258,12 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
|||||||
| [shaders_basic_pbr](shaders/shaders_basic_pbr.c) | <img src="shaders/shaders_basic_pbr.png" alt="shaders_basic_pbr" width="80"> | ⭐⭐⭐⭐️ | 5.0 | 5.5 | [Afan OLOVCIC](https://github.com/_DevDad) |
|
| [shaders_basic_pbr](shaders/shaders_basic_pbr.c) | <img src="shaders/shaders_basic_pbr.png" alt="shaders_basic_pbr" width="80"> | ⭐⭐⭐⭐️ | 5.0 | 5.5 | [Afan OLOVCIC](https://github.com/_DevDad) |
|
||||||
| [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) | <img src="shaders/shaders_lightmap_rendering.png" alt="shaders_lightmap_rendering" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
|
| [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) | <img src="shaders/shaders_lightmap_rendering.png" alt="shaders_lightmap_rendering" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
|
||||||
| [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) | <img src="shaders/shaders_rounded_rectangle.png" alt="shaders_rounded_rectangle" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) |
|
| [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) | <img src="shaders/shaders_rounded_rectangle.png" alt="shaders_rounded_rectangle" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) |
|
||||||
| [shaders_depth_rendering](shaders/shaders_depth_rendering.c) | <img src="shaders/shaders_depth_rendering.png" alt="shaders_depth_rendering" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) |
|
| [shaders_depth_rendering](shaders/shaders_depth_rendering.c) | <img src="shaders/shaders_depth_rendering.png" alt="shaders_depth_rendering" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Luís Almeida](https://github.com/luis605) |
|
||||||
| [shaders_game_of_life](shaders/shaders_game_of_life.c) | <img src="shaders/shaders_game_of_life.png" alt="shaders_game_of_life" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
| [shaders_game_of_life](shaders/shaders_game_of_life.c) | <img src="shaders/shaders_game_of_life.png" alt="shaders_game_of_life" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Jordi Santonja](https://github.com/JordSant) |
|
||||||
| [shaders_rlgl_compute](shaders/shaders_rlgl_compute.c) | <img src="shaders/shaders_rlgl_compute.png" alt="shaders_rlgl_compute" width="80"> | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
|
| [shaders_rlgl_compute](shaders/shaders_rlgl_compute.c) | <img src="shaders/shaders_rlgl_compute.png" alt="shaders_rlgl_compute" width="80"> | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
|
||||||
|
| [shaders_cel_shading](shaders/shaders_cel_shading.c) | <img src="shaders/shaders_cel_shading.png" alt="shaders_cel_shading" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Gleb A](https://github.com/ggrizzly) |
|
||||||
|
|
||||||
### category: audio [9]
|
### category: audio [10]
|
||||||
|
|
||||||
Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib.
|
Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib.
|
||||||
|
|
||||||
@ -268,13 +271,14 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
|||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
| [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐☆☆☆ | 1.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐☆☆☆ | 1.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐☆☆☆ | 1.3 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐☆☆☆ | 1.3 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐⭐⭐☆ | 1.6 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐⭐⭐☆ | 1.6 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐☆☆☆ | 1.1 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐☆☆☆ | 1.1 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [audio_mixed_processor](audio/audio_mixed_processor.c) | <img src="audio/audio_mixed_processor.png" alt="audio_mixed_processor" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [hkc](https://github.com/hatkidchan) |
|
| [audio_mixed_processor](audio/audio_mixed_processor.c) | <img src="audio/audio_mixed_processor.png" alt="audio_mixed_processor" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [hkc](https://github.com/hatkidchan) |
|
||||||
| [audio_stream_effects](audio/audio_stream_effects.c) | <img src="audio/audio_stream_effects.png" alt="audio_stream_effects" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [audio_stream_effects](audio/audio_stream_effects.c) | <img src="audio/audio_stream_effects.png" alt="audio_stream_effects" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [audio_sound_multi](audio/audio_sound_multi.c) | <img src="audio/audio_sound_multi.png" alt="audio_sound_multi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [Jeffery Myers](https://github.com/JeffM2501) |
|
| [audio_sound_multi](audio/audio_sound_multi.c) | <img src="audio/audio_sound_multi.png" alt="audio_sound_multi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||||
| [audio_sound_positioning](audio/audio_sound_positioning.c) | <img src="audio/audio_sound_positioning.png" alt="audio_sound_positioning" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
|
| [audio_sound_positioning](audio/audio_sound_positioning.c) | <img src="audio/audio_sound_positioning.png" alt="audio_sound_positioning" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
|
||||||
| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | <img src="audio/audio_spectrum_visualizer.png" alt="audio_spectrum_visualizer" width="80"> | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) |
|
| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | <img src="audio/audio_spectrum_visualizer.png" alt="audio_spectrum_visualizer" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [IANN](https://github.com/meisei4) |
|
||||||
|
| [audio_stream_callback](audio/audio_stream_callback.c) | <img src="audio/audio_stream_callback.png" alt="audio_stream_callback" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Dan Hoang](https://github.com/dan-hoang) |
|
||||||
|
|
||||||
Some example missing? As always, contributions are welcome, feel free to send new examples!
|
Some example missing? As always, contributions are welcome, feel free to send new examples!
|
||||||
Here is an [examples template](examples_template.c) with instructions to start with!
|
Here is an [examples template](examples_template.c) with instructions to start with!
|
||||||
|
|||||||
238
examples/audio/audio_amp_envelope.c
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [audio] example - amp envelope
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
|
*
|
||||||
|
* Example contributed by Arbinda Rizki Muhammad (@arbipink) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2026 Arbinda Rizki Muhammad (@arbipink)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "raygui.h"
|
||||||
|
|
||||||
|
#include <math.h> // Required for: sinf()
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 4096
|
||||||
|
#define SAMPLE_RATE 44100
|
||||||
|
|
||||||
|
// Wave state
|
||||||
|
typedef enum {
|
||||||
|
IDLE,
|
||||||
|
ATTACK,
|
||||||
|
DECAY,
|
||||||
|
SUSTAIN,
|
||||||
|
RELEASE
|
||||||
|
} ADSRState;
|
||||||
|
|
||||||
|
// Grouping all ADSR parameters and state into a struct
|
||||||
|
typedef struct {
|
||||||
|
float attackTime;
|
||||||
|
float decayTime;
|
||||||
|
float sustainLevel;
|
||||||
|
float releaseTime;
|
||||||
|
float currentValue;
|
||||||
|
ADSRState state;
|
||||||
|
} Envelope;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime);
|
||||||
|
static void UpdateEnvelope(Envelope *env);
|
||||||
|
static void DrawADSRGraph(Envelope *env, Rectangle bounds);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [audio] example - amp envelope");
|
||||||
|
|
||||||
|
InitAudioDevice();
|
||||||
|
|
||||||
|
// Set the number of samples the stream will keep in memory at a time to BUFFER_SIZE
|
||||||
|
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
|
||||||
|
float buffer[BUFFER_SIZE] = { 0 };
|
||||||
|
|
||||||
|
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
|
||||||
|
AudioStream stream = LoadAudioStream(SAMPLE_RATE, 32, 1);
|
||||||
|
|
||||||
|
// Init Phase
|
||||||
|
float audioTime = 0.0f;
|
||||||
|
|
||||||
|
// Initialize the struct
|
||||||
|
Envelope env = {
|
||||||
|
.attackTime = 1.0f,
|
||||||
|
.decayTime = 1.0f,
|
||||||
|
.sustainLevel = 0.5f,
|
||||||
|
.releaseTime = 1.0f,
|
||||||
|
.currentValue = 0.0f,
|
||||||
|
.state = IDLE
|
||||||
|
};
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose())
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) env.state = ATTACK;
|
||||||
|
|
||||||
|
if (IsKeyReleased(KEY_SPACE) && (env.state != IDLE)) env.state = RELEASE;
|
||||||
|
|
||||||
|
if (IsAudioStreamProcessed(stream))
|
||||||
|
{
|
||||||
|
if ((env.state != IDLE) || (env.currentValue > 0.0f))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||||
|
{
|
||||||
|
UpdateEnvelope(&env);
|
||||||
|
FillAudioBuffer(i, buffer, env.currentValue, &audioTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clear buffer if silent to avoid looping noise
|
||||||
|
for (int i = 0; i < BUFFER_SIZE; i++) buffer[i] = 0;
|
||||||
|
audioTime = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAudioStream(stream, buffer, BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsAudioStreamPlaying(stream)) PlayAudioStream(stream);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
GuiSliderBar((Rectangle){ 100, 60, 400, 30 }, "Attack (s)", TextFormat("%2.2fs", env.attackTime), &env.attackTime, 0.1f, 3.0f);
|
||||||
|
GuiSliderBar((Rectangle){ 100, 100, 400, 30 }, "Decay (s)", TextFormat("%2.2fs", env.decayTime), &env.decayTime, 0.1f, 3.0f);
|
||||||
|
GuiSliderBar((Rectangle){ 100, 140, 400, 30 }, "Sustain", TextFormat("%2.2f", env.sustainLevel), &env.sustainLevel, 0.0f, 1.0f);
|
||||||
|
GuiSliderBar((Rectangle){ 100, 180, 400, 30 }, "Release (s)", TextFormat("%2.2fs", env.releaseTime), &env.releaseTime, 0.1f, 3.0f);
|
||||||
|
|
||||||
|
DrawADSRGraph(&env, (Rectangle){ 100, 250, 400, 100 });
|
||||||
|
|
||||||
|
DrawCircleV((Vector2){ 520, 350 - (env.currentValue * 100) }, 5, MAROON);
|
||||||
|
DrawText(TextFormat("Current Gain: %2.2f", env.currentValue), 535, 345 - (env.currentValue * 100), 10, MAROON);
|
||||||
|
|
||||||
|
DrawText("Press SPACE to PLAY the sound!", 200, 400, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadAudioStream(stream);
|
||||||
|
CloseAudioDevice();
|
||||||
|
|
||||||
|
CloseWindow();
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime)
|
||||||
|
{
|
||||||
|
int frequency = 440;
|
||||||
|
buffer[i] = envelopeValue*sinf(2.0f*PI*frequency*(*audioTime));
|
||||||
|
*audioTime += (1.0f/SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateEnvelope(Envelope *env)
|
||||||
|
{
|
||||||
|
// Calculate the time delta for ONE sample (1/44100)
|
||||||
|
float sampleTime = 1.0f/SAMPLE_RATE;
|
||||||
|
|
||||||
|
switch(env->state)
|
||||||
|
{
|
||||||
|
case ATTACK:
|
||||||
|
{
|
||||||
|
env->currentValue += (1.0f/env->attackTime)*sampleTime;
|
||||||
|
if (env->currentValue >= 1.0f)
|
||||||
|
{
|
||||||
|
env->currentValue = 1.0f;
|
||||||
|
env->state = DECAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case DECAY:
|
||||||
|
{
|
||||||
|
env->currentValue -= ((1.0f - env->sustainLevel)/env->decayTime)*sampleTime;
|
||||||
|
if (env->currentValue <= env->sustainLevel)
|
||||||
|
{
|
||||||
|
env->currentValue = env->sustainLevel;
|
||||||
|
env->state = SUSTAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case SUSTAIN:
|
||||||
|
{
|
||||||
|
env->currentValue = env->sustainLevel;
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case RELEASE:
|
||||||
|
{
|
||||||
|
env->currentValue -= (env->sustainLevel/env->releaseTime)*sampleTime;
|
||||||
|
if (env->currentValue <= 0.001f) // Use a small threshold to avoid infinite tail
|
||||||
|
{
|
||||||
|
env->currentValue = 0.0f;
|
||||||
|
env->state = IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawADSRGraph(Envelope *env, Rectangle bounds)
|
||||||
|
{
|
||||||
|
DrawRectangleRec(bounds, Fade(LIGHTGRAY, 0.3f));
|
||||||
|
DrawRectangleLinesEx(bounds, 1, GRAY);
|
||||||
|
|
||||||
|
// Fixed visual width for sustain stage since it's an amplitude not a time value
|
||||||
|
float sustainWidth = 1.0f;
|
||||||
|
|
||||||
|
// Total time to visualize (sum of A, D, R + a padding for Sustain)
|
||||||
|
float totalTime = env->attackTime + env->decayTime + sustainWidth + env->releaseTime;
|
||||||
|
|
||||||
|
float scaleX = bounds.width/totalTime;
|
||||||
|
float scaleY = bounds.height;
|
||||||
|
|
||||||
|
Vector2 start = { bounds.x, bounds.y + bounds.height };
|
||||||
|
Vector2 peak = { start.x + (env->attackTime*scaleX), bounds.y };
|
||||||
|
Vector2 sustain = { peak.x + (env->decayTime*scaleX), bounds.y + (1.0f - env->sustainLevel)*scaleY };
|
||||||
|
Vector2 rel = { sustain.x + (sustainWidth*scaleX), sustain.y };
|
||||||
|
Vector2 end = { rel.x + (env->releaseTime*scaleX), bounds.y + bounds.height };
|
||||||
|
|
||||||
|
DrawLineV(start, peak, SKYBLUE);
|
||||||
|
DrawLineV(peak, sustain, BLUE);
|
||||||
|
DrawLineV(sustain, rel, DARKBLUE);
|
||||||
|
DrawLineV(rel, end, ORANGE);
|
||||||
|
|
||||||
|
DrawText("ADSR Visualizer", bounds.x, bounds.y - 20, 10, DARKGRAY);
|
||||||
|
}
|
||||||
BIN
examples/audio/audio_amp_envelope.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
@ -4,53 +4,22 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★★☆] 3/4
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 1.6, last time updated with raylib 4.2
|
* Example originally created with raylib 1.6, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example created by Ramon Santamaria (@raysan5) and reviewed by James Hofmann (@triplefox)
|
* Example created by Ramon Santamaria (@raysan5) and reviewed by James Hofmann (@triplefox)
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
|
* Copyright (c) 2015-2026 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: malloc(), free()
|
#define BUFFER_SIZE 4096
|
||||||
#include <math.h> // Required for: sinf()
|
#define SAMPLE_RATE 44100
|
||||||
#include <string.h> // Required for: memcpy()
|
|
||||||
|
|
||||||
#define MAX_SAMPLES 512
|
|
||||||
#define MAX_SAMPLES_PER_UPDATE 4096
|
|
||||||
|
|
||||||
// Cycles per second (hz)
|
|
||||||
float frequency = 440.0f;
|
|
||||||
|
|
||||||
// Audio frequency, for smoothing
|
|
||||||
float audioFrequency = 440.0f;
|
|
||||||
|
|
||||||
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
|
|
||||||
float oldFrequency = 1.0f;
|
|
||||||
|
|
||||||
// Index for audio rendering
|
|
||||||
float sineIdx = 0.0f;
|
|
||||||
|
|
||||||
// Audio input processing callback
|
|
||||||
void AudioInputCallback(void *buffer, unsigned int frames)
|
|
||||||
{
|
|
||||||
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
|
|
||||||
|
|
||||||
float incr = audioFrequency/44100.0f;
|
|
||||||
short *d = (short *)buffer;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < frames; i++)
|
|
||||||
{
|
|
||||||
d[i] = (short)(32000.0f*sinf(2*PI*sineIdx));
|
|
||||||
sineIdx += incr;
|
|
||||||
if (sineIdx > 1.0f) sineIdx -= 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
@ -64,43 +33,24 @@ int main(void)
|
|||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream");
|
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream");
|
||||||
|
|
||||||
InitAudioDevice(); // Initialize audio device
|
InitAudioDevice();
|
||||||
|
|
||||||
SetAudioStreamBufferSizeDefault(MAX_SAMPLES_PER_UPDATE);
|
// Set the number of samples the stream will keep in memory at a time to BUFFER_SIZE
|
||||||
|
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
|
||||||
|
float buffer[BUFFER_SIZE] = {};
|
||||||
|
|
||||||
// Init raw audio stream (sample rate: 44100, sample size: 16bit-short, channels: 1-mono)
|
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
|
||||||
AudioStream stream = LoadAudioStream(44100, 16, 1);
|
AudioStream stream = LoadAudioStream(SAMPLE_RATE, 32, 1);
|
||||||
|
float pan = 0.0f;
|
||||||
|
SetAudioStreamPan(stream, pan);
|
||||||
|
PlayAudioStream(stream);
|
||||||
|
|
||||||
SetAudioStreamCallback(stream, AudioInputCallback);
|
int sineFrequency = 440;
|
||||||
|
int newSineFrequency = 440;
|
||||||
|
int sineIndex = 0;
|
||||||
|
double sineStartTime = 0.0;
|
||||||
|
|
||||||
// Buffer for the single cycle waveform we are synthesizing
|
SetTargetFPS(30);
|
||||||
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
|
|
||||||
|
|
||||||
// Frame buffer, describing the waveform when repeated over the course of a frame
|
|
||||||
short *writeBuf = (short *)malloc(sizeof(short)*MAX_SAMPLES_PER_UPDATE);
|
|
||||||
|
|
||||||
PlayAudioStream(stream); // Start processing stream buffer (no data loaded currently)
|
|
||||||
|
|
||||||
// Position read in to determine next frequency
|
|
||||||
Vector2 mousePosition = { -100.0f, -100.0f };
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Cycles per second (hz)
|
|
||||||
float frequency = 440.0f;
|
|
||||||
|
|
||||||
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
|
|
||||||
float oldFrequency = 1.0f;
|
|
||||||
|
|
||||||
// Cursor to read and copy the samples of the sine wave buffer
|
|
||||||
int readCursor = 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Computed size in samples of the sine wave
|
|
||||||
int waveLength = 1;
|
|
||||||
|
|
||||||
Vector2 position = { 0, 0 };
|
|
||||||
|
|
||||||
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
@ -108,91 +58,76 @@ int main(void)
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
mousePosition = GetMousePosition();
|
|
||||||
|
|
||||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
|
if (IsKeyDown(KEY_UP))
|
||||||
{
|
{
|
||||||
float fp = (float)(mousePosition.y);
|
newSineFrequency += 10;
|
||||||
frequency = 40.0f + (float)(fp);
|
if (newSineFrequency > 12500) newSineFrequency = 12500;
|
||||||
|
}
|
||||||
|
|
||||||
float pan = (float)(mousePosition.x)/(float)screenWidth;
|
if (IsKeyDown(KEY_DOWN))
|
||||||
|
{
|
||||||
|
newSineFrequency -= 10;
|
||||||
|
if (newSineFrequency < 20) newSineFrequency = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyDown(KEY_LEFT))
|
||||||
|
{
|
||||||
|
pan -= 0.01f;
|
||||||
|
if (pan < -1.0f) pan = -1.0f;
|
||||||
SetAudioStreamPan(stream, pan);
|
SetAudioStreamPan(stream, pan);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite the sine wave
|
if (IsKeyDown(KEY_RIGHT))
|
||||||
// Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc.
|
|
||||||
if (frequency != oldFrequency)
|
|
||||||
{
|
{
|
||||||
// Compute wavelength. Limit size in both directions
|
pan += 0.01f;
|
||||||
//int oldWavelength = waveLength;
|
if (pan > 1.0f) pan = 1.0f;
|
||||||
waveLength = (int)(22050/frequency);
|
SetAudioStreamPan(stream, pan);
|
||||||
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
|
|
||||||
if (waveLength < 1) waveLength = 1;
|
|
||||||
|
|
||||||
// Write sine wave
|
|
||||||
for (int i = 0; i < waveLength*2; i++)
|
|
||||||
{
|
|
||||||
data[i] = (short)(sinf(((2*PI*(float)i/waveLength)))*32000);
|
|
||||||
}
|
|
||||||
// Make sure the rest of the line is flat
|
|
||||||
for (int j = waveLength*2; j < MAX_SAMPLES; j++)
|
|
||||||
{
|
|
||||||
data[j] = (short)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale read cursor's position to minimize transition artifacts
|
|
||||||
//readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
|
|
||||||
oldFrequency = frequency;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Refill audio stream if required
|
|
||||||
if (IsAudioStreamProcessed(stream))
|
if (IsAudioStreamProcessed(stream))
|
||||||
{
|
{
|
||||||
// Synthesize a buffer that is exactly the requested size
|
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||||
int writeCursor = 0;
|
|
||||||
|
|
||||||
while (writeCursor < MAX_SAMPLES_PER_UPDATE)
|
|
||||||
{
|
{
|
||||||
// Start by trying to write the whole chunk at once
|
int wavelength = SAMPLE_RATE/sineFrequency;
|
||||||
int writeLength = MAX_SAMPLES_PER_UPDATE-writeCursor;
|
buffer[i] = sin(2*PI*sineIndex/wavelength);
|
||||||
|
sineIndex++;
|
||||||
|
|
||||||
// Limit to the maximum readable size
|
if (sineIndex >= wavelength)
|
||||||
int readLength = waveLength-readCursor;
|
{
|
||||||
|
sineFrequency = newSineFrequency;
|
||||||
if (writeLength > readLength) writeLength = readLength;
|
sineIndex = 0;
|
||||||
|
sineStartTime = GetTime();
|
||||||
// Write the slice
|
}
|
||||||
memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short));
|
|
||||||
|
|
||||||
// Update cursors and loop audio
|
|
||||||
readCursor = (readCursor + writeLength)%waveLength;
|
|
||||||
|
|
||||||
writeCursor += writeLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy finished frame to audio stream
|
UpdateAudioStream(stream, buffer, BUFFER_SIZE);
|
||||||
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
DrawText(TextFormat("sine frequency: %i",(int)frequency), GetScreenWidth() - 220, 10, 20, RED);
|
DrawText(TextFormat("sine frequency: %i", sineFrequency), screenWidth - 220, 10, 20, RED);
|
||||||
DrawText("click mouse button to change frequency or pan", 10, 10, 20, DARKGRAY);
|
DrawText(TextFormat("pan: %.2f", pan), screenWidth - 220, 30, 20, RED);
|
||||||
|
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
|
||||||
|
DrawText("Left/right to pan", 10, 30, 20, DARKGRAY);
|
||||||
|
|
||||||
// Draw the current buffer state proportionate to the screen
|
int windowStart = (GetTime() - sineStartTime)*SAMPLE_RATE;
|
||||||
|
int windowSize = 0.1f*SAMPLE_RATE;
|
||||||
|
int wavelength = SAMPLE_RATE/sineFrequency;
|
||||||
|
|
||||||
|
// Draw a sine wave with the same frequency as the one being sent to the audio stream
|
||||||
for (int i = 0; i < screenWidth; i++)
|
for (int i = 0; i < screenWidth; i++)
|
||||||
{
|
{
|
||||||
position.x = (float)i;
|
int t0 = windowStart + i*windowSize/screenWidth;
|
||||||
position.y = 250 + 50*data[i*MAX_SAMPLES/screenWidth]/32000.0f;
|
int t1 = windowStart + (i + 1)*windowSize/screenWidth;
|
||||||
|
Vector2 startPos = { i, 250 + 50*sin(2*PI*t0/wavelength) };
|
||||||
DrawPixelV(position, RED);
|
Vector2 endPos = { i + 1, 250 + 50*sin(2*PI*t1/wavelength) };
|
||||||
|
DrawLineV(startPos, endPos, RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
@ -201,9 +136,6 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
free(data); // Unload sine wave data
|
|
||||||
free(writeBuf); // Unload write buffer
|
|
||||||
|
|
||||||
UnloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
|
UnloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
|
||||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★★☆] 3/4
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 6.0, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Inspired by Inigo Quilez's https://www.shadertoy.com/
|
* Inspired by Inigo Quilez's https://www.shadertoy.com/
|
||||||
* Resources/specification: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8
|
* Resources/specification: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8
|
||||||
@ -115,7 +115,7 @@ int main(void)
|
|||||||
.tapbackPos = 0.01f
|
.tapbackPos = 0.01f
|
||||||
};
|
};
|
||||||
|
|
||||||
int wavCursor = 0;
|
unsigned int wavCursor = 0;
|
||||||
const short *wavPCM16 = wav.data;
|
const short *wavPCM16 = wav.data;
|
||||||
|
|
||||||
short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 };
|
short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 };
|
||||||
@ -274,8 +274,8 @@ static void CaptureFrame(FFTData *fftData, const float *audioSamples)
|
|||||||
|
|
||||||
static void RenderFrame(const FFTData *fftData, Image *fftImage)
|
static void RenderFrame(const FFTData *fftData, Image *fftImage)
|
||||||
{
|
{
|
||||||
double framesSinceTapback = floor(fftData->tapbackPos/WINDOW_TIME);
|
float framesSinceTapback = floorf((float)(fftData->tapbackPos/WINDOW_TIME));
|
||||||
framesSinceTapback = Clamp(framesSinceTapback, 0.0, fftData->fftHistoryLen - 1);
|
framesSinceTapback = Clamp(framesSinceTapback, 0.0f, (float)(fftData->fftHistoryLen - 1));
|
||||||
|
|
||||||
int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback)%fftData->fftHistoryLen;
|
int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback)%fftData->fftHistoryLen;
|
||||||
if (historyPosition < 0) historyPosition += fftData->fftHistoryLen;
|
if (historyPosition < 0) historyPosition += fftData->fftHistoryLen;
|
||||||
|
|||||||
246
examples/audio/audio_stream_callback.c
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [audio] example - stream callback
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
|
*
|
||||||
|
* Example created by Dan Hoang (@dan-hoang) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* NOTE: Example sends a wave to the audio device,
|
||||||
|
* user gets the choice of four waves: sine, square, triangle, and sawtooth
|
||||||
|
* A stream is set up to play to the audio device; stream is hooked to a callback that
|
||||||
|
* generates a wave, that is determined by user choice
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2026 Dan Hoang (@dan-hoang)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 4096
|
||||||
|
#define SAMPLE_RATE 44100
|
||||||
|
|
||||||
|
// Wave type
|
||||||
|
typedef enum {
|
||||||
|
SINE,
|
||||||
|
SQUARE,
|
||||||
|
TRIANGLE,
|
||||||
|
SAWTOOTH
|
||||||
|
} WaveType;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static void SineCallback(void *framesOut, unsigned int frameCount);
|
||||||
|
static void SquareCallback(void *framesOut, unsigned int frameCount);
|
||||||
|
static void TriangleCallback(void *framesOut, unsigned int frameCount);
|
||||||
|
static void SawtoothCallback(void *framesOut, unsigned int frameCount);
|
||||||
|
|
||||||
|
static int waveFrequency = 440;
|
||||||
|
static int newWaveFrequency = 440;
|
||||||
|
static int waveIndex = 0;
|
||||||
|
|
||||||
|
// Buffer to keep the last second of uploaded audio,
|
||||||
|
// part of which will be drawn on the screen
|
||||||
|
static float buffer[SAMPLE_RATE] = { 0 };
|
||||||
|
static AudioCallback waveCallbacks[] = { SineCallback, SquareCallback, TriangleCallback, SawtoothCallback };
|
||||||
|
static char *waveTypesAsString[] = { "sine", "square", "triangle", "sawtooth" };
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [audio] example - stream callback");
|
||||||
|
|
||||||
|
InitAudioDevice();
|
||||||
|
|
||||||
|
// Set the number of samples the stream will keep in memory at a time to BUFFER_SIZE
|
||||||
|
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
|
||||||
|
|
||||||
|
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
|
||||||
|
AudioStream stream = LoadAudioStream(SAMPLE_RATE, 32, 1);
|
||||||
|
PlayAudioStream(stream);
|
||||||
|
|
||||||
|
// Configure it so that waveCallbacks[waveType] is called whenever stream is out of samples
|
||||||
|
WaveType waveType = SINE;
|
||||||
|
SetAudioStreamCallback(stream, waveCallbacks[waveType]);
|
||||||
|
|
||||||
|
SetTargetFPS(30);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (IsKeyDown(KEY_UP))
|
||||||
|
{
|
||||||
|
newWaveFrequency += 10;
|
||||||
|
if (newWaveFrequency > 12500) newWaveFrequency = 12500;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyDown(KEY_DOWN))
|
||||||
|
{
|
||||||
|
newWaveFrequency -= 10;
|
||||||
|
if (newWaveFrequency < 20) newWaveFrequency = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_LEFT))
|
||||||
|
{
|
||||||
|
if (waveType == SINE) waveType = SAWTOOTH;
|
||||||
|
else if (waveType == SQUARE) waveType = SINE;
|
||||||
|
else if (waveType == TRIANGLE) waveType = SQUARE;
|
||||||
|
else waveType = TRIANGLE;
|
||||||
|
|
||||||
|
SetAudioStreamCallback(stream, waveCallbacks[waveType]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_RIGHT))
|
||||||
|
{
|
||||||
|
if (waveType == SINE) waveType = SQUARE;
|
||||||
|
else if (waveType == SQUARE) waveType = TRIANGLE;
|
||||||
|
else if (waveType == TRIANGLE) waveType = SAWTOOTH;
|
||||||
|
else waveType = SINE;
|
||||||
|
|
||||||
|
SetAudioStreamCallback(stream, waveCallbacks[waveType]);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
DrawText(TextFormat("frequency: %i", newWaveFrequency), screenWidth - 220, 10, 20, RED);
|
||||||
|
DrawText(TextFormat("wave type: %s", waveTypesAsString[waveType]), screenWidth - 220, 30, 20, RED);
|
||||||
|
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
|
||||||
|
DrawText("Left/right to change wave type", 10, 30, 20, DARKGRAY);
|
||||||
|
|
||||||
|
// Draw the last 10 ms of uploaded audio
|
||||||
|
for (int i = 0; i < screenWidth; i++)
|
||||||
|
{
|
||||||
|
Vector2 startPos = { i, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + i*SAMPLE_RATE/100/screenWidth] };
|
||||||
|
Vector2 endPos = { i + 1, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + (i + 1)*SAMPLE_RATE/100/screenWidth] };
|
||||||
|
DrawLineV(startPos, endPos, RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
|
||||||
|
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static void SineCallback(void *framesOut, unsigned int frameCount)
|
||||||
|
{
|
||||||
|
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||||
|
|
||||||
|
// Synthesize the sine wave
|
||||||
|
for (int i = 0; i < frameCount; i++)
|
||||||
|
{
|
||||||
|
((float *)framesOut)[i] = sin(2*PI*waveIndex/wavelength);
|
||||||
|
|
||||||
|
waveIndex++;
|
||||||
|
|
||||||
|
if (waveIndex >= wavelength)
|
||||||
|
{
|
||||||
|
waveFrequency = newWaveFrequency;
|
||||||
|
waveIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the synthesized samples for later drawing
|
||||||
|
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||||
|
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SquareCallback(void *framesOut, unsigned int frameCount)
|
||||||
|
{
|
||||||
|
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||||
|
|
||||||
|
// Synthesize the square wave
|
||||||
|
for (int i = 0; i < frameCount; i++)
|
||||||
|
{
|
||||||
|
((float *)framesOut)[i] = (waveIndex < wavelength/2)? 1 : -1;
|
||||||
|
waveIndex++;
|
||||||
|
|
||||||
|
if (waveIndex >= wavelength)
|
||||||
|
{
|
||||||
|
waveFrequency = newWaveFrequency;
|
||||||
|
waveIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the synthesized samples for later drawing
|
||||||
|
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||||
|
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TriangleCallback(void *framesOut, unsigned int frameCount)
|
||||||
|
{
|
||||||
|
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||||
|
|
||||||
|
// Synthesize the triangle wave
|
||||||
|
for (int i = 0; i < frameCount; i++)
|
||||||
|
{
|
||||||
|
((float *)framesOut)[i] = (waveIndex < wavelength/2)? (-1 + 2.0f*waveIndex/(wavelength/2)) : (1 - 2.0f*(waveIndex - wavelength/2)/(wavelength/2));
|
||||||
|
waveIndex++;
|
||||||
|
|
||||||
|
if (waveIndex >= wavelength)
|
||||||
|
{
|
||||||
|
waveFrequency = newWaveFrequency;
|
||||||
|
waveIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the synthesized samples for later drawing
|
||||||
|
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||||
|
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SawtoothCallback(void *framesOut, unsigned int frameCount)
|
||||||
|
{
|
||||||
|
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||||
|
|
||||||
|
// Synthesize the sawtooth wave
|
||||||
|
for (int i = 0; i < frameCount; i++)
|
||||||
|
{
|
||||||
|
((float *)framesOut)[i] = -1 + 2.0f*waveIndex/wavelength;
|
||||||
|
waveIndex++;
|
||||||
|
|
||||||
|
if (waveIndex >= wavelength)
|
||||||
|
{
|
||||||
|
waveFrequency = newWaveFrequency;
|
||||||
|
waveIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the synthesized samples for later drawing
|
||||||
|
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||||
|
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||||
|
}
|
||||||
BIN
examples/audio/audio_stream_callback.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
6051
examples/audio/raygui.h
Normal file
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Ananth S (@Ananth1839) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Ananth S (@Ananth1839) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
@ -60,7 +60,7 @@ int main(void)
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
if (btnComputeHashes)
|
if (btnComputeHashes)
|
||||||
{
|
{
|
||||||
int textInputLen = strlen(textInput);
|
int textInputLen = (int)strlen(textInput);
|
||||||
|
|
||||||
// Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
|
// Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
|
||||||
base64Text = EncodeDataBase64((unsigned char *)textInput, textInputLen, &base64TextSize);
|
base64Text = EncodeDataBase64((unsigned char *)textInput, textInputLen, &base64TextSize);
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★☆☆☆] 1/4
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -78,7 +78,7 @@ int main(void)
|
|||||||
|
|
||||||
GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
||||||
GuiSetStyle(LISTVIEW, TEXT_PADDING, 40);
|
GuiSetStyle(LISTVIEW, TEXT_PADDING, 40);
|
||||||
GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 50 },
|
GuiListViewEx((Rectangle){ 0, 50, (float)GetScreenWidth(), (float)GetScreenHeight() - 50 },
|
||||||
files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused);
|
files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★☆☆☆] 1/4
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Ramon Santamaria (@raysan5) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Ramon Santamaria (@raysan5) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
@ -86,10 +86,10 @@ int main(void)
|
|||||||
|
|
||||||
// Draw mouse position
|
// Draw mouse position
|
||||||
DrawCircleV(GetMousePosition(), 20, MAROON);
|
DrawCircleV(GetMousePosition(), 20, MAROON);
|
||||||
DrawRectangle(mousePos.x - 25, mousePos.y, 50, 2, BLACK);
|
DrawRectangleRec((Rectangle) { mousePos.x - 25, mousePos.y, 50, 2 }, BLACK);
|
||||||
DrawRectangle(mousePos.x, mousePos.y - 25, 2, 50, BLACK);
|
DrawRectangleRec((Rectangle) { mousePos.x, mousePos.y - 25, 2, 50 }, BLACK);
|
||||||
DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), mousePos.x - 44,
|
DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), mousePos.x - 44,
|
||||||
(mousePos.y > GetScreenHeight() - 60)? mousePos.y - 46 : mousePos.y + 30, 20, BLACK);
|
(mousePos.y > GetScreenHeight() - 60)? (int)mousePos.y - 46 : (int)mousePos.y + 30, 20, BLACK);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★★☆] 3/4
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.0, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 5.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by ubkp (@ubkp) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by ubkp (@ubkp) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -133,7 +133,7 @@ int main(void)
|
|||||||
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
|
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
|
||||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, line01KeyWidths[i], 30 }, line01Keys[i]);
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, (float)line01KeyWidths[i], 30.0f }, line01Keys[i]);
|
||||||
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
|
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ int main(void)
|
|||||||
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
|
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
|
||||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, line02KeyWidths[i], 38 }, line02Keys[i]);
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, (float)line02KeyWidths[i], 38.0f }, line02Keys[i]);
|
||||||
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
|
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ int main(void)
|
|||||||
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
|
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
|
||||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38 + KEY_REC_SPACING*2, line03KeyWidths[i], 38 }, line03Keys[i]);
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38 + KEY_REC_SPACING*2, (float)line03KeyWidths[i], 38.0f }, line03Keys[i]);
|
||||||
recOffsetX += line03KeyWidths[i] + KEY_REC_SPACING;
|
recOffsetX += line03KeyWidths[i] + KEY_REC_SPACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ int main(void)
|
|||||||
// MAYUS, A, S, D, F, G, H, J, K, L, ;, ', ENTER, REPAG
|
// MAYUS, A, S, D, F, G, H, J, K, L, ;, ', ENTER, REPAG
|
||||||
for (int i = 0, recOffsetX = 0; i < 14; i++)
|
for (int i = 0, recOffsetX = 0; i < 14; i++)
|
||||||
{
|
{
|
||||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*2 + KEY_REC_SPACING*3, line04KeyWidths[i], 38 }, line04Keys[i]);
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*2 + KEY_REC_SPACING*3, (float)line04KeyWidths[i], 38.0f }, line04Keys[i]);
|
||||||
recOffsetX += line04KeyWidths[i] + KEY_REC_SPACING;
|
recOffsetX += line04KeyWidths[i] + KEY_REC_SPACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ int main(void)
|
|||||||
// LSHIFT, Z, X, C, V, B, N, M, ,, ., /, RSHIFT, UP, AVPAG
|
// LSHIFT, Z, X, C, V, B, N, M, ,, ., /, RSHIFT, UP, AVPAG
|
||||||
for (int i = 0, recOffsetX = 0; i < 14; i++)
|
for (int i = 0, recOffsetX = 0; i < 14; i++)
|
||||||
{
|
{
|
||||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*3 + KEY_REC_SPACING*4, line05KeyWidths[i], 38 }, line05Keys[i]);
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*3 + KEY_REC_SPACING*4, (float)line05KeyWidths[i], 38.0f }, line05Keys[i]);
|
||||||
recOffsetX += line05KeyWidths[i] + KEY_REC_SPACING;
|
recOffsetX += line05KeyWidths[i] + KEY_REC_SPACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ int main(void)
|
|||||||
// LCTRL, WIN, LALT, SPACE, ALTGR, \, FN, RCTRL, LEFT, DOWN, RIGHT
|
// LCTRL, WIN, LALT, SPACE, ALTGR, \, FN, RCTRL, LEFT, DOWN, RIGHT
|
||||||
for (int i = 0, recOffsetX = 0; i < 11; i++)
|
for (int i = 0, recOffsetX = 0; i < 11; i++)
|
||||||
{
|
{
|
||||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*4 + KEY_REC_SPACING*5, line06KeyWidths[i], 38 }, line06Keys[i]);
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*4 + KEY_REC_SPACING*5, (float)line06KeyWidths[i], 38.0f }, line06Keys[i]);
|
||||||
recOffsetX += line06KeyWidths[i] + KEY_REC_SPACING;
|
recOffsetX += line06KeyWidths[i] + KEY_REC_SPACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,12 +316,12 @@ static void GuiKeyboardKey(Rectangle bounds, int key)
|
|||||||
if (IsKeyDown(key))
|
if (IsKeyDown(key))
|
||||||
{
|
{
|
||||||
DrawRectangleLinesEx(bounds, 2.0f, MAROON);
|
DrawRectangleLinesEx(bounds, 2.0f, MAROON);
|
||||||
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, MAROON);
|
DrawText(GetKeyText(key), (int)(bounds.x + 4), (int)(bounds.y + 4), 10, MAROON);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DrawRectangleLinesEx(bounds, 2.0f, DARKGRAY);
|
DrawRectangleLinesEx(bounds, 2.0f, DARKGRAY);
|
||||||
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, DARKGRAY);
|
DrawText(GetKeyText(key), (int)(bounds.x + 4), (int)(bounds.y + 4), 10, DARKGRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -111,7 +111,7 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
free(rectangles);
|
RL_FREE(rectangles);
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★☆☆☆] 1/4
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
|||||||
@ -177,10 +177,10 @@ int main(void)
|
|||||||
DrawRectangleRec(increaseTypeButton, SKYBLUE);
|
DrawRectangleRec(increaseTypeButton, SKYBLUE);
|
||||||
DrawRectangleRec(decreaseResolutionButton, SKYBLUE);
|
DrawRectangleRec(decreaseResolutionButton, SKYBLUE);
|
||||||
DrawRectangleRec(increaseResolutionButton, SKYBLUE);
|
DrawRectangleRec(increaseResolutionButton, SKYBLUE);
|
||||||
DrawText("<", decreaseTypeButton.x + 3, decreaseTypeButton.y + 1, 10, BLACK);
|
DrawText("<", (int)decreaseTypeButton.x + 3, (int)decreaseTypeButton.y + 1, 10, BLACK);
|
||||||
DrawText(">", increaseTypeButton.x + 3, increaseTypeButton.y + 1, 10, BLACK);
|
DrawText(">", (int)increaseTypeButton.x + 3, (int)increaseTypeButton.y + 1, 10, BLACK);
|
||||||
DrawText("<", decreaseResolutionButton.x + 3, decreaseResolutionButton.y + 1, 10, BLACK);
|
DrawText("<", (int)decreaseResolutionButton.x + 3, (int)decreaseResolutionButton.y + 1, 10, BLACK);
|
||||||
DrawText(">", increaseResolutionButton.x + 3, increaseResolutionButton.y + 1, 10, BLACK);
|
DrawText(">", (int)increaseResolutionButton.x + 3, (int)increaseResolutionButton.y + 1, 10, BLACK);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -308,7 +308,7 @@ static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *s
|
|||||||
}
|
}
|
||||||
|
|
||||||
UnloadRenderTexture(*target);
|
UnloadRenderTexture(*target);
|
||||||
*target = LoadRenderTexture(sourceRect->width, -sourceRect->height);
|
*target = LoadRenderTexture((int)sourceRect->width, -(int)sourceRect->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example how to calculate position on RenderTexture
|
// Example how to calculate position on RenderTexture
|
||||||
|
|||||||
@ -646,6 +646,7 @@ typedef enum {
|
|||||||
// ProgressBar
|
// ProgressBar
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
||||||
|
PROGRESS_SIDE, // ProgressBar increment side: 0-left->right, 1-right-left
|
||||||
} GuiProgressBarProperty;
|
} GuiProgressBarProperty;
|
||||||
|
|
||||||
// ScrollBar
|
// ScrollBar
|
||||||
@ -3522,7 +3523,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw slider internal progress bar (depends on state)
|
// Draw slider internal progress bar (depends on state)
|
||||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
if (GuiGetStyle(PROGRESSBAR, PROGRESS_SIDE) == 0) // Left-->Right
|
||||||
|
{
|
||||||
|
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||||
|
}
|
||||||
|
else // Right-->Left
|
||||||
|
{
|
||||||
|
progress.x = bounds.x + bounds.width - progress.width - GuiGetStyle(PROGRESSBAR, BORDER_WIDTH);
|
||||||
|
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw left/right text if provided
|
// Draw left/right text if provided
|
||||||
@ -5119,11 +5128,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
|||||||
|
|
||||||
// Get text divided into lines (by line-breaks '\n')
|
// Get text divided into lines (by line-breaks '\n')
|
||||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||||
static char **GetTextLines(const char *text, int *count)
|
static const char **GetTextLines(const char *text, int *count)
|
||||||
{
|
{
|
||||||
#define RAYGUI_MAX_TEXT_LINES 128
|
#define RAYGUI_MAX_TEXT_LINES 128
|
||||||
|
|
||||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||||
|
|
||||||
int textLength = (int)strlen(text);
|
int textLength = (int)strlen(text);
|
||||||
@ -5193,7 +5202,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
|||||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
char **lines = GetTextLines(text, &lineCount);
|
const char **lines = GetTextLines(text, &lineCount);
|
||||||
|
|
||||||
// Text style variables
|
// Text style variables
|
||||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
GLFW_ICON ICON "raylib.ico"
|
GLFW_ICON ICON "raylib.ico"
|
||||||
|
|
||||||
1 VERSIONINFO
|
1 VERSIONINFO
|
||||||
FILEVERSION 5,5,0,0
|
FILEVERSION 6,0,0,0
|
||||||
PRODUCTVERSION 5,5,0,0
|
PRODUCTVERSION 6,0,0,0
|
||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "StringFileInfo"
|
BLOCK "StringFileInfo"
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -11,12 +11,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "raylib technologies"
|
VALUE "CompanyName", "raylib technologies"
|
||||||
VALUE "FileDescription", "raylib application (www.raylib.com)"
|
VALUE "FileDescription", "raylib application (www.raylib.com)"
|
||||||
VALUE "FileVersion", "5.5.0"
|
VALUE "FileVersion", "6.0.0"
|
||||||
VALUE "InternalName", "raylib-example"
|
VALUE "InternalName", "raylib-example"
|
||||||
VALUE "LegalCopyright", "(c) 2025 Ramon Santamaria (@raysan5)"
|
VALUE "LegalCopyright", "(c) 2026 Ramon Santamaria (@raysan5)"
|
||||||
VALUE "OriginalFilename", "raylib-example"
|
VALUE "OriginalFilename", "raylib-example"
|
||||||
VALUE "ProductName", "raylib-example"
|
VALUE "ProductName", "raylib-example"
|
||||||
VALUE "ProductVersion", "5.5.0"
|
VALUE "ProductVersion", "6.0.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
@ -10,14 +10,14 @@
|
|||||||
# This list is used as the main reference by [rexm] tool for examples collection validation and management
|
# This list is used as the main reference by [rexm] tool for examples collection validation and management
|
||||||
#
|
#
|
||||||
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
|
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
core;core_delta_time;★☆☆☆;5.5;6.0;2025;2025;"Robin";@RobinsAviary
|
||||||
core;core_input_keys;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
core;core_input_keys;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_input_mouse;★☆☆☆;1.0;5.5;2014;2025;"Ramon Santamaria";@raysan5
|
core;core_input_mouse;★☆☆☆;1.0;5.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_input_mouse_wheel;★☆☆☆;1.1;1.3;2014;2025;"Ramon Santamaria";@raysan5
|
core;core_input_mouse_wheel;★☆☆☆;1.1;1.3;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_input_gamepad;★☆☆☆;1.1;4.2;2013;2025;"Ramon Santamaria";@raysan5
|
core;core_input_gamepad;★☆☆☆;1.1;4.2;2013;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_input_multitouch;★☆☆☆;2.1;2.5;2019;2025;"Berni";@Berni8k
|
core;core_input_multitouch;★☆☆☆;2.1;2.5;2019;2025;"Berni";@Berni8k
|
||||||
core;core_input_gestures;★★☆☆;1.4;4.2;2016;2025;"Ramon Santamaria";@raysan5
|
core;core_input_gestures;★★☆☆;1.4;4.2;2016;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_input_gestures_testbed;★★★☆;5.0;5.6-dev;2023;2025;"ubkp";@ubkp
|
core;core_input_gestures_testbed;★★★☆;5.0;6.0;2023;2025;"ubkp";@ubkp
|
||||||
core;core_input_virtual_controls;★★☆☆;5.0;5.0;2024;2025;"GreenSnakeLinux";@GreenSnakeLinux
|
core;core_input_virtual_controls;★★☆☆;5.0;5.0;2024;2025;"GreenSnakeLinux";@GreenSnakeLinux
|
||||||
core;core_2d_camera;★★☆☆;1.5;3.0;2016;2025;"Ramon Santamaria";@raysan5
|
core;core_2d_camera;★★☆☆;1.5;3.0;2016;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_2d_camera_mouse_zoom;★★☆☆;4.2;4.2;2022;2025;"Jeffery Myers";@JeffM2501
|
core;core_2d_camera_mouse_zoom;★★☆☆;4.2;4.2;2022;2025;"Jeffery Myers";@JeffM2501
|
||||||
@ -46,16 +46,16 @@ core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessa
|
|||||||
core;core_random_sequence;★☆☆☆;5.0;5.0;2023;2025;"Dalton Overmyer";@REDl3east
|
core;core_random_sequence;★☆☆☆;5.0;5.0;2023;2025;"Dalton Overmyer";@REDl3east
|
||||||
core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_highdpi_demo;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
|
core;core_highdpi_demo;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
|
||||||
core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
core;core_render_texture;★☆☆☆;6.0;6.0;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
|
core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||||
core;core_input_actions;★★☆☆;5.5;5.6;2025;2025;"Jett";@JettMonstersGoBoom
|
core;core_input_actions;★★☆☆;5.5;5.6;2025;2025;"Jett";@JettMonstersGoBoom
|
||||||
core;core_directory_files;★☆☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
|
core;core_directory_files;★☆☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
|
||||||
core;core_highdpi_testbed;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
core;core_highdpi_testbed;★☆☆☆;6.0;6.0;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_screen_recording;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
core;core_screen_recording;★★☆☆;6.0;6.0;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839
|
core;core_clipboard_text;★★☆☆;6.0;6.0;2025;2025;"Ananth S";@Ananth1839
|
||||||
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
|
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
|
||||||
core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
core;core_compute_hash;★★☆☆;6.0;6.0;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
|
core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
|
||||||
core;core_window_web;★☆☆☆;1.3;5.5;2015;2025;"Ramon Santamaria";@raysan5
|
core;core_window_web;★☆☆☆;1.3;5.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
@ -71,7 +71,7 @@ shapes;shapes_following_eyes;★★☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@
|
|||||||
shapes;shapes_easings_ball;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_easings_ball;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_easings_box;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_easings_box;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_easings_rectangles;★★★☆;2.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_easings_rectangles;★★★☆;2.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_recursive_tree;★★★☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
shapes;shapes_recursive_tree;★★★☆;6.0;6.0;2025;2025;"Jopestpe";@jopestpe
|
||||||
shapes;shapes_ring_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
shapes;shapes_ring_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
||||||
shapes;shapes_circle_sector_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
shapes;shapes_circle_sector_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
||||||
shapes;shapes_rounded_rectangle_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
shapes;shapes_rounded_rectangle_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
||||||
@ -81,23 +81,25 @@ shapes;shapes_splines_drawing;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";
|
|||||||
shapes;shapes_digital_clock;★★★★;5.5;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
shapes;shapes_digital_clock;★★★★;5.5;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
||||||
shapes;shapes_double_pendulum;★★☆☆;5.5;5.5;2025;2025;"JoeCheong";@Joecheong2006
|
shapes;shapes_double_pendulum;★★☆☆;5.5;5.5;2025;2025;"JoeCheong";@Joecheong2006
|
||||||
shapes;shapes_dashed_line;★☆☆☆;5.5;5.5;2025;2025;"Luís Almeida";@luis605
|
shapes;shapes_dashed_line;★☆☆☆;5.5;5.5;2025;2025;"Luís Almeida";@luis605
|
||||||
shapes;shapes_triangle_strip;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
shapes;shapes_triangle_strip;★★☆☆;6.0;6.0;2025;2025;"Jopestpe";@jopestpe
|
||||||
shapes;shapes_vector_angle;★★☆☆;1.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_vector_angle;★★☆☆;1.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_pie_chart;★★★☆;5.5;5.6;2025;2025;"Gideon Serfontein";@GideonSerf
|
shapes;shapes_pie_chart;★★★☆;5.5;5.6;2025;2025;"Gideon Serfontein";@GideonSerf
|
||||||
shapes;shapes_kaleidoscope;★★☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
|
shapes;shapes_kaleidoscope;★★☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
|
||||||
shapes;shapes_clock_of_clocks;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
shapes;shapes_clock_of_clocks;★★☆☆;5.5;6.0;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
shapes;shapes_math_sine_cosine;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
shapes;shapes_math_sine_cosine;★★☆☆;6.0;6.0;2025;2025;"Jopestpe";@jopestpe
|
||||||
shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2025;2025;"Balamurugan R";@Bala050814
|
shapes;shapes_mouse_trail;★☆☆☆;5.6;6.0;2025;2025;"Balamurugan R";@Bala050814
|
||||||
shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||||
shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
shapes;shapes_starfield_effect;★★☆☆;5.5;6.0;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
shapes;shapes_lines_drawing;★☆☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
shapes;shapes_lines_drawing;★☆☆☆;6.0;5.6;2025;2025;"Robin";@RobinsAviary
|
||||||
shapes;shapes_math_angle_rotation;★☆☆☆;5.6-dev;5.6;2025;2025;"Kris";@krispy-snacc
|
shapes;shapes_math_angle_rotation;★☆☆☆;6.0;5.6;2025;2025;"Kris";@krispy-snacc
|
||||||
shapes;shapes_rlgl_color_wheel;★★★☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
shapes;shapes_rlgl_color_wheel;★★★☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||||
shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
shapes;shapes_rlgl_triangle;★★☆☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||||
shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
shapes;shapes_ball_physics;★★☆☆;6.0;6.0;2025;2025;"David Buzatto";@davidbuzatto
|
||||||
shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
shapes;shapes_penrose_tile;★★★★;5.5;6.0;2025;2025;"David Buzatto";@davidbuzatto
|
||||||
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
||||||
shapes;shapes_easings_testbed;★★★☆;2.5;2.5;2019;2025;"Juan Miguel López";@flashback-fx
|
shapes;shapes_easings_testbed;★★★☆;2.5;2.5;2019;2025;"Juan Miguel López";@flashback-fx
|
||||||
|
textures;textures_clipboard_image;★☆☆☆;6.0;6.0;2026;2026;"Maicon Santana";@maiconpintoabreu
|
||||||
|
textures;textures_magnifying_glass;★★★☆;5.6;5.6;2026;2026;"Luke Vaughan";@badram
|
||||||
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
||||||
@ -125,7 +127,7 @@ textures;textures_image_channel;★★☆☆;5.5;5.5;2024;2025;"Bruno Cabral";@b
|
|||||||
textures;textures_image_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
textures;textures_image_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||||
textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501
|
textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501
|
||||||
textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary
|
textures;textures_sprite_stacking;★★☆☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||||
textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||||
textures;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes
|
textures;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes
|
||||||
text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5
|
text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5
|
||||||
@ -141,9 +143,9 @@ text;text_unicode_emojis;★★★★;2.5;4.0;2019;2025;"Vlad Adrian";@demizdor
|
|||||||
text;text_unicode_ranges;★★★★;5.5;5.6;2025;2025;"Vadim Gunko";@GuvaCode
|
text;text_unicode_ranges;★★★★;5.5;5.6;2025;2025;"Vadim Gunko";@GuvaCode
|
||||||
text;text_3d_drawing;★★★★;3.5;4.0;2021;2025;"Vlad Adrian";@demizdor
|
text;text_3d_drawing;★★★★;3.5;4.0;2021;2025;"Vlad Adrian";@demizdor
|
||||||
text;text_codepoints_loading;★★★☆;4.2;4.2;2022;2025;"Ramon Santamaria";@raysan5
|
text;text_codepoints_loading;★★★☆;4.2;4.2;2022;2025;"Ramon Santamaria";@raysan5
|
||||||
text;text_inline_styling;★★★☆;5.6-dev;5.6-dev;2025;2025;"Wagner Barongello";@SultansOfCode
|
text;text_inline_styling;★★★☆;6.0;6.0;2025;2025;"Wagner Barongello";@SultansOfCode
|
||||||
text;text_words_alignment;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
text;text_words_alignment;★☆☆☆;6.0;6.0;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
text;text_strings_management;★★★☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
text;text_strings_management;★★★☆;6.0;6.0;2025;2025;"David Buzatto";@davidbuzatto
|
||||||
models;models_loading_iqm;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant
|
models;models_loading_iqm;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant
|
||||||
models;models_billboard_rendering;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
models;models_billboard_rendering;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
models;models_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
models;models_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
@ -166,15 +168,15 @@ models;models_skybox_rendering;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria"
|
|||||||
models;models_textured_cube;★★☆☆;4.5;4.5;2022;2025;"Ramon Santamaria";@raysan5
|
models;models_textured_cube;★★☆☆;4.5;4.5;2022;2025;"Ramon Santamaria";@raysan5
|
||||||
models;models_animation_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Holden";@orangeduck
|
models;models_animation_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Holden";@orangeduck
|
||||||
models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur
|
models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur
|
||||||
models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz
|
models;models_tesseract_view;★★☆☆;6.0;6.0;2024;2025;"Timothy van der Valk";@arceryz
|
||||||
models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle
|
models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle
|
||||||
models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
models;models_rotating_cube;★☆☆☆;6.0;6.0;2025;2025;"Jopestpe";@jopestpe
|
||||||
models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
models;models_decals;★★★★;6.0;6.0;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
models;models_directional_billboard;★★☆☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||||
models;models_animation_blend_custom;★★★★;5.5;5.5;2026;2026;"dmitrii-brand";@dmitrii-brand
|
models;models_animation_blend_custom;★★★★;5.5;6.0;2026;2026;"dmitrii-brand";@dmitrii-brand
|
||||||
models;models_animation_blending;☆☆☆☆;5.5;5.6-dev;2024;2024;"Kirandeep";@Kirandeep-Singh-Khehra
|
models;models_animation_blending;★★★★;5.5;6.0;2024;2026;"Kirandeep";@Kirandeep-Singh-Khehra
|
||||||
models;models_animation_timming;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
|
models;models_animation_timing;★★★☆;6.0;6.0;2026;2026;"Ramon Santamaria";@raysan5
|
||||||
shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
|
shaders;shaders_ascii_rendering;★★☆☆;5.5;6.0;2025;2025;"Maicon Santana";@maiconpintoabreu
|
||||||
shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
|
shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
|
||||||
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
|
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shaders;shaders_shapes_textures;★★☆☆;1.7;3.7;2015;2025;"Ramon Santamaria";@raysan5
|
shaders;shaders_shapes_textures;★★☆☆;1.7;3.7;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
@ -186,15 +188,15 @@ shaders;shaders_texture_rendering;★★☆☆;2.0;3.7;2019;2025;"Michał Ciesie
|
|||||||
shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff";@GoldenThumbs
|
shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff";@GoldenThumbs
|
||||||
shaders;shaders_texture_waves;★★☆☆;2.5;3.7;2019;2025;"Anata";@anatagawa
|
shaders;shaders_texture_waves;★★☆☆;2.5;3.7;2019;2025;"Anata";@anatagawa
|
||||||
shaders;shaders_julia_set;★★★☆;2.5;4.0;2019;2025;"Josh Colclough";@joshcol9232
|
shaders;shaders_julia_set;★★★☆;2.5;4.0;2019;2025;"Josh Colclough";@joshcol9232
|
||||||
shaders;shaders_mandelbrot_set;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
shaders;shaders_mandelbrot_set;★★★☆;6.0;6.0;2025;2025;"Jordi Santonja";@JordSant
|
||||||
shaders;shaders_color_correction;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
shaders;shaders_color_correction;★★☆☆;6.0;6.0;2025;2025;"Jordi Santonja";@JordSant
|
||||||
shaders;shaders_eratosthenes_sieve;★★★☆;2.5;4.0;2019;2025;"ProfJski";@ProfJski
|
shaders;shaders_eratosthenes_sieve;★★★☆;2.5;4.0;2019;2025;"ProfJski";@ProfJski
|
||||||
shaders;shaders_fog_rendering;★★★☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
shaders;shaders_fog_rendering;★★★☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
||||||
shaders;shaders_simple_mask;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
shaders;shaders_simple_mask;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
||||||
shaders;shaders_hot_reloading;★★★☆;3.0;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
shaders;shaders_hot_reloading;★★★☆;3.0;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
||||||
shaders;shaders_mesh_instancing;★★★★;3.7;4.2;2020;2025;"seanpringle";@seanpringle
|
shaders;shaders_mesh_instancing;★★★★;3.7;4.2;2020;2025;"seanpringle";@seanpringle
|
||||||
shaders;shaders_multi_sample2d;★★☆☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
shaders;shaders_multi_sample2d;★★☆☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
||||||
shaders;shaders_normalmap_rendering;★★★★;5.6;5.6;2025;2025;"Jeremy Montgomery";@Sir_Irk
|
shaders;shaders_normalmap_rendering;★★★★;6.0;6.0;2025;2025;"Jeremy Montgomery";@Sir_Irk
|
||||||
shaders;shaders_spotlight_rendering;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
shaders;shaders_spotlight_rendering;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
||||||
shaders;shaders_deferred_rendering;★★★★;4.5;4.5;2023;2025;"Justin Andreas Lacoste";@27justin
|
shaders;shaders_deferred_rendering;★★★★;4.5;4.5;2023;2025;"Justin Andreas Lacoste";@27justin
|
||||||
shaders;shaders_hybrid_rendering;★★★★;4.2;4.2;2022;2025;"Buğra Alptekin Sarı";@BugraAlptekinSari
|
shaders;shaders_hybrid_rendering;★★★★;4.2;4.2;2022;2025;"Buğra Alptekin Sarı";@BugraAlptekinSari
|
||||||
@ -205,15 +207,17 @@ shaders;shaders_depth_writing;★★☆☆;4.2;4.2;2022;2025;"Buğra Alptekin Sa
|
|||||||
shaders;shaders_basic_pbr;★★★★;5.0;5.5;2023;2025;"Afan OLOVCIC";@_DevDad
|
shaders;shaders_basic_pbr;★★★★;5.0;5.5;2023;2025;"Afan OLOVCIC";@_DevDad
|
||||||
shaders;shaders_lightmap_rendering;★★★☆;4.5;4.5;2019;2025;"Jussi Viitala";@nullstare
|
shaders;shaders_lightmap_rendering;★★★☆;4.5;4.5;2019;2025;"Jussi Viitala";@nullstare
|
||||||
shaders;shaders_rounded_rectangle;★★★☆;5.5;5.5;2025;2025;"Anstro Pleuton";@anstropleuton
|
shaders;shaders_rounded_rectangle;★★★☆;5.5;5.5;2025;2025;"Anstro Pleuton";@anstropleuton
|
||||||
shaders;shaders_depth_rendering;★★★☆;5.6-dev;5.6-dev;2025;2025;"Luís Almeida";@luis605
|
shaders;shaders_depth_rendering;★★★☆;6.0;6.0;2025;2025;"Luís Almeida";@luis605
|
||||||
shaders;shaders_game_of_life;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
shaders;shaders_game_of_life;★★★☆;6.0;6.0;2025;2025;"Jordi Santonja";@JordSant
|
||||||
shaders;shaders_rlgl_compute;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
shaders;shaders_rlgl_compute;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
||||||
|
shaders;shaders_cel_shading;★★★☆;6.0;6.0;2026;2026;"Gleb A";@ggrizzly
|
||||||
audio;audio_module_playing;★☆☆☆;1.5;3.5;2016;2025;"Ramon Santamaria";@raysan5
|
audio;audio_module_playing;★☆☆☆;1.5;3.5;2016;2025;"Ramon Santamaria";@raysan5
|
||||||
audio;audio_music_stream;★☆☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
audio;audio_music_stream;★☆☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
audio;audio_raw_stream;★★★☆;1.6;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
audio;audio_raw_stream;★★★☆;1.6;6.0;2015;2026;"Ramon Santamaria";@raysan5
|
||||||
audio;audio_sound_loading;★☆☆☆;1.1;3.5;2014;2025;"Ramon Santamaria";@raysan5
|
audio;audio_sound_loading;★☆☆☆;1.1;3.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
audio;audio_mixed_processor;★★★★;4.2;4.2;2023;2025;"hkc";@hatkidchan
|
audio;audio_mixed_processor;★★★★;4.2;4.2;2023;2025;"hkc";@hatkidchan
|
||||||
audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@raysan5
|
audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@raysan5
|
||||||
audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501
|
audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501
|
||||||
audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71
|
audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71
|
||||||
audio;audio_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4
|
audio;audio_spectrum_visualizer;★★★☆;6.0;6.0;2025;2025;"IANN";@meisei4
|
||||||
|
audio;audio_stream_callback;★★★☆;6.0;6.0;2026;2026;"Dan Hoang";@dan-hoang
|
||||||
|
|||||||
@ -4,17 +4,18 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★★★] 4/4
|
* Example complexity rating: [★★★★] 4/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* This example demonstrates per-bone animation blending, allowing smooth transitions
|
* Example contributed by dmitrii-brand (@dmitrii-brand) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* DETAILS: Example demonstrates per-bone animation blending, allowing smooth transitions
|
||||||
* between two animations by interpolating bone transforms. This is useful for:
|
* between two animations by interpolating bone transforms. This is useful for:
|
||||||
* - Blending movement animations (walk/run) with action animations (jump/attack)
|
* - Blending movement animations (walk/run) with action animations (jump/attack)
|
||||||
* - Creating smooth animation transitions
|
* - Creating smooth animation transitions
|
||||||
* - Layering animations (e.g., upper body attack while lower body walks)
|
* - Layering animations (e.g., upper body attack while lower body walks)
|
||||||
*
|
*
|
||||||
* Example contributed by dmitrii-brand (@dmitrii-brand) and reviewed by Ramon Santamaria (@raysan5)
|
* WARNING: GPU skinning must be enabled in raylib with a compilation flag,
|
||||||
*
|
* if not enabled, CPU skinning will be used instead
|
||||||
* NOTE: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS
|
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
@ -27,8 +28,10 @@
|
|||||||
|
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
|
|
||||||
#include <string.h> // Required for: memcpy()
|
#include "rlgl.h" // Requried for: rlUpdateVertexBuffer() (CPU-skinning)
|
||||||
#include <stdlib.h> // Required for: NULL
|
|
||||||
|
#include <string.h> // Required for: memcpy()
|
||||||
|
#include <stdlib.h> // Required for: NULL
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP)
|
||||||
#define GLSL_VERSION 330
|
#define GLSL_VERSION 330
|
||||||
@ -40,8 +43,8 @@
|
|||||||
// Module Functions Declaration
|
// Module Functions Declaration
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
static bool IsUpperBodyBone(const char *boneName);
|
static bool IsUpperBodyBone(const char *boneName);
|
||||||
static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int frame1,
|
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim1, int frame1,
|
||||||
ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend);
|
ModelAnimation *anim2, int frame2, float blend, bool upperBodyBlend);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
@ -57,51 +60,40 @@ int main(void)
|
|||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
|
camera.position = (Vector3){ 4.0f, 4.0f, 4.0f }; // Camera position
|
||||||
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
camera.target = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera looking at point
|
||||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
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.fovy = 45.0f; // Camera field-of-view Y
|
||||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||||
|
|
||||||
// Load gltf model
|
// Load gltf model
|
||||||
Model characterModel = LoadModel("resources/models/gltf/greenman.glb");
|
Model model = LoadModel("resources/models/gltf/greenman.glb");
|
||||||
|
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||||
|
|
||||||
// Load skinning shader
|
// Load skinning shader
|
||||||
|
// WARNING: GPU skinning must be enabled in raylib with a compilation flag,
|
||||||
|
// if not enabled, CPU skinning will be used instead
|
||||||
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||||
|
model.materials[1].shader = skinningShader;
|
||||||
characterModel.materials[1].shader = skinningShader;
|
|
||||||
|
|
||||||
// Load gltf model animations
|
// Load gltf model animations
|
||||||
int animsCount = 0;
|
int animCount = 0;
|
||||||
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/greenman.glb", &animsCount);
|
ModelAnimation *anims = LoadModelAnimations("resources/models/gltf/greenman.glb", &animCount);
|
||||||
|
|
||||||
// Log all available animations for debugging
|
// Use specific animation indices: 2-walk/move, 3-attack
|
||||||
TraceLog(LOG_INFO, "Found %d animations:", animsCount);
|
int animIndex0 = 2; // Walk/Move animation (index 2)
|
||||||
for (int i = 0; i < animsCount; i++)
|
int animIndex1 = 3; // Attack animation (index 3)
|
||||||
{
|
int animCurrentFrame0 = 0;
|
||||||
TraceLog(LOG_INFO, " Animation %d: %s (%d frames)", i, modelAnimations[i].name, modelAnimations[i].keyframeCount);
|
int animCurrentFrame1 = 0;
|
||||||
}
|
|
||||||
|
|
||||||
// Use specific indices: walk/move = 2, attack = 3
|
|
||||||
unsigned int animIndex1 = 2; // Walk/Move animation (index 2)
|
|
||||||
unsigned int animIndex2 = 3; // Attack animation (index 3)
|
|
||||||
unsigned int animCurrentFrame1 = 0;
|
|
||||||
unsigned int animCurrentFrame2 = 0;
|
|
||||||
|
|
||||||
// Validate indices
|
// Validate indices
|
||||||
if (animIndex1 >= animsCount) animIndex1 = 0;
|
if (animIndex0 >= animCount) animIndex0 = 0;
|
||||||
if (animIndex2 >= animsCount) animIndex2 = (animsCount > 1) ? 1 : 0;
|
if (animIndex1 >= animCount) animIndex1 = (animCount > 1) ? 1 : 0;
|
||||||
|
|
||||||
TraceLog(LOG_INFO, "Using Walk (index %d): %s", animIndex1, modelAnimations[animIndex1].name);
|
bool upperBodyBlend = true; // Toggle: true = upper/lower body blending, false = uniform blending (50/50)
|
||||||
TraceLog(LOG_INFO, "Using Attack (index %d): %s", animIndex2, modelAnimations[animIndex2].name);
|
|
||||||
|
|
||||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
bool upperBodyBlend = true; // Toggle: true = upper/lower body blending, false = uniform blending (50/50)
|
|
||||||
|
|
||||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
@ -109,24 +101,28 @@ int main(void)
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
// Toggle upper/lower body blending mode (SPACE key)
|
// Toggle upper/lower body blending mode (SPACE key)
|
||||||
if (IsKeyPressed(KEY_SPACE)) upperBodyBlend = !upperBodyBlend;
|
if (IsKeyPressed(KEY_SPACE)) upperBodyBlend = !upperBodyBlend;
|
||||||
|
|
||||||
// Update animation frames
|
// Update animation frames
|
||||||
ModelAnimation anim1 = modelAnimations[animIndex1];
|
ModelAnimation anim0 = anims[animIndex0];
|
||||||
ModelAnimation anim2 = modelAnimations[animIndex2];
|
ModelAnimation anim1 = anims[animIndex1];
|
||||||
|
|
||||||
|
animCurrentFrame0 = (animCurrentFrame0 + 1)%anim0.keyframeCount;
|
||||||
animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.keyframeCount;
|
animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.keyframeCount;
|
||||||
animCurrentFrame2 = (animCurrentFrame2 + 1)%anim2.keyframeCount;
|
|
||||||
|
|
||||||
// Blend the two animations
|
// Blend the two animations
|
||||||
characterModel.transform = MatrixTranslate(position.x, position.y, position.z);
|
|
||||||
// When upperBodyBlend is ON: upper body = attack (1.0), lower body = walk (0.0)
|
// When upperBodyBlend is ON: upper body = attack (1.0), lower body = walk (0.0)
|
||||||
// When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack)
|
// When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack)
|
||||||
float blendFactor = upperBodyBlend ? 1.0f : 0.5f;
|
float blendFactor = (upperBodyBlend? 1.0f : 0.5f);
|
||||||
BlendModelAnimationsBones(&characterModel, &anim1, animCurrentFrame1, &anim2, animCurrentFrame2, blendFactor, upperBodyBlend);
|
UpdateModelAnimationBones(&model, &anim0, animCurrentFrame0,
|
||||||
|
&anim1, animCurrentFrame1, blendFactor, upperBodyBlend);
|
||||||
|
|
||||||
|
// raylib provided animation blending function
|
||||||
|
//UpdateModelAnimationEx(model, anim0, (float)animCurrentFrame0,
|
||||||
|
// anim1, (float)animCurrentFrame1, blendFactor);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -137,19 +133,18 @@ int main(void)
|
|||||||
|
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
|
|
||||||
// Draw character mesh, pose calculation is done in shader (GPU skinning)
|
DrawModel(model, position, 1.0f, WHITE);
|
||||||
DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);
|
|
||||||
|
|
||||||
DrawGrid(10, 1.0f);
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
// Draw UI
|
// Draw UI
|
||||||
DrawText("BONE BLENDING EXAMPLE", 10, 10, 20, DARKGRAY);
|
DrawText(TextFormat("ANIM 0: %s", anim0.name), 10, 10, 20, GRAY);
|
||||||
DrawText(TextFormat("Walk (Animation 2): %s", anim1.name), 10, 35, 10, GRAY);
|
DrawText(TextFormat("ANIM 1: %s", anim1.name), 10, 40, 20, GRAY);
|
||||||
DrawText(TextFormat("Attack (Animation 3): %s", anim2.name), 10, 50, 10, GRAY);
|
DrawText(TextFormat("[SPACE] Toggle blending mode: %s",
|
||||||
DrawText(TextFormat("Mode: %s", upperBodyBlend ? "Upper/Lower Body Blending" : "Uniform Blending"), 10, 65, 10, GRAY);
|
upperBodyBlend? "Upper/Lower Body Blending" : "Uniform Blending"),
|
||||||
DrawText("SPACE - Toggle blending mode", 10, GetScreenHeight() - 20, 10, DARKGRAY);
|
10, GetScreenHeight() - 30, 20, DARKGRAY);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -157,8 +152,8 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadModelAnimations(modelAnimations, animsCount); // Unload model animation
|
UnloadModelAnimations(anims, animCount); // Unload model animation
|
||||||
UnloadModel(characterModel); // Unload model and meshes/material
|
UnloadModel(model); // Unload model and meshes/material
|
||||||
UnloadShader(skinningShader); // Unload GPU skinning shader
|
UnloadShader(skinningShader); // Unload GPU skinning shader
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
@ -199,74 +194,138 @@ static bool IsUpperBodyBone(const char *boneName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Blend two animations per-bone with selective upper/lower body blending
|
// Blend two animations per-bone with selective upper/lower body blending
|
||||||
static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int frame1,
|
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int frame0,
|
||||||
ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend)
|
ModelAnimation *anim1, int frame1, float blend, bool upperBodyBlend)
|
||||||
{
|
{
|
||||||
// Validate inputs
|
// Validate inputs
|
||||||
if (anim1->boneCount == 0 || anim1->keyframePoses == NULL ||
|
if ((anim0->boneCount != 0) && (anim0->keyframePoses != NULL) &&
|
||||||
anim2->boneCount == 0 || anim2->keyframePoses == NULL ||
|
(anim1->boneCount != 0) && (anim1->keyframePoses != NULL) &&
|
||||||
model->skeleton.boneCount == 0 || model->skeleton.bindPose == NULL)
|
(model->skeleton.boneCount != 0) && (model->skeleton.bindPose != NULL))
|
||||||
{
|
{
|
||||||
return;
|
// Clamp blend factor to [0, 1]
|
||||||
}
|
blend = fminf(1.0f, fmaxf(0.0f, blend));
|
||||||
|
|
||||||
// Clamp blend factor to [0, 1]
|
// Ensure frame indices are valid
|
||||||
blendFactor = fminf(1.0f, fmaxf(0.0f, blendFactor));
|
if (frame0 >= anim0->keyframeCount) frame0 = anim0->keyframeCount - 1;
|
||||||
|
if (frame1 >= anim1->keyframeCount) frame1 = anim1->keyframeCount - 1;
|
||||||
|
if (frame0 < 0) frame0 = 0;
|
||||||
|
if (frame1 < 0) frame1 = 0;
|
||||||
|
|
||||||
// Ensure frame indices are valid
|
// Get bone count (use minimum of all to be safe)
|
||||||
if (frame1 >= anim1->keyframeCount) frame1 = anim1->keyframeCount - 1;
|
int boneCount = model->skeleton.boneCount;
|
||||||
if (frame2 >= anim2->keyframeCount) frame2 = anim2->keyframeCount - 1;
|
if (anim0->boneCount < boneCount) boneCount = anim0->boneCount;
|
||||||
if (frame1 < 0) frame1 = 0;
|
if (anim1->boneCount < boneCount) boneCount = anim1->boneCount;
|
||||||
if (frame2 < 0) frame2 = 0;
|
|
||||||
|
|
||||||
// Get bone count (use minimum of all to be safe)
|
// Blend each bone
|
||||||
int boneCount = model->skeleton.boneCount;
|
for (int boneIndex = 0; boneIndex < boneCount; boneIndex++)
|
||||||
if (anim1->boneCount < boneCount) boneCount = anim1->boneCount;
|
|
||||||
if (anim2->boneCount < boneCount) boneCount = anim2->boneCount;
|
|
||||||
|
|
||||||
// Blend each bone
|
|
||||||
for (int boneId = 0; boneId < boneCount; boneId++)
|
|
||||||
{
|
|
||||||
// Determine blend factor for this bone
|
|
||||||
float boneBlendFactor = blendFactor;
|
|
||||||
|
|
||||||
// If upper body blending is enabled, use different blend factors for upper vs lower body
|
|
||||||
if (upperBodyBlend)
|
|
||||||
{
|
{
|
||||||
const char *boneName = model->skeleton.bones[boneId].name;
|
// Determine blend factor for this bone
|
||||||
bool isUpperBody = IsUpperBodyBone(boneName);
|
float boneBlendFactor = blend;
|
||||||
|
|
||||||
// Upper body: use anim2 (attack), Lower body: use anim1 (walk)
|
// If upper body blending is enabled, use different blend factors for upper vs lower body
|
||||||
// blendFactor = 0.0 means full anim1 (walk), 1.0 means full anim2 (attack)
|
if (upperBodyBlend)
|
||||||
if (isUpperBody) boneBlendFactor = blendFactor; // Upper body: blend towards anim2 (attack)
|
{
|
||||||
else boneBlendFactor = 1.0f - blendFactor; // Lower body: blend towards anim1 (walk) - invert the blend
|
const char *boneName = model->skeleton.bones[boneIndex].name;
|
||||||
|
bool isUpperBody = IsUpperBodyBone(boneName);
|
||||||
|
|
||||||
|
// Upper body: use anim1 (attack), Lower body: use anim0 (walk)
|
||||||
|
// blend = 0.0 means full anim0 (walk), 1.0 means full anim1 (attack)
|
||||||
|
if (isUpperBody) boneBlendFactor = blend; // Upper body: blend towards anim1 (attack)
|
||||||
|
else boneBlendFactor = 1.0f - blend; // Lower body: blend towards anim0 (walk) - invert the blend
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get transforms from both animations
|
||||||
|
Transform *bindTransform = &model->skeleton.bindPose[boneIndex];
|
||||||
|
Transform *animTransform0 = &anim0->keyframePoses[frame0][boneIndex];
|
||||||
|
Transform *animTransform1 = &anim1->keyframePoses[frame1][boneIndex];
|
||||||
|
|
||||||
|
// Blend the transforms
|
||||||
|
Transform blended = { 0 };
|
||||||
|
blended.translation = Vector3Lerp(animTransform0->translation, animTransform1->translation, boneBlendFactor);
|
||||||
|
blended.rotation = QuaternionSlerp(animTransform0->rotation, animTransform1->rotation, boneBlendFactor);
|
||||||
|
blended.scale = Vector3Lerp(animTransform0->scale, animTransform1->scale, boneBlendFactor);
|
||||||
|
|
||||||
|
// Convert bind pose to matrix
|
||||||
|
Matrix bindMatrix = MatrixMultiply(MatrixMultiply(
|
||||||
|
MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z),
|
||||||
|
QuaternionToMatrix(bindTransform->rotation)),
|
||||||
|
MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z));
|
||||||
|
|
||||||
|
// Convert blended transform to matrix
|
||||||
|
Matrix blendedMatrix = MatrixMultiply(MatrixMultiply(
|
||||||
|
MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z),
|
||||||
|
QuaternionToMatrix(blended.rotation)),
|
||||||
|
MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z));
|
||||||
|
|
||||||
|
// Calculate final bone matrix (similar to UpdateModelAnimationBones)
|
||||||
|
model->boneMatrices[boneIndex] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get transforms from both animations
|
// CPU skinning, updates CPU buffers and uploads them to GPU (if available)
|
||||||
Transform *bindTransform = &model->skeleton.bindPose[boneId];
|
// NOTE: Fallback in case GPU skinning is not supported or enabled
|
||||||
Transform *anim1Transform = &anim1->keyframePoses[frame1][boneId];
|
for (int m = 0; m < model->meshCount; m++)
|
||||||
Transform *anim2Transform = &anim2->keyframePoses[frame2][boneId];
|
{
|
||||||
|
Mesh mesh = model->meshes[m];
|
||||||
|
Vector3 animVertex = { 0 };
|
||||||
|
Vector3 animNormal = { 0 };
|
||||||
|
const int vertexValuesCount = mesh.vertexCount*3;
|
||||||
|
|
||||||
// Blend the transforms
|
int boneIndex = 0;
|
||||||
Transform blended = { 0 };
|
int boneCounter = 0;
|
||||||
blended.translation = Vector3Lerp(anim1Transform->translation, anim2Transform->translation, boneBlendFactor);
|
float boneWeight = 0.0f;
|
||||||
blended.rotation = QuaternionSlerp(anim1Transform->rotation, anim2Transform->rotation, boneBlendFactor);
|
bool bufferUpdateRequired = false; // Flag to check when anim vertex information is updated
|
||||||
blended.scale = Vector3Lerp(anim1Transform->scale, anim2Transform->scale, boneBlendFactor);
|
|
||||||
|
|
||||||
// Convert bind pose to matrix
|
// Skip if missing bone data or missing anim buffers initialization
|
||||||
Matrix bindMatrix = MatrixMultiply(MatrixMultiply(
|
if ((mesh.boneWeights == NULL) || (mesh.boneIndices == NULL) ||
|
||||||
MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z),
|
(mesh.animVertices == NULL) || (mesh.animNormals == NULL)) continue;
|
||||||
QuaternionToMatrix(bindTransform->rotation)),
|
|
||||||
MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z));
|
|
||||||
|
|
||||||
// Convert blended transform to matrix
|
for (int vCounter = 0; vCounter < vertexValuesCount; vCounter += 3)
|
||||||
Matrix blendedMatrix = MatrixMultiply(MatrixMultiply(
|
{
|
||||||
MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z),
|
mesh.animVertices[vCounter] = 0;
|
||||||
QuaternionToMatrix(blended.rotation)),
|
mesh.animVertices[vCounter + 1] = 0;
|
||||||
MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z));
|
mesh.animVertices[vCounter + 2] = 0;
|
||||||
|
if (mesh.animNormals != NULL)
|
||||||
|
{
|
||||||
|
mesh.animNormals[vCounter] = 0;
|
||||||
|
mesh.animNormals[vCounter + 1] = 0;
|
||||||
|
mesh.animNormals[vCounter + 2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate final bone matrix (similar to UpdateModelAnimationBones)
|
// Iterates over 4 bones per vertex
|
||||||
model->boneMatrices[boneId] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix);
|
for (int j = 0; j < 4; j++, boneCounter++)
|
||||||
|
{
|
||||||
|
boneWeight = mesh.boneWeights[boneCounter];
|
||||||
|
boneIndex = mesh.boneIndices[boneCounter];
|
||||||
|
|
||||||
|
// Early stop when no transformation will be applied
|
||||||
|
if (boneWeight == 0.0f) continue;
|
||||||
|
animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] };
|
||||||
|
animVertex = Vector3Transform(animVertex, model->boneMatrices[boneIndex]);
|
||||||
|
mesh.animVertices[vCounter] += animVertex.x*boneWeight;
|
||||||
|
mesh.animVertices[vCounter + 1] += animVertex.y*boneWeight;
|
||||||
|
mesh.animVertices[vCounter + 2] += animVertex.z*boneWeight;
|
||||||
|
bufferUpdateRequired = true;
|
||||||
|
|
||||||
|
// Normals processing
|
||||||
|
// NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
|
||||||
|
if ((mesh.normals != NULL) && (mesh.animNormals != NULL ))
|
||||||
|
{
|
||||||
|
animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] };
|
||||||
|
animNormal = Vector3Transform(animNormal, MatrixTranspose(MatrixInvert(model->boneMatrices[boneIndex])));
|
||||||
|
mesh.animNormals[vCounter] += animNormal.x*boneWeight;
|
||||||
|
mesh.animNormals[vCounter + 1] += animNormal.y*boneWeight;
|
||||||
|
mesh.animNormals[vCounter + 2] += animNormal.z*boneWeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufferUpdateRequired)
|
||||||
|
{
|
||||||
|
// Update GPU vertex buffers with updated data (position + normals)
|
||||||
|
rlUpdateVertexBuffer(mesh.vboId[SHADER_LOC_VERTEX_POSITION], mesh.animVertices, mesh.vertexCount*3*sizeof(float), 0);
|
||||||
|
if (mesh.normals != NULL) rlUpdateVertexBuffer(mesh.vboId[SHADER_LOC_VERTEX_NORMAL], mesh.animNormals, mesh.vertexCount*3*sizeof(float), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 82 KiB |
@ -2,26 +2,26 @@
|
|||||||
*
|
*
|
||||||
* raylib [models] example - animation blending
|
* raylib [models] example - animation blending
|
||||||
*
|
*
|
||||||
* Example complexity rating: [☆☆☆☆] 0/4
|
* Example complexity rating: [★★★★] 4/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Kirandeep (@Kirandeep-Singh-Khehra)
|
* Example contributed by Kirandeep (@Kirandeep-Singh-Khehra) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* WARNING: GPU skinning must be enabled in raylib with a compilation flag,
|
||||||
|
* if not enabled, CPU skinning will be used instead
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
*
|
*
|
||||||
* Copyright (c) 2024 Kirandeep (@Kirandeep-Singh-Khehra)
|
* Copyright (c) 2024-2026 Kirandeep (@Kirandeep-Singh-Khehra) and Ramon Santamaria (@raysan5)
|
||||||
*
|
|
||||||
* Note: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS
|
|
||||||
* Note: This example uses CPU for updating meshes.
|
|
||||||
* For GPU skinning see comments with 'INFO:'.
|
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#define clamp(x,a,b) ((x < a)? a : (x > b)? b : x)
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "raygui.h" // Required for: UI controls
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP)
|
||||||
#define GLSL_VERSION 330
|
#define GLSL_VERSION 330
|
||||||
@ -43,31 +43,58 @@ int main(void)
|
|||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
camera.position = (Vector3){ 8.0f, 8.0f, 8.0f }; // Camera position
|
camera.position = (Vector3){ 6.0f, 6.0f, 6.0f }; // Camera position
|
||||||
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
||||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
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.fovy = 45.0f; // Camera field-of-view Y
|
||||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||||
|
|
||||||
// Load model
|
// Load model
|
||||||
Model characterModel = LoadModel("resources/models/gltf/robot.glb"); // Load character model
|
Model model = LoadModel("resources/models/gltf/robot.glb"); // Load character model
|
||||||
|
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model world position
|
||||||
|
|
||||||
// Load skinning shader
|
// Load skinning shader
|
||||||
|
// WARNING: It requires SUPPORT_GPU_SKINNING enabled on raylib (disabled by default)
|
||||||
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||||
|
|
||||||
// Assign skinning shader to all materials shaders
|
// Assign skinning shader to all materials shaders
|
||||||
for (int i = 0; i < characterModel.materialCount; i++) characterModel.materials[i].shader = skinningShader;
|
//for (int i = 0; i < model.materialCount; i++) model.materials[i].shader = skinningShader;
|
||||||
|
|
||||||
// Load model animations
|
// Load model animations
|
||||||
int animsCount = 0;
|
int animCount = 0;
|
||||||
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount);
|
ModelAnimation *anims = LoadModelAnimations("resources/models/gltf/robot.glb", &animCount);
|
||||||
|
|
||||||
// Define animation variables
|
// Animation playing variables
|
||||||
unsigned int animIndex0 = 0;
|
// NOTE: Two animations are played with a smooth transition between them
|
||||||
unsigned int animIndex1 = 0;
|
int currentAnimPlaying = 0; // Current animation playing (0 o 1)
|
||||||
float animCurrentFrame = 0;
|
int nextAnimToPlay = 1; // Next animation to play (to transition)
|
||||||
float blendFactor = 0.5f;
|
bool animTransition = false; // Flag to register anim transition state
|
||||||
|
|
||||||
|
int animIndex0 = 10; // Current animation playing (walking)
|
||||||
|
float animCurrentFrame0 = 0.0f; // Current animation frame (supporting interpolated frames)
|
||||||
|
float animFrameSpeed0 = 0.5f; // Current animation play speed
|
||||||
|
int animIndex1 = 6; // Next animation to play (running)
|
||||||
|
float animCurrentFrame1 = 0.0f; // Next animation frame (supporting interpolated frames)
|
||||||
|
float animFrameSpeed1 = 0.5f; // Next animation play speed
|
||||||
|
|
||||||
|
float animBlendFactor = 0.0f; // Blend factor from anim0[frame0] --> anim1[frame1], [0.0f..1.0f]
|
||||||
|
// NOTE: 0.0f results in full anim0[] and 1.0f in full anim1[]
|
||||||
|
|
||||||
|
float animBlendTime = 2.0f; // Time to blend from one playing animation to another (in seconds)
|
||||||
|
float animBlendTimeCounter = 0.0f; // Time counter (delta time)
|
||||||
|
|
||||||
|
bool animPause = false; // Pause animation
|
||||||
|
|
||||||
|
// UI required variables
|
||||||
|
char *animNames[64] = { 0 }; // Pointers to animation names for dropdown box
|
||||||
|
for (int i = 0; i < animCount; i++) animNames[i] = anims[i].name;
|
||||||
|
|
||||||
|
bool dropdownEditMode0 = false;
|
||||||
|
bool dropdownEditMode1 = false;
|
||||||
|
float animFrameProgress0 = 0.0f;
|
||||||
|
float animFrameProgress1 = 0.0f;
|
||||||
|
float animBlendProgress = 0.0f;
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -79,23 +106,100 @@ int main(void)
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
// Select current animation
|
if (IsKeyPressed(KEY_P)) animPause = !animPause;
|
||||||
if (IsKeyPressed(KEY_T)) animIndex0 = (animIndex0 + 1)%animsCount;
|
|
||||||
else if (IsKeyPressed(KEY_G)) animIndex0 = (animIndex0 + animsCount - 1)%animsCount;
|
|
||||||
if (IsKeyPressed(KEY_Y)) animIndex1 = (animIndex1 + 1)%animsCount;
|
|
||||||
else if (IsKeyPressed(KEY_H)) animIndex1 = (animIndex1 + animsCount - 1)%animsCount;
|
|
||||||
|
|
||||||
// Select blend factor
|
if (!animPause)
|
||||||
if (IsKeyPressed(KEY_U)) blendFactor = clamp(blendFactor - 0.1, 0.0f, 1.0f);
|
{
|
||||||
else if (IsKeyPressed(KEY_J)) blendFactor = clamp(blendFactor + 0.1, 0.0f, 1.0f);
|
// Start transition from anim0[] to anim1[]
|
||||||
|
if (IsKeyPressed(KEY_SPACE) && !animTransition)
|
||||||
|
{
|
||||||
|
if (currentAnimPlaying == 0)
|
||||||
|
{
|
||||||
|
// Transition anim0 --> anim1
|
||||||
|
nextAnimToPlay = 1;
|
||||||
|
animCurrentFrame1 = 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Transition anim1 --> anim0
|
||||||
|
nextAnimToPlay = 0;
|
||||||
|
animCurrentFrame0 = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// Update animation
|
// Set animation transition
|
||||||
animCurrentFrame += 0.2f;
|
animTransition = true;
|
||||||
|
animBlendTimeCounter = 0.0f;
|
||||||
|
animBlendFactor = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// Update bones
|
if (animTransition)
|
||||||
// Note: Same animation frame index is used below. By default it loops both animations
|
{
|
||||||
UpdateModelAnimationEx(characterModel, modelAnimations[animIndex0], animCurrentFrame,
|
// Playing anim0 and anim1 at the same time
|
||||||
modelAnimations[animIndex1], animCurrentFrame, blendFactor);
|
animCurrentFrame0 += animFrameSpeed0;
|
||||||
|
if (animCurrentFrame0 >= anims[animIndex0].keyframeCount) animCurrentFrame0 = 0.0f;
|
||||||
|
animCurrentFrame1 += animFrameSpeed1;
|
||||||
|
if (animCurrentFrame1 >= anims[animIndex1].keyframeCount) animCurrentFrame1 = 0.0f;
|
||||||
|
|
||||||
|
// Increment blend factor over time to transition from anim0 --> anim1 over time
|
||||||
|
// NOTE: Time blending could be other than linear, using some easing
|
||||||
|
animBlendFactor = animBlendTimeCounter/animBlendTime;
|
||||||
|
animBlendTimeCounter += GetFrameTime();
|
||||||
|
animBlendProgress = animBlendFactor;
|
||||||
|
|
||||||
|
// Update model with animations blending
|
||||||
|
if (nextAnimToPlay == 1)
|
||||||
|
{
|
||||||
|
// Blend anim0 --> anim1
|
||||||
|
UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
|
||||||
|
anims[animIndex1], animCurrentFrame1, animBlendFactor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Blend anim1 --> anim0
|
||||||
|
UpdateModelAnimationEx(model, anims[animIndex1], animCurrentFrame1,
|
||||||
|
anims[animIndex0], animCurrentFrame0, animBlendFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if transition completed
|
||||||
|
if (animBlendFactor > 1.0f)
|
||||||
|
{
|
||||||
|
// Reset frame states
|
||||||
|
if (currentAnimPlaying == 0) animCurrentFrame0 = 0.0f;
|
||||||
|
else if (currentAnimPlaying == 1) animCurrentFrame1 = 0.0f;
|
||||||
|
currentAnimPlaying = nextAnimToPlay; // Update current animation playing
|
||||||
|
|
||||||
|
animBlendFactor = 0.0f; // Reset blend factor
|
||||||
|
animTransition = false; // Exit transition mode
|
||||||
|
animBlendTimeCounter = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Play only one anim, the current one
|
||||||
|
if (currentAnimPlaying == 0)
|
||||||
|
{
|
||||||
|
// Playing anim0 at defined speed
|
||||||
|
animCurrentFrame0 += animFrameSpeed0;
|
||||||
|
if (animCurrentFrame0 >= anims[animIndex0].keyframeCount) animCurrentFrame0 = 0.0f;
|
||||||
|
UpdateModelAnimation(model, anims[animIndex0], animCurrentFrame0);
|
||||||
|
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
|
||||||
|
// anims[animIndex1], animCurrentFrame1, 0.0f); // Same as above, first animation frame blend
|
||||||
|
}
|
||||||
|
else if (currentAnimPlaying == 1)
|
||||||
|
{
|
||||||
|
// Playing anim1 at defined speed
|
||||||
|
animCurrentFrame1 += animFrameSpeed1;
|
||||||
|
if (animCurrentFrame1 >= anims[animIndex1].keyframeCount) animCurrentFrame1 = 0.0f;
|
||||||
|
UpdateModelAnimation(model, anims[animIndex1], animCurrentFrame1);
|
||||||
|
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
|
||||||
|
// anims[animIndex1], animCurrentFrame1, 1.0f); // Same as above, second animation frame blend
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update progress bars values with current frame for each animation
|
||||||
|
animFrameProgress0 = animCurrentFrame0;
|
||||||
|
animFrameProgress1 = animCurrentFrame1;
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -106,16 +210,56 @@ int main(void)
|
|||||||
|
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
|
|
||||||
DrawModel(characterModel, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
|
DrawModel(model, position, 1.0f, WHITE); // Draw animated model
|
||||||
|
|
||||||
DrawGrid(10, 1.0f);
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
DrawText("Use the U/J to adjust blend factor", 10, 10, 20, GRAY);
|
if (animTransition) DrawText("ANIM TRANSITION BLENDING!", 170, 50, 30, BLUE);
|
||||||
DrawText("Use the T/G to switch first animation", 10, 30, 20, GRAY);
|
|
||||||
DrawText("Use the Y/H to switch second animation", 10, 50, 20, GRAY);
|
// Draw UI elements
|
||||||
DrawText(TextFormat("Animations: %s, %s", modelAnimations[animIndex0].name, modelAnimations[animIndex1].name), 10, 70, 20, BLACK);
|
//---------------------------------------------------------------------------------------------
|
||||||
DrawText(TextFormat("Blend Factor: %f", blendFactor), 10, 86, 20, BLACK);
|
if (dropdownEditMode0) GuiDisable();
|
||||||
|
GuiSlider((Rectangle){ 10, 38, 160, 12 },
|
||||||
|
NULL, TextFormat("x%.1f", animFrameSpeed0), &animFrameSpeed0, 0.1f, 2.0f);
|
||||||
|
GuiEnable();
|
||||||
|
if (dropdownEditMode1) GuiDisable();
|
||||||
|
GuiSlider((Rectangle){ GetScreenWidth() - 170.0f, 38, 160, 12 },
|
||||||
|
TextFormat("%.1fx", animFrameSpeed1), NULL, &animFrameSpeed1, 0.1f, 2.0f);
|
||||||
|
GuiEnable();
|
||||||
|
|
||||||
|
// Draw animation selectors for blending transition
|
||||||
|
// NOTE: Transition does not start until requested
|
||||||
|
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 1);
|
||||||
|
if (GuiDropdownBox((Rectangle){ 10, 10, 160, 24 }, TextJoin(animNames, animCount, ";"),
|
||||||
|
&animIndex0, dropdownEditMode0)) dropdownEditMode0 = !dropdownEditMode0;
|
||||||
|
|
||||||
|
// Blending process progress bar
|
||||||
|
if (nextAnimToPlay == 1) GuiSetStyle(PROGRESSBAR, PROGRESS_SIDE, 0); // Left-->Right
|
||||||
|
else GuiSetStyle(PROGRESSBAR, PROGRESS_SIDE, 1); // Right-->Left
|
||||||
|
GuiProgressBar((Rectangle){ 180, 14, 440, 16 }, NULL, NULL, &animBlendProgress, 0.0f, 1.0f);
|
||||||
|
GuiSetStyle(PROGRESSBAR, PROGRESS_SIDE, 0); // Reset to Left-->Right
|
||||||
|
|
||||||
|
if (GuiDropdownBox((Rectangle){ GetScreenWidth() - 170.0f, 10, 160, 24 }, TextJoin(animNames, animCount, ";"),
|
||||||
|
&animIndex1, dropdownEditMode1)) dropdownEditMode1 = !dropdownEditMode1;
|
||||||
|
|
||||||
|
// Draw playing timeline with keyframes for anim0[]
|
||||||
|
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 60.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 0",
|
||||||
|
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
||||||
|
&animFrameProgress0, 0.0f, (float)anims[animIndex0].keyframeCount);
|
||||||
|
for (int i = 0; i < anims[animIndex0].keyframeCount; i++)
|
||||||
|
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex0].keyframeCount)*(float)i),
|
||||||
|
GetScreenHeight() - 60, 1, 20, BLUE);
|
||||||
|
|
||||||
|
// Draw playing timeline with keyframes for anim1[]
|
||||||
|
GuiProgressBar((Rectangle){ 60, GetScreenHeight() - 30.0f, GetScreenWidth() - 180.0f, 20 }, "ANIM 1",
|
||||||
|
TextFormat("FRAME: %.2f / %i", animFrameProgress1, anims[animIndex1].keyframeCount),
|
||||||
|
&animFrameProgress1, 0.0f, (float)anims[animIndex1].keyframeCount);
|
||||||
|
for (int i = 0; i < anims[animIndex1].keyframeCount; i++)
|
||||||
|
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
|
||||||
|
GetScreenHeight() - 30, 1, 20, BLUE);
|
||||||
|
//---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -123,9 +267,8 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadModelAnimations(modelAnimations, animsCount); // Unload model animation
|
UnloadModelAnimations(anims, animCount); // Unload model animation
|
||||||
UnloadModel(characterModel); // Unload model and meshes/material
|
UnloadModel(model); // Unload model and meshes/material
|
||||||
|
|
||||||
UnloadShader(skinningShader); // Unload GPU skinning shader
|
UnloadShader(skinningShader); // Unload GPU skinning shader
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
@ -10,7 +10,6 @@
|
|||||||
*
|
*
|
||||||
* WARNING: GPU skinning must be enabled in raylib with a compilation flag,
|
* WARNING: GPU skinning must be enabled in raylib with a compilation flag,
|
||||||
* if not enabled, CPU skinning will be used instead
|
* if not enabled, CPU skinning will be used instead
|
||||||
* NOTE: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS
|
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 65 KiB |
@ -1,10 +1,10 @@
|
|||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
*
|
*
|
||||||
* raylib [models] example - animation timming
|
* raylib [models] example - animation timing
|
||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
@ -16,7 +16,7 @@
|
|||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#define RAYGUI_IMPLEMENTATION
|
#define RAYGUI_IMPLEMENTATION
|
||||||
#include "raygui.h" // Required for: UI controls
|
#include "raygui.h" // Required for: UI controls
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
@ -28,7 +28,7 @@ int main(void)
|
|||||||
const int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - animation timming");
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - animation timing");
|
||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
@ -43,13 +43,21 @@ int main(void)
|
|||||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model world position
|
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model world position
|
||||||
|
|
||||||
// Load model animations
|
// Load model animations
|
||||||
int animsCount = 0;
|
int animCount = 0;
|
||||||
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount);
|
ModelAnimation *anims = LoadModelAnimations("resources/models/gltf/robot.glb", &animCount);
|
||||||
|
|
||||||
// Animation playing variables
|
// Animation playing variables
|
||||||
unsigned int animIndex = 0; // Current animation playing
|
int animIndex = 10; // Current animation playing
|
||||||
float animCurrentFrame = 0.0f; // Current animation frame (supporting interpolated frames)
|
float animCurrentFrame = 0.0f; // Current animation frame (supporting interpolated frames)
|
||||||
float animFrameSpeed = 0.1f; // Animation play speed
|
float animFrameSpeed = 0.5f; // Animation play speed
|
||||||
|
bool animPause = false; // Pause animation
|
||||||
|
|
||||||
|
// UI required variables
|
||||||
|
char *animNames[64] = { 0 };
|
||||||
|
for (int i = 0; i < animCount; i++) animNames[i] = anims[i].name;
|
||||||
|
|
||||||
|
bool dropdownEditMode = false;
|
||||||
|
float animFrameProgress = 0.0f;
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -61,17 +69,20 @@ int main(void)
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
// Select current animation
|
if (IsKeyPressed(KEY_P)) animPause = !animPause;
|
||||||
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount;
|
|
||||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount;
|
|
||||||
|
|
||||||
// Select animation playing speed
|
if (!animPause && (animIndex < animCount))
|
||||||
if (IsKeyPressed(KEY_RIGHT)) animFrameSpeed += 0.1f;
|
{
|
||||||
else if (IsKeyPressed(KEY_LEFT)) animFrameSpeed -= 0.1f;
|
// Update model animation
|
||||||
|
animCurrentFrame += animFrameSpeed;
|
||||||
|
if (animCurrentFrame >= anims[animIndex].keyframeCount) animCurrentFrame = 0.0f;
|
||||||
|
UpdateModelAnimation(model, anims[animIndex], animCurrentFrame);
|
||||||
|
}
|
||||||
|
|
||||||
// Update model animation
|
// NOTE: Animation and playing speed selected through UI
|
||||||
animCurrentFrame += animFrameSpeed;
|
|
||||||
UpdateModelAnimation(model, modelAnimations[animIndex], animCurrentFrame);
|
// Update progressbar value with current frame
|
||||||
|
animFrameProgress = animCurrentFrame;
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -88,13 +99,22 @@ int main(void)
|
|||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
// Draw UI
|
// Draw UI, select anim and playing speed
|
||||||
//GuiDropdownBox((Rectangle){ 10, 20, 240, 30 }, "text", &animIndex, editMode);
|
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 1);
|
||||||
|
if (GuiDropdownBox((Rectangle){ 10, 10, 140, 24 }, TextJoin(animNames, animCount, ";"),
|
||||||
|
&animIndex, dropdownEditMode)) dropdownEditMode = !dropdownEditMode;
|
||||||
|
|
||||||
DrawText(TextFormat("FRAME SPEED: x%.1f", animFrameSpeed), 10, 40, 20, RED);
|
GuiSlider((Rectangle){ 260, 10, 500, 24 }, "FRAME SPEED: ", TextFormat("x%.1f", animFrameSpeed),
|
||||||
|
&animFrameSpeed, 0.1f, 2.0f);
|
||||||
|
|
||||||
DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY);
|
// Draw playing timeline with keyframes
|
||||||
DrawText(TextFormat("Animation: %s", modelAnimations[animIndex].name), 10, GetScreenHeight() - 20, 10, DARKGRAY);
|
GuiLabel((Rectangle){ 10, GetScreenHeight() - 64.0f, GetScreenWidth() - 20.0f, 24 },
|
||||||
|
TextFormat("CURRENT FRAME: %.2f / %i", animFrameProgress, anims[animIndex].keyframeCount));
|
||||||
|
GuiProgressBar((Rectangle){ 10, GetScreenHeight() - 40.0f, GetScreenWidth() - 20.0f, 24 }, NULL, NULL,
|
||||||
|
&animFrameProgress, 0.0f, (float)anims[animIndex].keyframeCount);
|
||||||
|
for (int i = 0; i < anims[animIndex].keyframeCount; i++)
|
||||||
|
DrawRectangle(10 + (int)(((float)(GetScreenWidth() - 20)/(float)anims[animIndex].keyframeCount)*(float)i),
|
||||||
|
GetScreenHeight() - 40, 1, 24, BLUE);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -102,6 +122,7 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadModelAnimations(anims, animCount); // Unload model animation
|
||||||
UnloadModel(model); // Unload model and meshes/material
|
UnloadModel(model); // Unload model and meshes/material
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
@ -110,5 +131,3 @@ int main(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
examples/models/models_animation_timing.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 22 KiB |
@ -72,6 +72,7 @@ int main(void)
|
|||||||
UpdateCamera(&camera, CAMERA_FIRST_PERSON);
|
UpdateCamera(&camera, CAMERA_FIRST_PERSON);
|
||||||
|
|
||||||
// Handle voxel removal with mouse click
|
// Handle voxel removal with mouse click
|
||||||
|
// This method is quite inefficient. Ray marching through the voxel grid using DDA would be faster, but more complex.
|
||||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||||
{
|
{
|
||||||
// Cast a ray from the screen center (where crosshair would be)
|
// Cast a ray from the screen center (where crosshair would be)
|
||||||
@ -79,12 +80,14 @@ int main(void)
|
|||||||
Ray ray = GetMouseRay(screenCenter, camera);
|
Ray ray = GetMouseRay(screenCenter, camera);
|
||||||
|
|
||||||
// Check ray collision with all voxels
|
// Check ray collision with all voxels
|
||||||
bool voxelRemoved = false;
|
float closestDistance = 99999.0f;
|
||||||
for (int x = 0; (x < WORLD_SIZE) && !voxelRemoved; x++)
|
Vector3 closestVoxelPosition = { -1, -1, -1 };
|
||||||
|
bool voxelFound = false;
|
||||||
|
for (int x = 0; x < WORLD_SIZE; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; (y < WORLD_SIZE) && !voxelRemoved; y++)
|
for (int y = 0; y < WORLD_SIZE; y++)
|
||||||
{
|
{
|
||||||
for (int z = 0; (z < WORLD_SIZE) && !voxelRemoved; z++)
|
for (int z = 0; z < WORLD_SIZE; z++)
|
||||||
{
|
{
|
||||||
if (!voxels[x][y][z]) continue; // Skip empty voxels
|
if (!voxels[x][y][z]) continue; // Skip empty voxels
|
||||||
|
|
||||||
@ -97,14 +100,23 @@ int main(void)
|
|||||||
|
|
||||||
// Check ray-box collision
|
// Check ray-box collision
|
||||||
RayCollision collision = GetRayCollisionBox(ray, box);
|
RayCollision collision = GetRayCollisionBox(ray, box);
|
||||||
if (collision.hit)
|
if (collision.hit && (collision.distance < closestDistance))
|
||||||
{
|
{
|
||||||
voxels[x][y][z] = false; // Remove this voxel
|
closestDistance = collision.distance;
|
||||||
voxelRemoved = true; // Exit all loops
|
closestVoxelPosition = (Vector3){ x, y, z };
|
||||||
|
voxelFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the closest voxel if one was hit
|
||||||
|
if (voxelFound)
|
||||||
|
{
|
||||||
|
voxels[(int)closestVoxelPosition.x]
|
||||||
|
[(int)closestVoxelPosition.y]
|
||||||
|
[(int)closestVoxelPosition.z] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -137,7 +149,7 @@ int main(void)
|
|||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
// Draw reference point for raycasting to delete blocks
|
// Draw reference point for raycasting to delete blocks
|
||||||
DrawCircle(GetRenderWidth()/2, GetScreenHeight()/2, 4, RED);
|
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 4, RED);
|
||||||
|
|
||||||
DrawText("Left-click a voxel to remove it!", 10, 10, 20, DARKGRAY);
|
DrawText("Left-click a voxel to remove it!", 10, 10, 20, DARKGRAY);
|
||||||
DrawText("WASD to move, mouse to look around", 10, 35, 10, GRAY);
|
DrawText("WASD to move, mouse to look around", 10, 35, 10, GRAY);
|
||||||
|
|||||||
@ -116,7 +116,7 @@ int main(void)
|
|||||||
// Update model animation
|
// Update model animation
|
||||||
ModelAnimation anim = modelAnimations[animIndex];
|
ModelAnimation anim = modelAnimations[animIndex];
|
||||||
animCurrentFrame = (animCurrentFrame + 1)%anim.keyframeCount;
|
animCurrentFrame = (animCurrentFrame + 1)%anim.keyframeCount;
|
||||||
UpdateModelAnimation(characterModel, anim, animCurrentFrame);
|
UpdateModelAnimation(characterModel, anim, (float)animCurrentFrame);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -129,7 +129,7 @@ int main(void)
|
|||||||
// Draw character
|
// Draw character
|
||||||
Quaternion characterRotate = QuaternionFromAxisAngle((Vector3){ 0.0f, 1.0f, 0.0f }, angle*DEG2RAD);
|
Quaternion characterRotate = QuaternionFromAxisAngle((Vector3){ 0.0f, 1.0f, 0.0f }, angle*DEG2RAD);
|
||||||
characterModel.transform = MatrixMultiply(QuaternionToMatrix(characterRotate), MatrixTranslate(position.x, position.y, position.z));
|
characterModel.transform = MatrixMultiply(QuaternionToMatrix(characterRotate), MatrixTranslate(position.x, position.y, position.z));
|
||||||
UpdateModelAnimation(characterModel, anim, animCurrentFrame);
|
UpdateModelAnimation(characterModel, anim, (float)animCurrentFrame);
|
||||||
DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);
|
DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);
|
||||||
|
|
||||||
// Draw equipments (hat, sword, shield)
|
// Draw equipments (hat, sword, shield)
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★★★] 4/4
|
* Example complexity rating: [★★★★] 4/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
* Based on previous work by @mrdoob
|
* Based on previous work by @mrdoob
|
||||||
@ -108,7 +108,7 @@ int main(void)
|
|||||||
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
||||||
|
|
||||||
bool showModel = true;
|
bool showModel = true;
|
||||||
Model decalModels[MAX_DECALS] = { 0 };
|
static Model decalModels[MAX_DECALS] = { 0 };
|
||||||
int decalCount = 0;
|
int decalCount = 0;
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -7,11 +7,11 @@
|
|||||||
* NOTE: raylib supports multiple models file formats:
|
* NOTE: raylib supports multiple models file formats:
|
||||||
*
|
*
|
||||||
* - OBJ > Text file format. Must include vertex position-texcoords-normals information,
|
* - OBJ > Text file format. Must include vertex position-texcoords-normals information,
|
||||||
* if files references some .mtl materials file, it will be loaded (or try to)
|
* if .obj references some .mtl materials file, it will be tried to be loaded
|
||||||
* - GLTF > Text/binary file format. Includes lot of information and it could
|
* - GLTF/GLB > Text/binary file formats. Includes lot of information and it could
|
||||||
* also reference external files, raylib will try loading mesh and materials data
|
* also reference external files, mesh and materials data will be tried to be loaded
|
||||||
* - IQM > Binary file format. Includes mesh vertex data but also animation data,
|
* - IQM > Binary file format. Includes mesh vertex data but also animation data,
|
||||||
* raylib can load .iqm animations
|
* meshes and animation data can be loaded
|
||||||
* - VOX > Binary file format. MagikaVoxel mesh format:
|
* - VOX > Binary file format. MagikaVoxel mesh format:
|
||||||
* https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox.txt
|
* https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox.txt
|
||||||
* - M3D > Binary file format. Model 3D format:
|
* - M3D > Binary file format. Model 3D format:
|
||||||
@ -43,10 +43,10 @@ int main(void)
|
|||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
camera.position = (Vector3){ 50.0f, 50.0f, 50.0f }; // Camera position
|
camera.position = (Vector3){ 50.0f, 50.0f, 50.0f }; // Camera position
|
||||||
camera.target = (Vector3){ 0.0f, 10.0f, 0.0f }; // Camera looking at point
|
camera.target = (Vector3){ 0.0f, 12.0f, 0.0f }; // Camera looking at point
|
||||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
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.fovy = 45.0f; // Camera field-of-view Y
|
||||||
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
|
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
|
||||||
|
|
||||||
Model model = LoadModel("resources/models/obj/castle.obj"); // Load model
|
Model model = LoadModel("resources/models/obj/castle.obj"); // Load model
|
||||||
Texture2D texture = LoadTexture("resources/models/obj/castle_diffuse.png"); // Load model texture
|
Texture2D texture = LoadTexture("resources/models/obj/castle_diffuse.png"); // Load model texture
|
||||||
@ -61,8 +61,6 @@ int main(void)
|
|||||||
|
|
||||||
bool selected = false; // Selected object flag
|
bool selected = false; // Selected object flag
|
||||||
|
|
||||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -71,7 +69,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_FIRST_PERSON);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
// Load new models/textures on drag&drop
|
// Load new models/textures on drag&drop
|
||||||
if (IsFileDropped())
|
if (IsFileDropped())
|
||||||
@ -93,7 +91,10 @@ int main(void)
|
|||||||
|
|
||||||
bounds = GetMeshBoundingBox(model.meshes[0]);
|
bounds = GetMeshBoundingBox(model.meshes[0]);
|
||||||
|
|
||||||
// TODO: Move camera position from target enough distance to visualize model properly
|
// Move camera position from target enough distance to visualize model properly
|
||||||
|
camera.position.x = bounds.max.x + 10.0f;
|
||||||
|
camera.position.y = bounds.max.y + 10.0f;
|
||||||
|
camera.position.z = bounds.max.z + 10.0f;
|
||||||
}
|
}
|
||||||
else if (IsFileExtension(droppedFiles.paths[0], ".png")) // Texture file formats supported
|
else if (IsFileExtension(droppedFiles.paths[0], ".png")) // Texture file formats supported
|
||||||
{
|
{
|
||||||
|
|||||||
@ -42,15 +42,17 @@ int main(void)
|
|||||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||||
|
|
||||||
// Load gltf model
|
// Load model
|
||||||
Model model = LoadModel("resources/models/gltf/robot.glb");
|
Model model = LoadModel("resources/models/gltf/robot.glb");
|
||||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model world position
|
||||||
|
|
||||||
// Load gltf model animations
|
// Load model animations
|
||||||
int animsCount = 0;
|
int animCount = 0;
|
||||||
unsigned int animIndex = 0;
|
ModelAnimation *anims = LoadModelAnimations("resources/models/gltf/robot.glb", &animCount);
|
||||||
unsigned int animCurrentFrame = 0;
|
|
||||||
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount);
|
// Animation playing variables
|
||||||
|
unsigned int animIndex = 0; // Current animation playing
|
||||||
|
unsigned int animCurrentFrame = 0; // Current animation frame
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -63,13 +65,12 @@ int main(void)
|
|||||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
// Select current animation
|
// Select current animation
|
||||||
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) animIndex = (animIndex + 1)%animsCount;
|
if (IsKeyPressed(KEY_RIGHT)) animIndex = (animIndex + 1)%animCount;
|
||||||
else if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) animIndex = (animIndex + animsCount - 1)%animsCount;
|
else if (IsKeyPressed(KEY_LEFT)) animIndex = (animIndex + animCount - 1)%animCount;
|
||||||
|
|
||||||
// Update model animation
|
// Update model animation
|
||||||
ModelAnimation anim = modelAnimations[animIndex];
|
animCurrentFrame = (animCurrentFrame + 1)%anims[animIndex].keyframeCount;
|
||||||
animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
|
UpdateModelAnimation(model, anims[animIndex], (float)animCurrentFrame);
|
||||||
UpdateModelAnimation(model, anim, animCurrentFrame);
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -79,12 +80,15 @@ int main(void)
|
|||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
DrawModel(model, position, 1.0f, WHITE); // Draw animated model
|
|
||||||
|
DrawModel(model, position, 1.0f, WHITE);
|
||||||
|
|
||||||
DrawGrid(10, 1.0f);
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
DrawText("Use the LEFT/RIGHT mouse buttons to switch animation", 10, 10, 20, GRAY);
|
DrawText(TextFormat("Current animation: %s", anims[animIndex].name), 10, 40, 20, MAROON);
|
||||||
DrawText(TextFormat("Animation: %s", anim.name), 10, GetScreenHeight() - 20, 10, DARKGRAY);
|
DrawText("Use the LEFT/RIGHT keys to switch animation", 10, 10, 20, GRAY);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -92,7 +96,8 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadModel(model); // Unload model and meshes/material
|
UnloadModelAnimations(anims, animCount); // Unload model animations data
|
||||||
|
UnloadModel(model); // Unload model
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 22 KiB |
@ -8,17 +8,15 @@
|
|||||||
*
|
*
|
||||||
* Example contributed by Culacant (@culacant) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Culacant (@culacant) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
* NOTES: To export an IQM model from blender, make sure it is not posed, the vertices need
|
||||||
|
* to be in the same position as they would be in edit mode and the scale of the models is
|
||||||
|
* set to 0; scaling can be set from the export menu
|
||||||
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2025 Culacant (@culacant) and Ramon Santamaria (@raysan5)
|
* Copyright (c) 2019-2025 Culacant (@culacant) and Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
********************************************************************************************
|
|
||||||
*
|
|
||||||
* NOTE: To export a model from blender, make sure it is not posed, the vertices need to be
|
|
||||||
* in the same position as they would be in edit mode and the scale of your models is
|
|
||||||
* set to 0. Scaling can be done from the export menu
|
|
||||||
*
|
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
@ -38,7 +36,7 @@ int main(void)
|
|||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
|
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
|
||||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
camera.target = (Vector3){ 0.0f, 4.0f, 0.0f }; // Camera looking at point
|
||||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
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.fovy = 45.0f; // Camera field-of-view Y
|
||||||
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
|
camera.projection = CAMERA_PERSPECTIVE; // Camera mode type
|
||||||
@ -46,15 +44,16 @@ int main(void)
|
|||||||
Model model = LoadModel("resources/models/iqm/guy.iqm"); // Load the animated model mesh and basic data
|
Model model = LoadModel("resources/models/iqm/guy.iqm"); // Load the animated model mesh and basic data
|
||||||
Texture2D texture = LoadTexture("resources/models/iqm/guytex.png"); // Load model texture and set material
|
Texture2D texture = LoadTexture("resources/models/iqm/guytex.png"); // Load model texture and set material
|
||||||
SetMaterialTexture(&model.materials[0], MATERIAL_MAP_DIFFUSE, texture); // Set model material map texture
|
SetMaterialTexture(&model.materials[0], MATERIAL_MAP_DIFFUSE, texture); // Set model material map texture
|
||||||
|
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
|
||||||
|
|
||||||
// Load animation data
|
// Load animation data
|
||||||
int animsCount = 0;
|
int animCount = 0;
|
||||||
ModelAnimation *anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm", &animsCount);
|
ModelAnimation *anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm", &animCount);
|
||||||
float animFrameCounter = 0;
|
|
||||||
|
// Animation playing variables
|
||||||
|
unsigned int animIndex = 0; // Current animation playing
|
||||||
|
float animCurrentFrame = 0.0f; // Current animation frame (supporting interpolated frames)
|
||||||
|
|
||||||
DisableCursor(); // Catch cursor
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -66,9 +65,9 @@ int main(void)
|
|||||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
// Play animation when spacebar is held down
|
// Play animation when spacebar is held down
|
||||||
animFrameCounter += 1.0f;
|
animCurrentFrame += 1.0f;
|
||||||
UpdateModelAnimation(model, anims[0], animFrameCounter);
|
UpdateModelAnimation(model, anims[0], animCurrentFrame);
|
||||||
if (animFrameCounter >= anims[0].keyframeCount) animFrameCounter = 0;
|
if (animCurrentFrame >= anims[0].keyframeCount) animCurrentFrame = 0;
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -81,16 +80,11 @@ int main(void)
|
|||||||
|
|
||||||
DrawModelEx(model, position, (Vector3){ 1.0f, 0.0f, 0.0f }, -90.0f, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE);
|
DrawModelEx(model, position, (Vector3){ 1.0f, 0.0f, 0.0f }, -90.0f, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE);
|
||||||
|
|
||||||
for (int i = 0; i < model.skeleton.boneCount; i++)
|
DrawGrid(10, 1.0f);
|
||||||
{
|
|
||||||
//DrawCube(anims[0].keyframePoses[animFrameCounter][i].translation, 0.2f, 0.2f, 0.2f, RED);
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawGrid(10, 1.0f); // Draw a grid
|
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, MAROON);
|
DrawText(TextFormat("Current animation: %s", anims[animIndex].name), 10, 10, 20, MAROON);
|
||||||
DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
@ -99,9 +93,9 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadTexture(texture); // Unload texture
|
UnloadTexture(texture); // Unload texture
|
||||||
UnloadModelAnimations(anims, animsCount); // Unload model animations data
|
UnloadModelAnimations(anims, animCount); // Unload model animations data
|
||||||
UnloadModel(model); // Unload model
|
UnloadModel(model); // Unload model
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 58 KiB |
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
|
static void DrawModelSkeleton(ModelSkeleton skeleton, ModelAnimPose pose, float scale, Color color);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
@ -41,22 +43,17 @@ int main(void)
|
|||||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||||
|
|
||||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
|
||||||
|
|
||||||
char modelFileName[128] = "resources/models/m3d/cesium_man.m3d";
|
|
||||||
bool drawMesh = 1;
|
|
||||||
bool drawSkeleton = 1;
|
|
||||||
bool animPlaying = false; // Store anim state, what to draw
|
|
||||||
|
|
||||||
// Load model
|
// Load model
|
||||||
Model model = LoadModel(modelFileName); // Load the bind-pose model mesh and basic data
|
Model model = LoadModel("resources/models/m3d/cesium_man.m3d"); // Load the animated model mesh and basic data
|
||||||
|
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||||
|
|
||||||
// Load animations
|
// Load animation data
|
||||||
int animsCount = 0;
|
int animCount = 0;
|
||||||
int animFrameCounter = 0, animId = 0;
|
ModelAnimation *anims = LoadModelAnimations("resources/models/m3d/cesium_man.m3d", &animCount);
|
||||||
ModelAnimation *anims = LoadModelAnimations(modelFileName, &animsCount); // Load skeletal animation data
|
|
||||||
|
|
||||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
// Animation playing variables
|
||||||
|
unsigned int animIndex = 0; // Current animation playing
|
||||||
|
float animCurrentFrame = 0.0f; // Current animation frame (supporting interpolated frames)
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
@ -66,38 +63,16 @@ int main(void)
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_FIRST_PERSON);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
if (animsCount)
|
// Select current animation
|
||||||
{
|
if (IsKeyPressed(KEY_RIGHT)) animIndex = (animIndex + 1)%animCount;
|
||||||
// Play animation when spacebar is held down (or step one frame with N)
|
else if (IsKeyPressed(KEY_LEFT)) animIndex = (animIndex + animCount - 1)%animCount;
|
||||||
if (IsKeyDown(KEY_SPACE) || IsKeyPressed(KEY_N))
|
|
||||||
{
|
|
||||||
animFrameCounter++;
|
|
||||||
|
|
||||||
if (animFrameCounter >= anims[animId].frameCount) animFrameCounter = 0;
|
// Update model animation
|
||||||
|
animCurrentFrame += 1.0f;
|
||||||
UpdateModelAnimation(model, anims[animId], animFrameCounter);
|
if (animCurrentFrame >= anims[animIndex].keyframeCount) animCurrentFrame = 0.0f;
|
||||||
animPlaying = true;
|
UpdateModelAnimation(model, anims[animIndex], animCurrentFrame);
|
||||||
}
|
|
||||||
|
|
||||||
// Select animation by pressing C
|
|
||||||
if (IsKeyPressed(KEY_C))
|
|
||||||
{
|
|
||||||
animFrameCounter = 0;
|
|
||||||
animId++;
|
|
||||||
|
|
||||||
if (animId >= (int)animsCount) animId = 0;
|
|
||||||
UpdateModelAnimation(model, anims[animId], 0);
|
|
||||||
animPlaying = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle skeleton drawing
|
|
||||||
if (IsKeyPressed(KEY_B)) drawSkeleton ^= 1;
|
|
||||||
|
|
||||||
// Toggle mesh drawing
|
|
||||||
if (IsKeyPressed(KEY_M)) drawMesh ^= 1;
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
@ -109,52 +84,19 @@ int main(void)
|
|||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
|
|
||||||
// Draw 3d model with texture
|
// Draw 3d model with texture
|
||||||
if (drawMesh) DrawModel(model, position, 1.0f, WHITE);
|
if (!IsKeyDown(KEY_SPACE)) DrawModel(model, position, 1.0f, WHITE);
|
||||||
|
else
|
||||||
// Draw the animated skeleton
|
|
||||||
if (drawSkeleton)
|
|
||||||
{
|
{
|
||||||
// Loop to (boneCount - 1) because the last one is a special "no bone" bone,
|
// Draw the animated skeleton
|
||||||
// needed to workaround buggy models
|
DrawModelSkeleton(model.skeleton, anims[animIndex].keyframePoses[(int)animCurrentFrame], 1.0f, RED);
|
||||||
// without a -1, we would always draw a cube at the origin
|
|
||||||
for (int i = 0; i < model.boneCount - 1; i++)
|
|
||||||
{
|
|
||||||
// By default the model is loaded in bind-pose by LoadModel()
|
|
||||||
// But if UpdateModelAnimation() has been called at least once
|
|
||||||
// then the model is already in animation pose, so we need the animated skeleton
|
|
||||||
if (!animPlaying || !animsCount)
|
|
||||||
{
|
|
||||||
// Display the bind-pose skeleton
|
|
||||||
DrawCube(model.bindPose[i].translation, 0.04f, 0.04f, 0.04f, RED);
|
|
||||||
|
|
||||||
if (model.bones[i].parent >= 0)
|
|
||||||
{
|
|
||||||
DrawLine3D(model.bindPose[i].translation,
|
|
||||||
model.bindPose[model.bones[i].parent].translation, RED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Display the frame-pose skeleton
|
|
||||||
DrawCube(anims[animId].framePoses[animFrameCounter][i].translation, 0.05f, 0.05f, 0.05f, RED);
|
|
||||||
|
|
||||||
if (anims[animId].bones[i].parent >= 0)
|
|
||||||
{
|
|
||||||
DrawLine3D(anims[animId].framePoses[animFrameCounter][i].translation,
|
|
||||||
anims[animId].framePoses[animFrameCounter][anims[animId].bones[i].parent].translation, RED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawGrid(10, 1.0f); // Draw a grid
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, GetScreenHeight() - 80, 10, MAROON);
|
DrawText(TextFormat("Current animation: %s", anims[animIndex].name), 10, 10, 20, LIGHTGRAY);
|
||||||
DrawText("PRESS N to STEP ONE ANIMATION FRAME", 10, GetScreenHeight() - 60, 10, DARKGRAY);
|
DrawText("Press SPACE to draw skeleton", 10, 40, 20, MAROON);
|
||||||
DrawText("PRESS C to CYCLE THROUGH ANIMATIONS", 10, GetScreenHeight() - 40, 10, DARKGRAY);
|
|
||||||
DrawText("PRESS M to toggle MESH, B to toggle SKELETON DRAWING", 10, GetScreenHeight() - 20, 10, DARKGRAY);
|
|
||||||
DrawText("(c) CesiumMan model by KhronosGroup", GetScreenWidth() - 210, GetScreenHeight() - 20, 10, GRAY);
|
DrawText("(c) CesiumMan model by KhronosGroup", GetScreenWidth() - 210, GetScreenHeight() - 20, 10, GRAY);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
@ -163,14 +105,28 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadModelAnimations(anims, animCount); // Unload model animations data
|
||||||
// Unload model animations data
|
UnloadModel(model); // Unload model
|
||||||
UnloadModelAnimations(anims, animsCount);
|
|
||||||
|
|
||||||
UnloadModel(model); // Unload model
|
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw model skeleton
|
||||||
|
static void DrawModelSkeleton(ModelSkeleton skeleton, ModelAnimPose pose, float scale, Color color)
|
||||||
|
{
|
||||||
|
// Loop to (boneCount - 1) because the last one is a special "no bone" bone,
|
||||||
|
// needed to workaround buggy models without a -1, a cube is always drawn at the origin
|
||||||
|
for (int i = 0; i < skeleton.boneCount - 1; i++)
|
||||||
|
{
|
||||||
|
// Display the frame-pose skeleton
|
||||||
|
DrawCube(pose[i].translation, scale*0.05f, scale*0.05f, scale*0.05f, color);
|
||||||
|
|
||||||
|
if (skeleton.bones[i].parent >= 0)
|
||||||
|
{
|
||||||
|
DrawLine3D(pose[i].translation, pose[skeleton.bones[i].parent].translation, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 22 KiB |
@ -25,9 +25,9 @@
|
|||||||
#include "rlights.h"
|
#include "rlights.h"
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP)
|
||||||
#define GLSL_VERSION 330
|
#define GLSL_VERSION 330
|
||||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||||
#define GLSL_VERSION 100
|
#define GLSL_VERSION 100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
@ -130,6 +130,7 @@ int main(void)
|
|||||||
camerarot.y = 0;
|
camerarot.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update camere movement, custom controls
|
||||||
UpdateCameraPro(&camera,
|
UpdateCameraPro(&camera,
|
||||||
(Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward
|
(Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward
|
||||||
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left
|
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left
|
||||||
@ -173,7 +174,7 @@ int main(void)
|
|||||||
DrawText("- MOUSE LEFT BUTTON: CYCLE VOX MODELS", 20, 50, 10, BLUE);
|
DrawText("- MOUSE LEFT BUTTON: CYCLE VOX MODELS", 20, 50, 10, BLUE);
|
||||||
DrawText("- MOUSE MIDDLE BUTTON: ZOOM OR ROTATE CAMERA", 20, 70, 10, BLUE);
|
DrawText("- MOUSE MIDDLE BUTTON: ZOOM OR ROTATE CAMERA", 20, 70, 10, BLUE);
|
||||||
DrawText("- UP-DOWN-LEFT-RIGHT KEYS: MOVE CAMERA", 20, 90, 10, BLUE);
|
DrawText("- UP-DOWN-LEFT-RIGHT KEYS: MOVE CAMERA", 20, 90, 10, BLUE);
|
||||||
DrawText(TextFormat("Model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
|
DrawText(TextFormat("VOX model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 36 KiB |
@ -16,6 +16,7 @@
|
|||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
#include "rlgl.h"
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: rand()
|
#include <stdlib.h> // Required for: rand()
|
||||||
#include <math.h> // Required for: cosf(), sinf()
|
#include <math.h> // Required for: cosf(), sinf()
|
||||||
@ -26,8 +27,9 @@
|
|||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module Functions Declaration
|
// Module Functions Declaration
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Generate mesh using points
|
static Mesh GenMeshPoints(int numPoints); // Generate mesh using points
|
||||||
static Mesh GenMeshPoints(int numPoints);
|
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points
|
||||||
|
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
@ -184,3 +186,30 @@ static Mesh GenMeshPoints(int numPoints)
|
|||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Draw a model points
|
||||||
|
// WARNING: OpenGL ES 2.0 does not support point mode drawing
|
||||||
|
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint)
|
||||||
|
{
|
||||||
|
rlEnablePointMode();
|
||||||
|
rlDisableBackfaceCulling();
|
||||||
|
|
||||||
|
DrawModel(model, position, scale, tint);
|
||||||
|
|
||||||
|
rlEnableBackfaceCulling();
|
||||||
|
rlDisablePointMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a model points
|
||||||
|
// WARNING: OpenGL ES 2.0 does not support point mode drawing
|
||||||
|
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||||
|
{
|
||||||
|
rlEnablePointMode();
|
||||||
|
rlDisableBackfaceCulling();
|
||||||
|
|
||||||
|
DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
|
||||||
|
|
||||||
|
rlEnableBackfaceCulling();
|
||||||
|
rlDisablePointMode();
|
||||||
|
}
|
||||||
|
|||||||
@ -66,8 +66,6 @@ int main(void)
|
|||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
|
||||||
|
|
||||||
earthRotation += (5.0f*rotationSpeed);
|
earthRotation += (5.0f*rotationSpeed);
|
||||||
earthOrbitRotation += (365/360.0f*(5.0f*rotationSpeed)*rotationSpeed);
|
earthOrbitRotation += (365/360.0f*(5.0f*rotationSpeed)*rotationSpeed);
|
||||||
moonRotation += (2.0f*rotationSpeed);
|
moonRotation += (2.0f*rotationSpeed);
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★☆☆☆] 1/4
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Jopestpe (@jopestpe)
|
* Example contributed by Jopestpe (@jopestpe)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Timothy van der Valk (@arceryz) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Timothy van der Valk (@arceryz) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -41,6 +41,9 @@ int main(void)
|
|||||||
|
|
||||||
Model model = LoadModel("resources/models/obj/plane.obj"); // Load model
|
Model model = LoadModel("resources/models/obj/plane.obj"); // Load model
|
||||||
Texture2D texture = LoadTexture("resources/models/obj/plane_diffuse.png"); // Load model texture
|
Texture2D texture = LoadTexture("resources/models/obj/plane_diffuse.png"); // Load model texture
|
||||||
|
|
||||||
|
SetTextureWrap(texture, TEXTURE_WRAP_REPEAT); // Force Repeat to avoid issue on Web version
|
||||||
|
|
||||||
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
|
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
|
||||||
|
|
||||||
float pitch = 0.0f;
|
float pitch = 0.0f;
|
||||||
|
|||||||
@ -357,8 +357,10 @@
|
|||||||
#elif defined(USE_LIBTYPE_SHARED)
|
#elif defined(USE_LIBTYPE_SHARED)
|
||||||
#define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll)
|
#define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll)
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||||
#define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC
|
#define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// Function specifiers definition
|
// Function specifiers definition
|
||||||
#ifndef RAYGUIAPI
|
#ifndef RAYGUIAPI
|
||||||
@ -646,6 +648,7 @@ typedef enum {
|
|||||||
// ProgressBar
|
// ProgressBar
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
||||||
|
PROGRESS_SIDE, // ProgressBar increment side: 0-left->right, 1-right-left
|
||||||
} GuiProgressBarProperty;
|
} GuiProgressBarProperty;
|
||||||
|
|
||||||
// ScrollBar
|
// ScrollBar
|
||||||
@ -3522,7 +3525,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw slider internal progress bar (depends on state)
|
// Draw slider internal progress bar (depends on state)
|
||||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
if (GuiGetStyle(PROGRESSBAR, PROGRESS_SIDE) == 0) // Left-->Right
|
||||||
|
{
|
||||||
|
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||||
|
}
|
||||||
|
else // Right-->Left
|
||||||
|
{
|
||||||
|
progress.x = bounds.x + bounds.width - progress.width - GuiGetStyle(PROGRESSBAR, BORDER_WIDTH);
|
||||||
|
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw left/right text if provided
|
// Draw left/right text if provided
|
||||||
@ -5119,11 +5130,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
|||||||
|
|
||||||
// Get text divided into lines (by line-breaks '\n')
|
// Get text divided into lines (by line-breaks '\n')
|
||||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||||
static char **GetTextLines(const char *text, int *count)
|
static const char **GetTextLines(const char *text, int *count)
|
||||||
{
|
{
|
||||||
#define RAYGUI_MAX_TEXT_LINES 128
|
#define RAYGUI_MAX_TEXT_LINES 128
|
||||||
|
|
||||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||||
|
|
||||||
int textLength = (int)strlen(text);
|
int textLength = (int)strlen(text);
|
||||||
@ -5193,7 +5204,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
|||||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
char **lines = GetTextLines(text, &lineCount);
|
const char **lines = GetTextLines(text, &lineCount);
|
||||||
|
|
||||||
// Text style variables
|
// Text style variables
|
||||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||||
|
|||||||
@ -13,9 +13,9 @@
|
|||||||
| models/vox/chr_knight.vox | ❔ | ❔ | - |
|
| models/vox/chr_knight.vox | ❔ | ❔ | - |
|
||||||
| models/vox/chr_sword.vox | ❔ | ❔ | - |
|
| models/vox/chr_sword.vox | ❔ | ❔ | - |
|
||||||
| models/vox/monu9.vox | ❔ | ❔ | - |
|
| models/vox/monu9.vox | ❔ | ❔ | - |
|
||||||
| billboard.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
| billboard.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||||
| cubicmap.png | [@raysan5](https://github.com/raysan5) | [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/) | - |
|
| cubicmap_atlas.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||||
| heightmap.png | [@raysan5](https://github.com/raysan5) | [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_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) | - |
|
| dresden_square_2k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
|
||||||
|
|||||||
@ -30,7 +30,6 @@
|
|||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
|
||||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
#define GLAD_GLES2_IMPLEMENTATION
|
|
||||||
#include "glad_gles2.h" // Required for: OpenGL functionality
|
#include "glad_gles2.h" // Required for: OpenGL functionality
|
||||||
#define glGenVertexArrays glGenVertexArraysOES
|
#define glGenVertexArrays glGenVertexArraysOES
|
||||||
#define glBindVertexArray glBindVertexArrayOES
|
#define glBindVertexArray glBindVertexArrayOES
|
||||||
|
|||||||
@ -646,6 +646,7 @@ typedef enum {
|
|||||||
// ProgressBar
|
// ProgressBar
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
||||||
|
PROGRESS_SIDE, // ProgressBar increment side: 0-left->right, 1-right-left
|
||||||
} GuiProgressBarProperty;
|
} GuiProgressBarProperty;
|
||||||
|
|
||||||
// ScrollBar
|
// ScrollBar
|
||||||
@ -3522,7 +3523,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw slider internal progress bar (depends on state)
|
// Draw slider internal progress bar (depends on state)
|
||||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
if (GuiGetStyle(PROGRESSBAR, PROGRESS_SIDE) == 0) // Left-->Right
|
||||||
|
{
|
||||||
|
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||||
|
}
|
||||||
|
else // Right-->Left
|
||||||
|
{
|
||||||
|
progress.x = bounds.x + bounds.width - progress.width - GuiGetStyle(PROGRESSBAR, BORDER_WIDTH);
|
||||||
|
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw left/right text if provided
|
// Draw left/right text if provided
|
||||||
@ -5119,11 +5128,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
|||||||
|
|
||||||
// Get text divided into lines (by line-breaks '\n')
|
// Get text divided into lines (by line-breaks '\n')
|
||||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||||
static char **GetTextLines(const char *text, int *count)
|
static const char **GetTextLines(const char *text, int *count)
|
||||||
{
|
{
|
||||||
#define RAYGUI_MAX_TEXT_LINES 128
|
#define RAYGUI_MAX_TEXT_LINES 128
|
||||||
|
|
||||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||||
|
|
||||||
int textLength = (int)strlen(text);
|
int textLength = (int)strlen(text);
|
||||||
@ -5193,7 +5202,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
|||||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
char **lines = GetTextLines(text, &lineCount);
|
const char **lines = GetTextLines(text, &lineCount);
|
||||||
|
|
||||||
// Text style variables
|
// Text style variables
|
||||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||||
|
|||||||
58
examples/shaders/resources/shaders/glsl100/cel.fs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#version 100
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
varying vec3 fragPosition;
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
varying vec3 fragNormal;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
uniform vec3 viewPos;
|
||||||
|
uniform float numBands;
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
int enabled;
|
||||||
|
int type;
|
||||||
|
vec3 position;
|
||||||
|
vec3 target;
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
uniform Light lights[4];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texColor = texture2D(texture0, fragTexCoord);
|
||||||
|
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
|
||||||
|
vec3 norm = normalize(fragNormal);
|
||||||
|
|
||||||
|
float lightAccum = 0.08; // ambient floor
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (lights[i].enabled == 1) // no continue in GLSL ES 1.0
|
||||||
|
{
|
||||||
|
vec3 lightDir;
|
||||||
|
if (lights[i].type == 0)
|
||||||
|
{
|
||||||
|
// Directional: direction is from position toward target.
|
||||||
|
lightDir = normalize(lights[i].position - lights[i].target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Point: direction from surface to light.
|
||||||
|
lightDir = normalize(lights[i].position - fragPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
float NdotL = max(dot(norm, lightDir), 0.0);
|
||||||
|
|
||||||
|
// Quantize NdotL into numBands discrete steps.
|
||||||
|
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
|
||||||
|
lightAccum += quantized * lights[i].color.r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lightAccum = clamp(lightAccum, 0.0, 1.0);
|
||||||
|
gl_FragColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
|
||||||
|
}
|
||||||
47
examples/shaders/resources/shaders/glsl100/cel.vs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#version 100
|
||||||
|
|
||||||
|
attribute vec3 vertexPosition;
|
||||||
|
attribute vec2 vertexTexCoord;
|
||||||
|
attribute vec3 vertexNormal;
|
||||||
|
attribute vec4 vertexColor;
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
uniform mat4 matModel;
|
||||||
|
|
||||||
|
varying vec3 fragPosition;
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
varying vec3 fragNormal;
|
||||||
|
|
||||||
|
mat3 inverse(mat3 m)
|
||||||
|
{
|
||||||
|
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||||
|
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||||
|
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||||
|
float b01 = a22*a11 - a12*a21;
|
||||||
|
float b11 = -a22*a10 + a12*a20;
|
||||||
|
float b21 = a21*a10 - a11*a20;
|
||||||
|
float det = a00*b01 + a01*b11 + a02*b21;
|
||||||
|
return mat3(b01, (-a22*a01 + a02*a21), ( a12*a01 - a02*a11),
|
||||||
|
b11, ( a22*a00 - a02*a20), (-a12*a00 + a02*a10),
|
||||||
|
b21, (-a21*a00 + a01*a20), ( a11*a00 - a01*a10)) / det;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 transpose(mat3 m)
|
||||||
|
{
|
||||||
|
return mat3(m[0][0], m[1][0], m[2][0],
|
||||||
|
m[0][1], m[1][1], m[2][1],
|
||||||
|
m[0][2], m[1][2], m[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||||
|
fragTexCoord = vertexTexCoord;
|
||||||
|
fragColor = vertexColor;
|
||||||
|
|
||||||
|
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||||
|
fragNormal = normalize(normalMatrix * vertexNormal);
|
||||||
|
|
||||||
|
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||||
|
}
|
||||||
@ -52,7 +52,7 @@ void main()
|
|||||||
|
|
||||||
float specCo = 0.0;
|
float specCo = 0.0;
|
||||||
|
|
||||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
|
||||||
|
|
||||||
specular += specCo;
|
specular += specCo;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
#version 100
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(0.05, 0.05, 0.05, 1.0);
|
||||||
|
}
|
||||||
15
examples/shaders/resources/shaders/glsl100/outline_hull.vs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#version 100
|
||||||
|
|
||||||
|
attribute vec3 vertexPosition;
|
||||||
|
attribute vec3 vertexNormal;
|
||||||
|
attribute vec2 vertexTexCoord;
|
||||||
|
attribute vec4 vertexColor;
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
uniform float outlineThickness;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 extruded = vertexPosition + vertexNormal * outlineThickness;
|
||||||
|
gl_Position = mvp * vec4(extruded, 1.0);
|
||||||
|
}
|
||||||
56
examples/shaders/resources/shaders/glsl120/cel.fs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#version 120
|
||||||
|
|
||||||
|
varying vec3 fragPosition;
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
varying vec3 fragNormal;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
uniform vec3 viewPos;
|
||||||
|
uniform float numBands;
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
int enabled;
|
||||||
|
int type;
|
||||||
|
vec3 position;
|
||||||
|
vec3 target;
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
uniform Light lights[4];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texColor = texture2D(texture0, fragTexCoord);
|
||||||
|
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
|
||||||
|
vec3 norm = normalize(fragNormal);
|
||||||
|
|
||||||
|
float lightAccum = 0.08; // ambient floor
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (lights[i].enabled == 1)
|
||||||
|
{
|
||||||
|
vec3 lightDir;
|
||||||
|
if (lights[i].type == 0)
|
||||||
|
{
|
||||||
|
// Directional: direction is from position toward target.
|
||||||
|
lightDir = normalize(lights[i].position - lights[i].target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Point: direction from surface to light.
|
||||||
|
lightDir = normalize(lights[i].position - fragPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
float NdotL = max(dot(norm, lightDir), 0.0);
|
||||||
|
|
||||||
|
// Quantize NdotL into numBands discrete steps.
|
||||||
|
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
|
||||||
|
lightAccum += quantized * lights[i].color.r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lightAccum = clamp(lightAccum, 0.0, 1.0);
|
||||||
|
gl_FragColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
|
||||||
|
}
|
||||||
48
examples/shaders/resources/shaders/glsl120/cel.vs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#version 120
|
||||||
|
|
||||||
|
attribute vec3 vertexPosition;
|
||||||
|
attribute vec2 vertexTexCoord;
|
||||||
|
attribute vec3 vertexNormal;
|
||||||
|
attribute vec4 vertexColor;
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
uniform mat4 matModel;
|
||||||
|
|
||||||
|
varying vec3 fragPosition;
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
varying vec3 fragNormal;
|
||||||
|
|
||||||
|
// inverse() and transpose() are not built-in until GLSL 1.40
|
||||||
|
mat3 inverse(mat3 m)
|
||||||
|
{
|
||||||
|
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||||
|
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||||
|
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||||
|
float b01 = a22*a11 - a12*a21;
|
||||||
|
float b11 = -a22*a10 + a12*a20;
|
||||||
|
float b21 = a21*a10 - a11*a20;
|
||||||
|
float det = a00*b01 + a01*b11 + a02*b21;
|
||||||
|
return mat3(b01, (-a22*a01 + a02*a21), ( a12*a01 - a02*a11),
|
||||||
|
b11, ( a22*a00 - a02*a20), (-a12*a00 + a02*a10),
|
||||||
|
b21, (-a21*a00 + a01*a20), ( a11*a00 - a01*a10)) / det;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 transpose(mat3 m)
|
||||||
|
{
|
||||||
|
return mat3(m[0][0], m[1][0], m[2][0],
|
||||||
|
m[0][1], m[1][1], m[2][1],
|
||||||
|
m[0][2], m[1][2], m[2][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||||
|
fragTexCoord = vertexTexCoord;
|
||||||
|
fragColor = vertexColor;
|
||||||
|
|
||||||
|
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||||
|
fragNormal = normalize(normalMatrix * vertexNormal);
|
||||||
|
|
||||||
|
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||||
|
}
|
||||||
@ -50,7 +50,7 @@ void main()
|
|||||||
|
|
||||||
float specCo = 0.0;
|
float specCo = 0.0;
|
||||||
|
|
||||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
|
||||||
|
|
||||||
specular += specCo;
|
specular += specCo;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
#version 120
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(0.05, 0.05, 0.05, 1.0);
|
||||||
|
}
|
||||||
15
examples/shaders/resources/shaders/glsl120/outline_hull.vs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#version 120
|
||||||
|
|
||||||
|
attribute vec3 vertexPosition;
|
||||||
|
attribute vec3 vertexNormal;
|
||||||
|
attribute vec2 vertexTexCoord;
|
||||||
|
attribute vec4 vertexColor;
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
uniform float outlineThickness;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 extruded = vertexPosition + vertexNormal * outlineThickness;
|
||||||
|
gl_Position = mvp * vec4(extruded, 1.0);
|
||||||
|
}
|
||||||
60
examples/shaders/resources/shaders/glsl330/cel.fs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec3 fragPosition;
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
in vec3 fragNormal;
|
||||||
|
|
||||||
|
// Raylib standard uniforms
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
|
||||||
|
// View position for future specular / fresnel use.
|
||||||
|
uniform vec3 viewPos;
|
||||||
|
|
||||||
|
// Number of discrete toon bands (2 = hard binary, 10 = default, 20 = near-smooth).
|
||||||
|
uniform float numBands;
|
||||||
|
|
||||||
|
// rlights.h compatible light block.
|
||||||
|
struct Light {
|
||||||
|
int enabled;
|
||||||
|
int type; // 0 = directional, 1 = point
|
||||||
|
vec3 position;
|
||||||
|
vec3 target;
|
||||||
|
vec4 color;
|
||||||
|
float attenuation;
|
||||||
|
};
|
||||||
|
uniform Light lights[4];
|
||||||
|
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texColor = texture(texture0, fragTexCoord);
|
||||||
|
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
|
||||||
|
vec3 norm = normalize(fragNormal);
|
||||||
|
|
||||||
|
float lightAccum = 0.08; // ambient floor
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (lights[i].enabled == 0) continue;
|
||||||
|
|
||||||
|
vec3 lightDir;
|
||||||
|
if (lights[i].type == 0) {
|
||||||
|
// Directional: direction is from position toward target.
|
||||||
|
lightDir = normalize(lights[i].position - lights[i].target);
|
||||||
|
} else {
|
||||||
|
// Point: direction from surface to light.
|
||||||
|
lightDir = normalize(lights[i].position - fragPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
float NdotL = max(dot(norm, lightDir), 0.0);
|
||||||
|
|
||||||
|
// Quantize NdotL into numBands discrete steps.
|
||||||
|
// min() guards against NdotL == 1.0 producing an out-of-range index.
|
||||||
|
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
|
||||||
|
lightAccum += quantized * lights[i].color.r;
|
||||||
|
}
|
||||||
|
|
||||||
|
lightAccum = clamp(lightAccum, 0.0, 1.0);
|
||||||
|
finalColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
|
||||||
|
}
|
||||||
25
examples/shaders/resources/shaders/glsl330/cel.vs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
// Raylib standard attributes
|
||||||
|
in vec3 vertexPosition;
|
||||||
|
in vec2 vertexTexCoord;
|
||||||
|
in vec3 vertexNormal;
|
||||||
|
in vec4 vertexColor;
|
||||||
|
|
||||||
|
// Raylib standard uniforms
|
||||||
|
uniform mat4 mvp;
|
||||||
|
uniform mat4 matModel;
|
||||||
|
uniform mat4 matNormal;
|
||||||
|
|
||||||
|
out vec3 fragPosition;
|
||||||
|
out vec2 fragTexCoord;
|
||||||
|
out vec4 fragColor;
|
||||||
|
out vec3 fragNormal;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||||
|
fragTexCoord = vertexTexCoord;
|
||||||
|
fragColor = vertexColor;
|
||||||
|
fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 0.0)));
|
||||||
|
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||||
|
}
|
||||||
@ -37,6 +37,7 @@ struct Light {
|
|||||||
uniform Light lights[MAX_LIGHTS];
|
uniform Light lights[MAX_LIGHTS];
|
||||||
uniform vec4 ambient;
|
uniform vec4 ambient;
|
||||||
uniform vec3 viewPos;
|
uniform vec3 viewPos;
|
||||||
|
uniform vec4 fogColor;
|
||||||
uniform float fogDensity;
|
uniform float fogDensity;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
@ -77,10 +78,6 @@ void main()
|
|||||||
// Fog calculation
|
// Fog calculation
|
||||||
float dist = length(viewPos - fragPosition);
|
float dist = length(viewPos - fragPosition);
|
||||||
|
|
||||||
// these could be parameters...
|
|
||||||
const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);
|
|
||||||
//const float fogDensity = 0.16;
|
|
||||||
|
|
||||||
// Exponential fog
|
// Exponential fog
|
||||||
float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity));
|
float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity));
|
||||||
|
|
||||||
|
|||||||
@ -54,7 +54,7 @@ void main()
|
|||||||
|
|
||||||
float specCo = 0.0;
|
float specCo = 0.0;
|
||||||
|
|
||||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
|
||||||
|
|
||||||
specular += specCo;
|
specular += specCo;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
finalColor = vec4(0.05, 0.05, 0.05, 1.0);
|
||||||
|
}
|
||||||
15
examples/shaders/resources/shaders/glsl330/outline_hull.vs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec3 vertexPosition;
|
||||||
|
in vec3 vertexNormal;
|
||||||
|
in vec2 vertexTexCoord;
|
||||||
|
in vec4 vertexColor;
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
uniform float outlineThickness;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Extrude vertex along its normal to create the hull.
|
||||||
|
vec3 extruded = vertexPosition + vertexNormal * outlineThickness;
|
||||||
|
gl_Position = mvp * vec4(extruded, 1.0);
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Maicon Santana (@maiconpintoabreu) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Maicon Santana (@maiconpintoabreu) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
175
examples/shaders/shaders_cel_shading.c
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shaders] example - cel shading
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
*
|
||||||
|
* Example contributed by Gleb A (@ggrizzly) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2026 Gleb A (@ggrizzly)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
#include "rlgl.h"
|
||||||
|
|
||||||
|
#include <math.h> // Required for: sinf(), cosf()
|
||||||
|
|
||||||
|
#define RLIGHTS_IMPLEMENTATION
|
||||||
|
#include "rlights.h"
|
||||||
|
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
#define GLSL_VERSION 330
|
||||||
|
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||||
|
#define GLSL_VERSION 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - cel shading");
|
||||||
|
|
||||||
|
Camera camera = { 0 };
|
||||||
|
camera.position = (Vector3){ 9.0f, 6.0f, 9.0f };
|
||||||
|
camera.target = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||||
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||||
|
camera.fovy = 45.0f;
|
||||||
|
camera.projection = CAMERA_PERSPECTIVE;
|
||||||
|
|
||||||
|
// Load model
|
||||||
|
Model model = LoadModel("resources/models/old_car_new.glb");
|
||||||
|
|
||||||
|
// Load cel shader
|
||||||
|
Shader celShader = LoadShader(
|
||||||
|
TextFormat("resources/shaders/glsl%i/cel.vs", GLSL_VERSION),
|
||||||
|
TextFormat("resources/shaders/glsl%i/cel.fs", GLSL_VERSION));
|
||||||
|
celShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(celShader, "viewPos");
|
||||||
|
|
||||||
|
// Apply cel shader to model, keep copy of default shader
|
||||||
|
Shader defaultShader = model.materials[0].shader;
|
||||||
|
model.materials[0].shader = celShader;
|
||||||
|
|
||||||
|
// numBands: controls toon quantization steps (2 = hard binary, 20 = near-smooth)
|
||||||
|
float numBands = 10.0f;
|
||||||
|
int numBandsLoc = GetShaderLocation(celShader, "numBands");
|
||||||
|
SetShaderValue(celShader, numBandsLoc, &numBands, SHADER_UNIFORM_FLOAT);
|
||||||
|
|
||||||
|
// Inverted-hull outline shader: draws back faces extruded along normals
|
||||||
|
Shader outlineShader = LoadShader(
|
||||||
|
TextFormat("resources/shaders/glsl%i/outline_hull.vs", GLSL_VERSION),
|
||||||
|
TextFormat("resources/shaders/glsl%i/outline_hull.fs", GLSL_VERSION));
|
||||||
|
int outlineThicknessLoc = GetShaderLocation(outlineShader, "outlineThickness");
|
||||||
|
|
||||||
|
// Single directional white light, angled so toon bands are visible on the model sides.
|
||||||
|
// Spins opposite to CAMERA_ORBITAL (0.5 rad/s) so lighting changes as you watch.
|
||||||
|
Light lights[MAX_LIGHTS] = { 0 };
|
||||||
|
lights[0] = CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 50.0f, 50.0f, 50.0f }, Vector3Zero(), WHITE, celShader);
|
||||||
|
|
||||||
|
bool celEnabled = true;
|
||||||
|
bool outlineEnabled = true;
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose())
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
|
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
|
||||||
|
SetShaderValue(celShader, celShader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
|
||||||
|
|
||||||
|
// [Z] Toggle cel shading on/off
|
||||||
|
if (IsKeyPressed(KEY_Z))
|
||||||
|
{
|
||||||
|
celEnabled = !celEnabled;
|
||||||
|
if (celEnabled) model.materials[0].shader = celShader; // Apply cel shader to model
|
||||||
|
else model.materials[0].shader = defaultShader; // Apply default shader to model
|
||||||
|
}
|
||||||
|
|
||||||
|
// [C] Toggle outline on/off
|
||||||
|
if (IsKeyPressed(KEY_C)) outlineEnabled = !outlineEnabled;
|
||||||
|
|
||||||
|
// [Q/E] Decrease/increase toon band count (press or hold to repeat)
|
||||||
|
if (IsKeyPressed(KEY_E) || IsKeyPressedRepeat(KEY_E)) numBands = Clamp(numBands + 1.0f, 2.0f, 20.0f);
|
||||||
|
if (IsKeyPressed(KEY_Q) || IsKeyPressedRepeat(KEY_Q)) numBands = Clamp(numBands - 1.0f, 2.0f, 20.0f);
|
||||||
|
SetShaderValue(celShader, numBandsLoc, &numBands, SHADER_UNIFORM_FLOAT);
|
||||||
|
|
||||||
|
// Spin light opposite to CAMERA_ORBITAL (0.5 rad/s), angled 45 degrees off vertical
|
||||||
|
float t = (float)GetTime();
|
||||||
|
lights[0].position = (Vector3){ sinf(-t*0.3f)*5.0f, 5.0f, cosf(-t*0.3f)*5.0f };
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(celShader, lights[i]);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode3D(camera);
|
||||||
|
|
||||||
|
if (outlineEnabled)
|
||||||
|
{
|
||||||
|
// Outline pass: cull front faces, draw extruded back faces as silhouette
|
||||||
|
float thickness = 0.005f;
|
||||||
|
SetShaderValue(outlineShader, outlineThicknessLoc, &thickness, SHADER_UNIFORM_FLOAT);
|
||||||
|
|
||||||
|
rlSetCullFace(RL_CULL_FACE_FRONT);
|
||||||
|
|
||||||
|
model.materials[0].shader = outlineShader;
|
||||||
|
|
||||||
|
DrawModel(model, Vector3Zero(), 0.75f, WHITE);
|
||||||
|
|
||||||
|
if (celEnabled) model.materials[0].shader = celShader; // Apply cel shader to model
|
||||||
|
else model.materials[0].shader = defaultShader; // Apply default shader to model
|
||||||
|
|
||||||
|
rlSetCullFace(RL_CULL_FACE_BACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawModel(model, Vector3Zero(), 0.75f, WHITE);
|
||||||
|
DrawSphereEx(lights[0].position, 0.2f, 50, 50, YELLOW); // Light position indicator
|
||||||
|
DrawGrid(10, 10.0f);
|
||||||
|
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
DrawText(TextFormat("Cel: %s [Z]", celEnabled? "ON" : "OFF"), 10, 65, 20, celEnabled? DARKGREEN : DARKGRAY);
|
||||||
|
DrawText(TextFormat("Outline: %s [C]", outlineEnabled? "ON" : "OFF"), 10, 90, 20, outlineEnabled? DARKGREEN : DARKGRAY);
|
||||||
|
DrawText(TextFormat("Bands: %.0f [Q/E]", numBands), 10, 115, 20, DARKGRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadModel(model);
|
||||||
|
UnloadShader(celShader);
|
||||||
|
UnloadShader(outlineShader);
|
||||||
|
|
||||||
|
CloseWindow();
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shaders/shaders_cel_shading.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
@ -7,7 +7,7 @@
|
|||||||
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
|
* 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
|
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Jordi Santonja (@JordSant) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Jordi Santonja (@JordSant) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★★☆] 3/4
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Luís Almeida (@luis605) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Luís Almeida (@luis605) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -72,8 +72,13 @@ int main(void)
|
|||||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||||
|
|
||||||
// Ambient light level
|
// Ambient light level
|
||||||
|
Vector4 ambient = (Vector4){ 0.2f, 0.2f, 0.2f, 1.0f };
|
||||||
int ambientLoc = GetShaderLocation(shader, "ambient");
|
int ambientLoc = GetShaderLocation(shader, "ambient");
|
||||||
SetShaderValue(shader, ambientLoc, (float[4]){ 0.2f, 0.2f, 0.2f, 1.0f }, SHADER_UNIFORM_VEC4);
|
SetShaderValue(shader, ambientLoc, &ambient, SHADER_UNIFORM_VEC4);
|
||||||
|
|
||||||
|
Vector4 fogColor = ColorNormalize(GRAY);
|
||||||
|
int fogColorLoc = GetShaderLocation(shader, "fogColor");
|
||||||
|
SetShaderValue(shader, fogColorLoc, &fogColor, SHADER_UNIFORM_VEC4);
|
||||||
|
|
||||||
float fogDensity = 0.15f;
|
float fogDensity = 0.15f;
|
||||||
int fogDensityLoc = GetShaderLocation(shader, "fogDensity");
|
int fogDensityLoc = GetShaderLocation(shader, "fogDensity");
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
|
* 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
|
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Jordi Santonja (@JordSant) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Jordi Santonja (@JordSant) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3)
|
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3)
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Jordi Santonja (@JordSant)
|
* Example contributed by Jordi Santonja (@JordSant)
|
||||||
* Based on previous work by Josh Colclough (@joshcol9232)
|
* Based on previous work by Josh Colclough (@joshcol9232)
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
|
* 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
|
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by Jeremy Montgomery (@Sir_Irk) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Jeremy Montgomery (@Sir_Irk) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
|
|||||||
@ -65,8 +65,8 @@ int main(void)
|
|||||||
|
|
||||||
// Game of Life logic compute shader
|
// Game of Life logic compute shader
|
||||||
char *golLogicCode = LoadFileText("resources/shaders/glsl430/gol.glsl");
|
char *golLogicCode = LoadFileText("resources/shaders/glsl430/gol.glsl");
|
||||||
unsigned int golLogicShader = rlCompileShader(golLogicCode, RL_COMPUTE_SHADER);
|
unsigned int golLogicShader = rlLoadShader(golLogicCode, RL_COMPUTE_SHADER);
|
||||||
unsigned int golLogicProgram = rlLoadComputeShaderProgram(golLogicShader);
|
unsigned int golLogicProgram = rlLoadShaderProgramCompute(golLogicShader);
|
||||||
UnloadFileText(golLogicCode);
|
UnloadFileText(golLogicCode);
|
||||||
|
|
||||||
// Game of Life logic render shader
|
// Game of Life logic render shader
|
||||||
@ -75,8 +75,8 @@ int main(void)
|
|||||||
|
|
||||||
// Game of Life transfert shader (CPU<->GPU download and upload)
|
// Game of Life transfert shader (CPU<->GPU download and upload)
|
||||||
char *golTransfertCode = LoadFileText("resources/shaders/glsl430/gol_transfert.glsl");
|
char *golTransfertCode = LoadFileText("resources/shaders/glsl430/gol_transfert.glsl");
|
||||||
unsigned int golTransfertShader = rlCompileShader(golTransfertCode, RL_COMPUTE_SHADER);
|
unsigned int golTransfertShader = rlLoadShader(golTransfertCode, RL_COMPUTE_SHADER);
|
||||||
unsigned int golTransfertProgram = rlLoadComputeShaderProgram(golTransfertShader);
|
unsigned int golTransfertProgram = rlLoadShaderProgramCompute(golTransfertShader);
|
||||||
UnloadFileText(golTransfertCode);
|
UnloadFileText(golTransfertCode);
|
||||||
|
|
||||||
// Load shader storage buffer object (SSBO), id returned
|
// Load shader storage buffer object (SSBO), id returned
|
||||||
@ -169,7 +169,9 @@ int main(void)
|
|||||||
rlUnloadShaderBuffer(ssboB);
|
rlUnloadShaderBuffer(ssboB);
|
||||||
rlUnloadShaderBuffer(ssboTransfert);
|
rlUnloadShaderBuffer(ssboTransfert);
|
||||||
|
|
||||||
// Unload compute shader programs
|
// Unload compute shader
|
||||||
|
rlUnloadShader(golLogicShader);
|
||||||
|
rlUnloadShader(golTransfertShader);
|
||||||
rlUnloadShaderProgram(golTransfertProgram);
|
rlUnloadShaderProgram(golTransfertProgram);
|
||||||
rlUnloadShaderProgram(golLogicProgram);
|
rlUnloadShaderProgram(golLogicProgram);
|
||||||
|
|
||||||
|
|||||||
@ -79,8 +79,9 @@ int main(void)
|
|||||||
cube.materials[0].shader = shadowShader;
|
cube.materials[0].shader = shadowShader;
|
||||||
Model robot = LoadModel("resources/models/robot.glb");
|
Model robot = LoadModel("resources/models/robot.glb");
|
||||||
for (int i = 0; i < robot.materialCount; i++) robot.materials[i].shader = shadowShader;
|
for (int i = 0; i < robot.materialCount; i++) robot.materials[i].shader = shadowShader;
|
||||||
|
|
||||||
int animCount = 0;
|
int animCount = 0;
|
||||||
ModelAnimation *robotAnimations = LoadModelAnimations("resources/models/robot.glb", &animCount);
|
ModelAnimation *anims = LoadModelAnimations("resources/models/robot.glb", &animCount);
|
||||||
|
|
||||||
RenderTexture2D shadowMap = LoadShadowmapRenderTexture(SHADOWMAP_RESOLUTION, SHADOWMAP_RESOLUTION);
|
RenderTexture2D shadowMap = LoadShadowmapRenderTexture(SHADOWMAP_RESOLUTION, SHADOWMAP_RESOLUTION);
|
||||||
|
|
||||||
@ -115,8 +116,8 @@ int main(void)
|
|||||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
frameCounter++;
|
frameCounter++;
|
||||||
frameCounter %= (robotAnimations[0].frameCount);
|
frameCounter %= (anims[0].keyframeCount);
|
||||||
UpdateModelAnimation(robot, robotAnimations[0], frameCounter);
|
UpdateModelAnimation(robot, anims[0], (float)frameCounter);
|
||||||
|
|
||||||
// Move light with arrow keys
|
// Move light with arrow keys
|
||||||
const float cameraSpeed = 0.05f;
|
const float cameraSpeed = 0.05f;
|
||||||
@ -190,7 +191,7 @@ int main(void)
|
|||||||
UnloadShader(shadowShader);
|
UnloadShader(shadowShader);
|
||||||
UnloadModel(cube);
|
UnloadModel(cube);
|
||||||
UnloadModel(robot);
|
UnloadModel(robot);
|
||||||
UnloadModelAnimations(robotAnimations, animCount);
|
UnloadModelAnimations(anims, animCount);
|
||||||
UnloadShadowmapRenderTexture(shadowMap);
|
UnloadShadowmapRenderTexture(shadowMap);
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
|||||||
@ -69,7 +69,7 @@ int main(void)
|
|||||||
DrawText("USING DEFAULT SHADER", 20, 40, 10, RED);
|
DrawText("USING DEFAULT SHADER", 20, 40, 10, RED);
|
||||||
|
|
||||||
DrawCircle(80, 120, 35, DARKBLUE);
|
DrawCircle(80, 120, 35, DARKBLUE);
|
||||||
DrawCircleGradient(80, 220, 60, GREEN, SKYBLUE);
|
DrawCircleGradient((Vector2){ 80.0f, 220.0f }, 60, GREEN, SKYBLUE);
|
||||||
DrawCircleLines(80, 340, 80, DARKBLUE);
|
DrawCircleLines(80, 340, 80, DARKBLUE);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,7 @@ int main(void)
|
|||||||
// Set the texture tiling using a shader
|
// Set the texture tiling using a shader
|
||||||
float tiling[2] = { 3.0f, 3.0f };
|
float tiling[2] = { 3.0f, 3.0f };
|
||||||
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/tiling.fs", GLSL_VERSION));
|
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/tiling.fs", GLSL_VERSION));
|
||||||
|
SetTextureWrap(texture, TEXTURE_WRAP_REPEAT);
|
||||||
SetShaderValue(shader, GetShaderLocation(shader, "tiling"), tiling, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, GetShaderLocation(shader, "tiling"), tiling, SHADER_UNIFORM_VEC2);
|
||||||
model.materials[0].shader = shader;
|
model.materials[0].shader = shader;
|
||||||
|
|
||||||
|
|||||||
@ -357,7 +357,9 @@
|
|||||||
#elif defined(USE_LIBTYPE_SHARED)
|
#elif defined(USE_LIBTYPE_SHARED)
|
||||||
#define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll)
|
#define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll)
|
||||||
#endif
|
#endif
|
||||||
#define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC
|
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Function specifiers definition
|
// Function specifiers definition
|
||||||
@ -646,6 +648,7 @@ typedef enum {
|
|||||||
// ProgressBar
|
// ProgressBar
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
||||||
|
PROGRESS_SIDE, // ProgressBar increment side: 0-left->right, 1-right-left
|
||||||
} GuiProgressBarProperty;
|
} GuiProgressBarProperty;
|
||||||
|
|
||||||
// ScrollBar
|
// ScrollBar
|
||||||
@ -3522,7 +3525,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw slider internal progress bar (depends on state)
|
// Draw slider internal progress bar (depends on state)
|
||||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
if (GuiGetStyle(PROGRESSBAR, PROGRESS_SIDE) == 0) // Left-->Right
|
||||||
|
{
|
||||||
|
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||||
|
}
|
||||||
|
else // Right-->Left
|
||||||
|
{
|
||||||
|
progress.x = bounds.x + bounds.width - progress.width - GuiGetStyle(PROGRESSBAR, BORDER_WIDTH);
|
||||||
|
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw left/right text if provided
|
// Draw left/right text if provided
|
||||||
@ -5119,11 +5130,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
|||||||
|
|
||||||
// Get text divided into lines (by line-breaks '\n')
|
// Get text divided into lines (by line-breaks '\n')
|
||||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||||
static char **GetTextLines(const char *text, int *count)
|
static const char **GetTextLines(const char *text, int *count)
|
||||||
{
|
{
|
||||||
#define RAYGUI_MAX_TEXT_LINES 128
|
#define RAYGUI_MAX_TEXT_LINES 128
|
||||||
|
|
||||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||||
|
|
||||||
int textLength = (int)strlen(text);
|
int textLength = (int)strlen(text);
|
||||||
@ -5193,7 +5204,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
|||||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||||
int lineCount = 0;
|
int lineCount = 0;
|
||||||
char **lines = GetTextLines(text, &lineCount);
|
const char **lines = GetTextLines(text, &lineCount);
|
||||||
|
|
||||||
// Text style variables
|
// Text style variables
|
||||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||||
*
|
*
|
||||||
* Example contributed by David Buzatto (@davidbuzatto) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by David Buzatto (@davidbuzatto) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
@ -17,15 +17,19 @@
|
|||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h> // Required for: malloc(), free()
|
||||||
#include <math.h>
|
#include <math.h> // Required for: hypot()
|
||||||
|
|
||||||
#define MAX_BALLS 5000 // Maximum quantity of balls
|
#define MAX_BALLS 5000 // Maximum quantity of balls
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Ball data type
|
||||||
typedef struct Ball {
|
typedef struct Ball {
|
||||||
Vector2 pos; // Position
|
Vector2 position;
|
||||||
Vector2 vel; // Velocity
|
Vector2 speed;
|
||||||
Vector2 ppos; // Previous position
|
Vector2 prevPosition;
|
||||||
float radius;
|
float radius;
|
||||||
float friction;
|
float friction;
|
||||||
float elasticity;
|
float elasticity;
|
||||||
@ -45,24 +49,27 @@ int main(void)
|
|||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
|
||||||
|
|
||||||
Ball balls[MAX_BALLS] = {{
|
Ball *balls = (Ball*)RL_MALLOC(sizeof(Ball)*MAX_BALLS);
|
||||||
.pos = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
|
|
||||||
.vel = { 200, 200 },
|
// Init first ball in the array
|
||||||
.ppos = { 0 },
|
balls[0] = (Ball){
|
||||||
|
.position = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
|
||||||
|
.speed = { 200, 200 },
|
||||||
|
.prevPosition = { 0 },
|
||||||
.radius = 40,
|
.radius = 40,
|
||||||
.friction = 0.99f,
|
.friction = 0.99f,
|
||||||
.elasticity = 0.9f,
|
.elasticity = 0.9f,
|
||||||
.color = BLUE,
|
.color = BLUE,
|
||||||
.grabbed = false
|
.grabbed = false
|
||||||
}};
|
};
|
||||||
|
|
||||||
int ballCount = 1;
|
int ballCount = 1;
|
||||||
Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed
|
Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed
|
||||||
Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd
|
Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd
|
||||||
|
|
||||||
float gravity = 100; // World gravity
|
float gravity = 100; // World gravity
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
@ -79,8 +86,8 @@ int main(void)
|
|||||||
for (int i = ballCount - 1; i >= 0; i--)
|
for (int i = ballCount - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
Ball *ball = &balls[i];
|
Ball *ball = &balls[i];
|
||||||
pressOffset.x = mousePos.x - ball->pos.x;
|
pressOffset.x = mousePos.x - ball->position.x;
|
||||||
pressOffset.y = mousePos.y - ball->pos.y;
|
pressOffset.y = mousePos.y - ball->position.y;
|
||||||
|
|
||||||
// If the distance between the ball position and the mouse press position
|
// If the distance between the ball position and the mouse press position
|
||||||
// is less than or equal to the ball radius, the event occurred inside the ball
|
// is less than or equal to the ball radius, the event occurred inside the ball
|
||||||
@ -109,9 +116,9 @@ int main(void)
|
|||||||
if (ballCount < MAX_BALLS)
|
if (ballCount < MAX_BALLS)
|
||||||
{
|
{
|
||||||
balls[ballCount++] = (Ball){
|
balls[ballCount++] = (Ball){
|
||||||
.pos = mousePos,
|
.position = mousePos,
|
||||||
.vel = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) },
|
.speed = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) },
|
||||||
.ppos = { 0 },
|
.prevPosition = { 0 },
|
||||||
.radius = 20.0f + (float)GetRandomValue(0, 30),
|
.radius = 20.0f + (float)GetRandomValue(0, 30),
|
||||||
.friction = 0.99f,
|
.friction = 0.99f,
|
||||||
.elasticity = 0.9f,
|
.elasticity = 0.9f,
|
||||||
@ -126,7 +133,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < ballCount; i++)
|
for (int i = 0; i < ballCount; i++)
|
||||||
{
|
{
|
||||||
if (!balls[i].grabbed) balls[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) };
|
if (!balls[i].grabbed) balls[i].speed = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,49 +149,49 @@ int main(void)
|
|||||||
if (!ball->grabbed)
|
if (!ball->grabbed)
|
||||||
{
|
{
|
||||||
// Ball repositioning using the velocity
|
// Ball repositioning using the velocity
|
||||||
ball->pos.x += ball->vel.x * delta;
|
ball->position.x += ball->speed.x * delta;
|
||||||
ball->pos.y += ball->vel.y * delta;
|
ball->position.y += ball->speed.y * delta;
|
||||||
|
|
||||||
// Does the ball hit the screen right boundary?
|
// Does the ball hit the screen right boundary?
|
||||||
if ((ball->pos.x + ball->radius) >= screenWidth)
|
if ((ball->position.x + ball->radius) >= screenWidth)
|
||||||
{
|
{
|
||||||
ball->pos.x = screenWidth - ball->radius; // Ball repositioning
|
ball->position.x = screenWidth - ball->radius; // Ball repositioning
|
||||||
ball->vel.x = -ball->vel.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit
|
ball->speed.x = -ball->speed.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit
|
||||||
}
|
}
|
||||||
// Does the ball hit the screen left boundary?
|
// Does the ball hit the screen left boundary?
|
||||||
else if ((ball->pos.x - ball->radius) <= 0)
|
else if ((ball->position.x - ball->radius) <= 0)
|
||||||
{
|
{
|
||||||
ball->pos.x = ball->radius;
|
ball->position.x = ball->radius;
|
||||||
ball->vel.x = -ball->vel.x*ball->elasticity;
|
ball->speed.x = -ball->speed.x*ball->elasticity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The same for y axis
|
// The same for y axis
|
||||||
if ((ball->pos.y + ball->radius) >= screenHeight)
|
if ((ball->position.y + ball->radius) >= screenHeight)
|
||||||
{
|
{
|
||||||
ball->pos.y = screenHeight - ball->radius;
|
ball->position.y = screenHeight - ball->radius;
|
||||||
ball->vel.y = -ball->vel.y*ball->elasticity;
|
ball->speed.y = -ball->speed.y*ball->elasticity;
|
||||||
}
|
}
|
||||||
else if ((ball->pos.y - ball->radius) <= 0)
|
else if ((ball->position.y - ball->radius) <= 0)
|
||||||
{
|
{
|
||||||
ball->pos.y = ball->radius;
|
ball->position.y = ball->radius;
|
||||||
ball->vel.y = -ball->vel.y*ball->elasticity;
|
ball->speed.y = -ball->speed.y*ball->elasticity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Friction makes the ball lose 1% of its velocity each frame
|
// Friction makes the ball lose 1% of its velocity each frame
|
||||||
ball->vel.x = ball->vel.x*ball->friction;
|
ball->speed.x = ball->speed.x*ball->friction;
|
||||||
// Gravity affects only the y axis
|
// Gravity affects only the y axis
|
||||||
ball->vel.y = ball->vel.y*ball->friction + gravity;
|
ball->speed.y = ball->speed.y*ball->friction + gravity;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Ball repositioning using the mouse position
|
// Ball repositioning using the mouse position
|
||||||
ball->pos.x = mousePos.x - pressOffset.x;
|
ball->position.x = mousePos.x - pressOffset.x;
|
||||||
ball->pos.y = mousePos.y - pressOffset.y;
|
ball->position.y = mousePos.y - pressOffset.y;
|
||||||
|
|
||||||
// While the ball is grabbed, recalculates its velocity
|
// While the ball is grabbed, recalculates its velocity
|
||||||
ball->vel.x = (ball->pos.x - ball->ppos.x)/delta;
|
ball->speed.x = (ball->position.x - ball->prevPosition.x)/delta;
|
||||||
ball->vel.y = (ball->pos.y - ball->ppos.y)/delta;
|
ball->speed.y = (ball->position.y - ball->prevPosition.y)/delta;
|
||||||
ball->ppos = ball->pos;
|
ball->prevPosition = ball->position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -197,8 +204,8 @@ int main(void)
|
|||||||
|
|
||||||
for (int i = 0; i < ballCount; i++)
|
for (int i = 0; i < ballCount; i++)
|
||||||
{
|
{
|
||||||
DrawCircleV(balls[i].pos, balls[i].radius, balls[i].color);
|
DrawCircleV(balls[i].position, balls[i].radius, balls[i].color);
|
||||||
DrawCircleLinesV(balls[i].pos, balls[i].radius, BLACK);
|
DrawCircleLinesV(balls[i].position, balls[i].radius, BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawText("grab a ball by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY);
|
DrawText("grab a ball by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY);
|
||||||
@ -214,6 +221,7 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
RL_FREE(balls);
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||