Merge branch 'master' into master
6
.github/workflows/build_android.yml
vendored
|
|
@ -84,8 +84,10 @@ jobs:
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NAME }}.tar.gz
|
name: ${{ env.RELEASE_NAME }}
|
||||||
path: ./build/${{ env.RELEASE_NAME }}.tar.gz
|
path: |
|
||||||
|
./build/${{ env.RELEASE_NAME }}
|
||||||
|
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||||
|
|
||||||
- name: Upload Artifact to Release
|
- name: Upload Artifact to Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
|
|
|
||||||
6
.github/workflows/build_linux.yml
vendored
|
|
@ -114,8 +114,10 @@ jobs:
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NAME }}.tar.gz
|
name: ${{ env.RELEASE_NAME }}
|
||||||
path: ./build/${{ env.RELEASE_NAME }}.tar.gz
|
path: |
|
||||||
|
./build/${{ env.RELEASE_NAME }}
|
||||||
|
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||||
|
|
||||||
- name: Upload Artifact to Release
|
- name: Upload Artifact to Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
|
|
|
||||||
6
.github/workflows/build_macos.yml
vendored
|
|
@ -101,8 +101,10 @@ jobs:
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NAME }}.tar.gz
|
name: ${{ env.RELEASE_NAME }}
|
||||||
path: ./build/${{ env.RELEASE_NAME }}.tar.gz
|
path: |
|
||||||
|
./build/${{ env.RELEASE_NAME }}
|
||||||
|
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||||
|
|
||||||
- name: Upload Artifact to Release
|
- name: Upload Artifact to Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
|
|
|
||||||
6
.github/workflows/build_webassembly.yml
vendored
|
|
@ -71,8 +71,10 @@ jobs:
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NAME }}.zip
|
name: ${{ env.RELEASE_NAME }}
|
||||||
path: ./build/${{ env.RELEASE_NAME }}.zip
|
path: |
|
||||||
|
./build/${{ env.RELEASE_NAME }}
|
||||||
|
!./build/${{ env.RELEASE_NAME }}.zip
|
||||||
|
|
||||||
- name: Upload Artifact to Release
|
- name: Upload Artifact to Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
|
|
|
||||||
6
.github/workflows/build_windows.yml
vendored
|
|
@ -142,8 +142,10 @@ jobs:
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ env.RELEASE_NAME }}.zip
|
name: ${{ env.RELEASE_NAME }}
|
||||||
path: ./build/${{ env.RELEASE_NAME }}.zip
|
path: |
|
||||||
|
./build/${{ env.RELEASE_NAME }}
|
||||||
|
!./build/${{ env.RELEASE_NAME }}.zip
|
||||||
|
|
||||||
- name: Upload Artifact to Release
|
- name: Upload Artifact to Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
|
|
|
||||||
4
.github/workflows/parse_api.yml
vendored
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
- name: Diff parse files
|
- name: Diff parse files
|
||||||
id: diff
|
id: diff
|
||||||
run: |
|
run: |
|
||||||
git add -N tools/rlparser
|
git add -N tools/rlparser/output
|
||||||
git diff --name-only --exit-code
|
git diff --name-only --exit-code
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
|
|
@ -32,6 +32,6 @@ jobs:
|
||||||
set -x
|
set -x
|
||||||
git config user.name "github-actions[bot]"
|
git config user.name "github-actions[bot]"
|
||||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
git add tools/rlparser
|
git add tools/rlparser/output
|
||||||
git commit -m "rlparser: update raylib_api.* by CI"
|
git commit -m "rlparser: update raylib_api.* by CI"
|
||||||
git push
|
git push
|
||||||
|
|
|
||||||
7
.github/workflows/update_examples.yml
vendored
|
|
@ -29,8 +29,9 @@ jobs:
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Build and run rexm tool (requires GNU Makefile)
|
- name: Build and run rexm tool (requires GNU Makefile)
|
||||||
# "rexm update" validates and updates all required examples in raylib and even raylib.com repos,
|
# "rexm validate" validates examples collection, looking for inconsistencies, it does not rebuild examples
|
||||||
# note that it calls examples/Makefile.Web internally, so it requires [make] tool available
|
# "rexm update" validates and updates all examples with inconsistencies, pushing fixes to raylib and raylib.com repos
|
||||||
|
# note that rexm calls examples/Makefile.Web internally, so it requires [make] tool available
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update && sudo apt-get install -y libopengl0 libglu1-mesa libx11-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libgl1-mesa-dev libglu1-mesa-dev
|
sudo apt-get update && sudo apt-get install -y libopengl0 libglu1-mesa libx11-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libgl1-mesa-dev libglu1-mesa-dev
|
||||||
cd "${{ github.workspace }}/src"
|
cd "${{ github.workspace }}/src"
|
||||||
|
|
@ -47,7 +48,7 @@ jobs:
|
||||||
export REXM_EXAMPLES_COLLECTION_FILE_PATH="${{ github.workspace }}/examples/examples_list.txt"
|
export REXM_EXAMPLES_COLLECTION_FILE_PATH="${{ github.workspace }}/examples/examples_list.txt"
|
||||||
export REXM_EXAMPLES_VS2022_SLN_FILE="${{ github.workspace }}/projects/VS2022/raylib.sln"
|
export REXM_EXAMPLES_VS2022_SLN_FILE="${{ github.workspace }}/projects/VS2022/raylib.sln"
|
||||||
export EMSDK_PATH="${{ github.workspace }}/emsdk-cache/emsdk-main"
|
export EMSDK_PATH="${{ github.workspace }}/emsdk-cache/emsdk-main"
|
||||||
./rexm update
|
./rexm validate
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Commit changes to raylib repo (DISABLED)
|
- name: Commit changes to raylib repo (DISABLED)
|
||||||
|
|
|
||||||
12
.gitignore
vendored
|
|
@ -58,14 +58,23 @@ packages/
|
||||||
*.h.pch
|
*.h.pch
|
||||||
./*.obj
|
./*.obj
|
||||||
|
|
||||||
|
# Ignore SDL libs for testing
|
||||||
|
src/external/SDL2
|
||||||
|
src/external/SDL3
|
||||||
|
|
||||||
# Emscripten
|
# Emscripten
|
||||||
emsdk
|
emsdk
|
||||||
|
|
||||||
# Ignore wasm data in examples/
|
# Ignore wasm data in examples/
|
||||||
|
examples/**/*
|
||||||
|
!examples/**/*.*
|
||||||
|
!examples/**/*/
|
||||||
|
examples/**/*.exe
|
||||||
examples/**/*.wasm
|
examples/**/*.wasm
|
||||||
examples/**/*.data
|
examples/**/*.data
|
||||||
examples/**/*.js
|
examples/**/*.js
|
||||||
examples/**/*.html
|
examples/**/*.html
|
||||||
|
examples/**/logs/*
|
||||||
|
|
||||||
# Ignore files build by xcode
|
# Ignore files build by xcode
|
||||||
*.mode*v*
|
*.mode*v*
|
||||||
|
|
@ -115,7 +124,8 @@ build-*/
|
||||||
docgen_tmp/
|
docgen_tmp/
|
||||||
|
|
||||||
# Tools stuff
|
# Tools stuff
|
||||||
tools/parser/raylib_parser
|
tools/parser/rlparser.exe
|
||||||
|
tools/parser/rlparser
|
||||||
tools/rexm/rexm.exe
|
tools/rexm/rexm.exe
|
||||||
tools/rexm/rexm
|
tools/rexm/rexm
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||||
| [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
|
| [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
|
||||||
| [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 |
|
| [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 |
|
||||||
| [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 |
|
| [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 |
|
||||||
|
| [chicken-raylib](https://github.com/meowstr/chicken-raylib) | 5.5 | [CHICKEN Scheme](https://wiki.call-cc.org) | MIT |
|
||||||
| [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT |
|
| [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT |
|
||||||
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 |
|
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 |
|
||||||
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
|
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
|
||||||
|
|
@ -28,9 +29,12 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||||
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
|
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
|
||||||
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
|
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
|
||||||
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib |
|
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib |
|
||||||
|
| [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-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) | 4.5 | [Factor](https://factorcode.org) | BSD |
|
||||||
| [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 |
|
||||||
| [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 |
|
||||||
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.5** | [Go](https://golang.org) | Zlib |
|
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.5** | [Go](https://golang.org) | Zlib |
|
||||||
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
|
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
|
||||||
|
|
@ -82,6 +86,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||||
| [raylib-v](https://github.com/vlang/raylib) | 5.5 | [V](https://vlang.io) | MIT/Unlicense |
|
| [raylib-v](https://github.com/vlang/raylib) | 5.5 | [V](https://vlang.io) | MIT/Unlicense |
|
||||||
| [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib |
|
| [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib |
|
||||||
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **5.0** | [Vala](https://vala.dev) | Zlib |
|
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **5.0** | [Vala](https://vala.dev) | Zlib |
|
||||||
|
| [raylib-wave](https://github.com/wavefnd/raylib-wave) | **auto** |[Wave](http://wave-lang.dev) | Zlib |
|
||||||
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
|
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
|
||||||
| [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **5.6-dev** | [Zig](https://ziglang.org) | MIT |
|
| [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **5.6-dev** | [Zig](https://ziglang.org) | MIT |
|
||||||
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT |
|
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT |
|
||||||
|
|
@ -90,6 +95,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||||
| [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD |
|
| [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD |
|
||||||
| [raylib-bqn](https://github.com/Brian-ED/raylib-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
| [raylib-bqn](https://github.com/Brian-ED/raylib-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
||||||
| [rayjs](https://github.com/mode777/rayjs) | 4.6-dev | [QuickJS](https://bellard.org/quickjs) | MIT |
|
| [rayjs](https://github.com/mode777/rayjs) | 4.6-dev | [QuickJS](https://bellard.org/quickjs) | MIT |
|
||||||
|
| [rayjule](https://github.com/SabeDoesThings/rayjule) | **5.5** | [Jule](https://jule.dev/) | MIT |
|
||||||
| [raylib-raku](https://github.com/vushu/raylib-raku) | **auto** | [Raku](https://www.raku.org) | Artistic License 2.0 |
|
| [raylib-raku](https://github.com/vushu/raylib-raku) | **auto** | [Raku](https://www.raku.org) | Artistic License 2.0 |
|
||||||
| [Raylib.lean](https://github.com/KislyjKisel/Raylib.lean) | **5.5-dev** | [Lean4](https://lean-lang.org) | BSD-3-Clause |
|
| [Raylib.lean](https://github.com/KislyjKisel/Raylib.lean) | **5.5-dev** | [Lean4](https://lean-lang.org) | BSD-3-Clause |
|
||||||
| [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain |
|
| [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain |
|
||||||
|
|
@ -98,6 +104,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||||
| [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/) | **???** |
|
||||||
|
|
||||||
|
|
||||||
### Utility Wrapers
|
### Utility Wrapers
|
||||||
|
|
||||||
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's paradigm.
|
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's paradigm.
|
||||||
|
|
|
||||||
|
|
@ -565,7 +565,7 @@ Detailed changes:
|
||||||
[rtext] ADDED: SetTextLineSpacing() to define line breaks text drawing spacing by @raysan5
|
[rtext] ADDED: SetTextLineSpacing() to define line breaks text drawing spacing by @raysan5
|
||||||
[rtext] RENAMED: LoadFont*() parameter names for consistency and coherence by @raysan5
|
[rtext] RENAMED: LoadFont*() parameter names for consistency and coherence by @raysan5
|
||||||
[rtext] REVIEWED: GetCodepointCount(), ignore unused return value of GetCodepointNext by @ashn-dot-dev
|
[rtext] REVIEWED: GetCodepointCount(), ignore unused return value of GetCodepointNext by @ashn-dot-dev
|
||||||
[rtext] REVIEWED: TextFormat() warn user if buffer overflow occured (#3399) by @Murlocohol
|
[rtext] REVIEWED: TextFormat() warn user if buffer overflow occurred (#3399) by @Murlocohol
|
||||||
[rtext] REVIEWED: TextFormat(), added "..." for truncation (#3366) by @raysan5
|
[rtext] REVIEWED: TextFormat(), added "..." for truncation (#3366) by @raysan5
|
||||||
[rtext] REVIEWED: GetGlyphIndex() (#3000) by @raysan5
|
[rtext] REVIEWED: GetGlyphIndex() (#3000) by @raysan5
|
||||||
[rtext] REVIEWED: GetCodepointNext() to return default value by @chocolate42
|
[rtext] REVIEWED: GetCodepointNext() to return default value by @chocolate42
|
||||||
|
|
|
||||||
|
|
@ -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;Android;Raspberry Pi;DRM;SDL" "Platform to build for.")
|
enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM;SDL;RGFW" "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?")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ while (!WindowShouldClose())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always use accumulators as `x++` instead of `++x`
|
||||||
for (int i = 0; i < NUM_VALUES; i++) printf("%i", i);
|
for (int i = 0; i < NUM_VALUES; i++) printf("%i", i);
|
||||||
|
|
||||||
// Be careful with the switch formatting!
|
// Be careful with the switch formatting!
|
||||||
|
|
|
||||||
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
|
Copyright (c) 2013-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.
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ contributors
|
||||||
------------
|
------------
|
||||||
|
|
||||||
<a href="https://github.com/raysan5/raylib/graphs/contributors">
|
<a href="https://github.com/raysan5/raylib/graphs/contributors">
|
||||||
<img src="https://contrib.rocks/image?repo=raysan5/raylib&max=500&columns=20&anon=1" />
|
<img src="https://contrib.rocks/image?repo=raysan5/raylib&max=800&columns=24&anon=0" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
license
|
license
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ _Current version of raylib is complete and functional but there is always room f
|
||||||
|
|
||||||
**raylib 5.x**
|
**raylib 5.x**
|
||||||
- [ ] `rcore`: Support additional platforms: iOS, consoles?
|
- [ ] `rcore`: Support additional platforms: iOS, consoles?
|
||||||
- [ ] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK
|
- [x] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK
|
||||||
- [ ] `rlgl`: Review GLSL shaders naming conventions for consistency
|
- [ ] `rlgl`: Review GLSL shaders naming conventions for consistency
|
||||||
- [ ] `textures`: Improve compressed textures support, loading and saving
|
- [ ] `textures`: Improve compressed textures support, loading and saving
|
||||||
- [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
|
- [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
|
||||||
- [ ] `raudio`: Implement miniaudio high-level provided features
|
- [ ] `raudio`: Implement miniaudio high-level provided features
|
||||||
- [ ] `examples`: Review all examples, add more and better code explanations
|
- [x] `examples`: Review all examples, add more and better code explanations
|
||||||
- [ ] Software renderer backend? Maybe using `Image` provided API
|
- [x] Software renderer backend? Maybe using `Image` provided API
|
||||||
|
|
||||||
**raylib 4.x**
|
**raylib 4.x**
|
||||||
- [x] Split core module into separate platforms?
|
- [x] Split core module into separate platforms?
|
||||||
|
|
|
||||||
18
SECURITY.md
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
Most considerations of errors and defects can be handled using the project Issues and/or Discussions.
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| 6.0.x | :white_check_mark: |
|
||||||
|
| < 5.5 | :x: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
Discovered vulnerability can be directly reported using the project Issues and/or Discussions.
|
||||||
|
|
||||||
|
_TODO: Tell them where to go, how often they can expect to get an update on a
|
||||||
|
reported vulnerability, what to expect if the vulnerability is accepted or
|
||||||
|
declined, etc._
|
||||||
42
build.zig
|
|
@ -2,7 +2,7 @@ const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
/// Minimum supported version of Zig
|
/// Minimum supported version of Zig
|
||||||
const min_ver = "0.15.1";
|
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";
|
||||||
|
|
@ -106,9 +106,9 @@ const config_h_flags = outer: {
|
||||||
if (std.mem.startsWith(u8, line, "//")) continue;
|
if (std.mem.startsWith(u8, line, "//")) continue;
|
||||||
if (std.mem.startsWith(u8, line, "#if")) continue;
|
if (std.mem.startsWith(u8, line, "#if")) continue;
|
||||||
|
|
||||||
var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace
|
var flag = std.mem.trimStart(u8, line, " \t"); // Trim whitespace
|
||||||
flag = flag["#define ".len - 1 ..]; // Remove #define
|
flag = flag["#define ".len - 1 ..]; // Remove #define
|
||||||
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace
|
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 = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
|
||||||
flag = "-D" ++ flag; // Prepend with -D
|
flag = "-D" ++ flag; // Prepend with -D
|
||||||
|
|
||||||
|
|
@ -155,9 +155,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets a flag indiciating the use of a custom `config.h`
|
|
||||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
|
||||||
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.
|
||||||
|
|
@ -187,17 +187,17 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||||
try raylib_flags_arr.append(b.allocator, flag);
|
try raylib_flags_arr.append(b.allocator, flag);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Set default config if no custome config got set
|
// Set default config if no custom config got set
|
||||||
try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
|
try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No GLFW required on PLATFORM_DRM
|
// No GLFW required on PLATFORM_DRM
|
||||||
if (options.platform != .drm) {
|
if (options.platform != .drm) {
|
||||||
raylib.addIncludePath(b.path("src/external/glfw/include"));
|
raylib.root_module.addIncludePath(b.path("src/external/glfw/include"));
|
||||||
}
|
}
|
||||||
|
|
||||||
var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2);
|
var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2);
|
||||||
c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c", "src/utils.c" });
|
c_source_files.appendSliceAssumeCapacity(&.{"src/rcore.c"});
|
||||||
|
|
||||||
if (options.rshapes) {
|
if (options.rshapes) {
|
||||||
try c_source_files.append(b.allocator, "src/rshapes.c");
|
try c_source_files.append(b.allocator, "src/rshapes.c");
|
||||||
|
|
@ -224,7 +224,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||||
raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), "");
|
raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
raylib.addIncludePath(b.path("src/platforms"));
|
raylib.root_module.addIncludePath(b.path("src/platforms"));
|
||||||
switch (target.result.os.tag) {
|
switch (target.result.os.tag) {
|
||||||
.windows => {
|
.windows => {
|
||||||
switch (options.platform) {
|
switch (options.platform) {
|
||||||
|
|
@ -348,7 +348,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.freebsd, .openbsd, .netbsd, .dragonfly => {
|
.freebsd, .openbsd, .netbsd, .dragonfly => {
|
||||||
try c_source_files.append(b.allocator, "rglfw.c");
|
try c_source_files.append(b.allocator, "src/rglfw.c");
|
||||||
raylib.root_module.linkSystemLibrary("GL", .{});
|
raylib.root_module.linkSystemLibrary("GL", .{});
|
||||||
raylib.root_module.linkSystemLibrary("rt", .{});
|
raylib.root_module.linkSystemLibrary("rt", .{});
|
||||||
raylib.root_module.linkSystemLibrary("dl", .{});
|
raylib.root_module.linkSystemLibrary("dl", .{});
|
||||||
|
|
@ -438,7 +438,7 @@ pub const Options = struct {
|
||||||
|
|
||||||
pub fn getOptions(b: *std.Build) Options {
|
pub fn getOptions(b: *std.Build) Options {
|
||||||
return .{
|
return .{
|
||||||
.platform = b.option(PlatformBackend, "platform", "Choose the platform backedn for desktop target") orelse defaults.platform,
|
.platform = b.option(PlatformBackend, "platform", "Choose the platform backend for desktop target") orelse defaults.platform,
|
||||||
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
|
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
|
||||||
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
|
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
|
||||||
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
|
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
|
||||||
|
|
@ -448,7 +448,7 @@ pub const Options = struct {
|
||||||
.linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend,
|
.linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend,
|
||||||
.opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version,
|
.opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version,
|
||||||
.config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{},
|
.config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{},
|
||||||
.android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse std.process.getEnvVarOwned(b.allocator, "ANDROID_NDK_HOME") catch "",
|
.android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse b.graph.environ_map.get("ANDROID_NDK_HOME") orelse "",
|
||||||
.android_api_version = b.option([]const u8, "android_api_version", "specify target android API level") orelse defaults.android_api_version,
|
.android_api_version = b.option([]const u8, "android_api_version", "specify target android API level") orelse defaults.android_api_version,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -523,15 +523,17 @@ fn addExamples(
|
||||||
) !*std.Build.Step {
|
) !*std.Build.Step {
|
||||||
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.fs.cwd().openDir(b.pathFromRoot(module_subpath), .{ .iterate = true });
|
|
||||||
defer dir.close();
|
var dir = try std.Io.Dir.cwd().openDir(b.graph.io, b.pathFromRoot(module_subpath), .{ .iterate = true });
|
||||||
|
defer dir.close(b.graph.io);
|
||||||
|
|
||||||
var iter = dir.iterate();
|
var iter = dir.iterate();
|
||||||
while (try iter.next()) |entry| {
|
while (try iter.next(b.graph.io)) |entry| {
|
||||||
if (entry.kind != .file) continue;
|
if (entry.kind != .file) continue;
|
||||||
const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue;
|
const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue;
|
||||||
const name = entry.name[0..extension_idx];
|
const name = entry.name[0..extension_idx];
|
||||||
const path = b.pathJoin(&.{ module_subpath, entry.name });
|
const filename = try std.fmt.allocPrint(b.allocator, "{s}.c", .{name});
|
||||||
|
const path = b.pathJoin(&.{ module_subpath, filename });
|
||||||
|
|
||||||
// zig's mingw headers do not include pthread.h
|
// zig's mingw headers do not include pthread.h
|
||||||
if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue;
|
if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue;
|
||||||
|
|
@ -553,12 +555,11 @@ fn addExamples(
|
||||||
});
|
});
|
||||||
|
|
||||||
if (std.mem.eql(u8, name, "rlgl_standalone")) {
|
if (std.mem.eql(u8, name, "rlgl_standalone")) {
|
||||||
//TODO: Make rlgl_standalone example work
|
exe_mod.addIncludePath(b.path("src"));
|
||||||
continue;
|
exe_mod.addIncludePath(b.path("src/external/glfw/include"));
|
||||||
}
|
}
|
||||||
if (std.mem.eql(u8, name, "raylib_opengl_interop")) {
|
if (std.mem.eql(u8, name, "raylib_opengl_interop")) {
|
||||||
//TODO: Make raylib_opengl_interop example work
|
exe_mod.addIncludePath(b.path("src/external"));
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize });
|
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize });
|
||||||
|
|
@ -650,6 +651,7 @@ fn addExamples(
|
||||||
all.dependOn(&install_cmd.step);
|
all.dependOn(&install_cmd.step);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,12 @@ if (${PLATFORM} MATCHES "Desktop")
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
find_package(OpenGL QUIET)
|
find_package(OpenGL QUIET)
|
||||||
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm)
|
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm)
|
||||||
|
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "QNX")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
|
find_library(GLESV2 GLESv2)
|
||||||
|
find_library(EGL EGL)
|
||||||
|
set(LIBS_PUBLIC m)
|
||||||
|
set(LIBS_PRIVATE ${GLESV2} ${EGL} atomic pthread dl)
|
||||||
elseif (UNIX)
|
elseif (UNIX)
|
||||||
find_library(pthread NAMES pthread)
|
find_library(pthread NAMES pthread)
|
||||||
find_package(OpenGL QUIET)
|
find_package(OpenGL QUIET)
|
||||||
|
|
@ -141,6 +147,26 @@ elseif ("${PLATFORM}" MATCHES "SDL")
|
||||||
add_compile_definitions(USING_SDL2_PACKAGE)
|
add_compile_definitions(USING_SDL2_PACKAGE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
elseif ("${PLATFORM}" MATCHES "RGFW")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW")
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
find_library(COCOA Cocoa)
|
||||||
|
find_library(OPENGL OpenGL)
|
||||||
|
|
||||||
|
set(LIBS_PRIVATE ${COCOA} ${OPENGL})
|
||||||
|
elseif (WIN32)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
|
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} gdi32)
|
||||||
|
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "QNX")
|
||||||
|
message(FATAL_ERROR "RGFW platform does not support QNX. Use PLATFORM=Desktop or PLATFORM=SDL instead.")
|
||||||
|
elseif (UNIX)
|
||||||
|
find_package(X11 REQUIRED)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
|
set(LIBS_PRIVATE ${X11_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
# > PLATFORM_ANDROID:
|
# > PLATFORM_ANDROID:
|
||||||
# - Android (ARM, ARM64)
|
# - Android (ARM, ARM64)
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
|
# Copyright (c) 2013-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.
|
||||||
|
|
@ -77,7 +77,7 @@ RAYLIB_SRC_PATH ?= ../src
|
||||||
|
|
||||||
# Locations of raylib.h and libraylib.a/libraylib.so
|
# Locations of raylib.h and libraylib.a/libraylib.so
|
||||||
# NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD
|
# NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD
|
||||||
DESTDIR ?= /usr/local
|
DESTDIR ?= /usr/local
|
||||||
RAYLIB_INCLUDE_PATH ?= $(DESTDIR)/include
|
RAYLIB_INCLUDE_PATH ?= $(DESTDIR)/include
|
||||||
RAYLIB_LIB_PATH ?= $(DESTDIR)/lib
|
RAYLIB_LIB_PATH ?= $(DESTDIR)/lib
|
||||||
|
|
||||||
|
|
@ -205,15 +205,17 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
|
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
|
||||||
MAKE = mingw32-make
|
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||||
|
MAKE = mingw32-make
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
|
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||||
MAKE = mingw32-make
|
MAKE = mingw32-make
|
||||||
else
|
else
|
||||||
EMMAKE != type emmake
|
EMMAKE := $(shell command -v emmake)
|
||||||
ifneq (, $(EMMAKE))
|
ifneq (, $(EMMAKE))
|
||||||
MAKE = emmake make
|
MAKE = $(EMMAKE) make
|
||||||
else
|
else
|
||||||
MAKE = mingw32-make
|
MAKE = mingw32-make
|
||||||
endif
|
endif
|
||||||
|
|
@ -231,7 +233,7 @@ endif
|
||||||
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
|
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
|
||||||
# -Wno-unused-value ignore unused return values of some functions (i.e. fread())
|
# -Wno-unused-value ignore unused return values of some functions (i.e. fread())
|
||||||
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
|
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
|
||||||
CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result
|
CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wno-unused-result
|
||||||
|
|
||||||
ifeq ($(BUILD_MODE),DEBUG)
|
ifeq ($(BUILD_MODE),DEBUG)
|
||||||
CFLAGS += -g -D_DEBUG
|
CFLAGS += -g -D_DEBUG
|
||||||
|
|
@ -486,7 +488,19 @@ endif
|
||||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||||
# Libraries for DRM compiling
|
# Libraries for DRM compiling
|
||||||
# NOTE: Required packages: libasound2-dev (ALSA)
|
# NOTE: Required packages: libasound2-dev (ALSA)
|
||||||
LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic
|
LDLIBS = -lraylib -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl -latomic
|
||||||
|
# TODO: Examples compilation does not define GRAPHICS, is it required?
|
||||||
|
#ifeq ($(GRAPHICS),GRAPHICS_API_OPENGL_ES2)
|
||||||
|
# LDLIBS += -lGLESv2 -lEGL
|
||||||
|
#endif
|
||||||
|
endif
|
||||||
|
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32)
|
||||||
|
# Libraries for Windows desktop compilation
|
||||||
|
LDFLAGS += -L..\src
|
||||||
|
LDLIBS = -lraylib -lgdi32 -lwinmm -lshcore
|
||||||
|
ifneq ($(GRAPHICS),GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||||
|
LDLIBS += -lopengl32
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
|
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
|
||||||
# Libraries for web (HTML5) compiling
|
# Libraries for web (HTML5) compiling
|
||||||
|
|
@ -513,12 +527,13 @@ CORE = \
|
||||||
core/core_basic_screen_manager \
|
core/core_basic_screen_manager \
|
||||||
core/core_basic_window \
|
core/core_basic_window \
|
||||||
core/core_clipboard_text \
|
core/core_clipboard_text \
|
||||||
|
core/core_compute_hash \
|
||||||
core/core_custom_frame_control \
|
core/core_custom_frame_control \
|
||||||
core/core_custom_logging \
|
core/core_custom_logging \
|
||||||
core/core_delta_time \
|
core/core_delta_time \
|
||||||
core/core_directory_files \
|
core/core_directory_files \
|
||||||
core/core_drop_files \
|
core/core_drop_files \
|
||||||
core/core_high_dpi \
|
core/core_highdpi_demo \
|
||||||
core/core_highdpi_testbed \
|
core/core_highdpi_testbed \
|
||||||
core/core_input_actions \
|
core/core_input_actions \
|
||||||
core/core_input_gamepad \
|
core/core_input_gamepad \
|
||||||
|
|
@ -529,6 +544,7 @@ CORE = \
|
||||||
core/core_input_mouse_wheel \
|
core/core_input_mouse_wheel \
|
||||||
core/core_input_multitouch \
|
core/core_input_multitouch \
|
||||||
core/core_input_virtual_controls \
|
core/core_input_virtual_controls \
|
||||||
|
core/core_keyboard_testbed \
|
||||||
core/core_monitor_detector \
|
core/core_monitor_detector \
|
||||||
core/core_random_sequence \
|
core/core_random_sequence \
|
||||||
core/core_random_values \
|
core/core_random_values \
|
||||||
|
|
@ -539,6 +555,7 @@ CORE = \
|
||||||
core/core_storage_values \
|
core/core_storage_values \
|
||||||
core/core_text_file_loading \
|
core/core_text_file_loading \
|
||||||
core/core_undo_redo \
|
core/core_undo_redo \
|
||||||
|
core/core_viewport_scaling \
|
||||||
core/core_vr_simulator \
|
core/core_vr_simulator \
|
||||||
core/core_window_flags \
|
core/core_window_flags \
|
||||||
core/core_window_letterbox \
|
core/core_window_letterbox \
|
||||||
|
|
@ -546,6 +563,7 @@ CORE = \
|
||||||
core/core_world_screen
|
core/core_world_screen
|
||||||
|
|
||||||
SHAPES = \
|
SHAPES = \
|
||||||
|
shapes/shapes_ball_physics \
|
||||||
shapes/shapes_basic_shapes \
|
shapes/shapes_basic_shapes \
|
||||||
shapes/shapes_bouncing_ball \
|
shapes/shapes_bouncing_ball \
|
||||||
shapes/shapes_bullet_hell \
|
shapes/shapes_bullet_hell \
|
||||||
|
|
@ -560,17 +578,23 @@ SHAPES = \
|
||||||
shapes/shapes_easings_box \
|
shapes/shapes_easings_box \
|
||||||
shapes/shapes_easings_rectangles \
|
shapes/shapes_easings_rectangles \
|
||||||
shapes/shapes_following_eyes \
|
shapes/shapes_following_eyes \
|
||||||
|
shapes/shapes_hilbert_curve \
|
||||||
shapes/shapes_kaleidoscope \
|
shapes/shapes_kaleidoscope \
|
||||||
shapes/shapes_lines_bezier \
|
shapes/shapes_lines_bezier \
|
||||||
|
shapes/shapes_lines_drawing \
|
||||||
shapes/shapes_logo_raylib \
|
shapes/shapes_logo_raylib \
|
||||||
shapes/shapes_logo_raylib_anim \
|
shapes/shapes_logo_raylib_anim \
|
||||||
|
shapes/shapes_math_angle_rotation \
|
||||||
shapes/shapes_math_sine_cosine \
|
shapes/shapes_math_sine_cosine \
|
||||||
shapes/shapes_mouse_trail \
|
shapes/shapes_mouse_trail \
|
||||||
|
shapes/shapes_penrose_tile \
|
||||||
shapes/shapes_pie_chart \
|
shapes/shapes_pie_chart \
|
||||||
shapes/shapes_rectangle_advanced \
|
shapes/shapes_rectangle_advanced \
|
||||||
shapes/shapes_rectangle_scaling \
|
shapes/shapes_rectangle_scaling \
|
||||||
shapes/shapes_recursive_tree \
|
shapes/shapes_recursive_tree \
|
||||||
shapes/shapes_ring_drawing \
|
shapes/shapes_ring_drawing \
|
||||||
|
shapes/shapes_rlgl_color_wheel \
|
||||||
|
shapes/shapes_rlgl_triangle \
|
||||||
shapes/shapes_rounded_rectangle_drawing \
|
shapes/shapes_rounded_rectangle_drawing \
|
||||||
shapes/shapes_simple_particles \
|
shapes/shapes_simple_particles \
|
||||||
shapes/shapes_splines_drawing \
|
shapes/shapes_splines_drawing \
|
||||||
|
|
@ -583,7 +607,9 @@ TEXTURES = \
|
||||||
textures/textures_background_scrolling \
|
textures/textures_background_scrolling \
|
||||||
textures/textures_blend_modes \
|
textures/textures_blend_modes \
|
||||||
textures/textures_bunnymark \
|
textures/textures_bunnymark \
|
||||||
|
textures/textures_cellular_automata \
|
||||||
textures/textures_fog_of_war \
|
textures/textures_fog_of_war \
|
||||||
|
textures/textures_framebuffer_rendering \
|
||||||
textures/textures_gif_player \
|
textures/textures_gif_player \
|
||||||
textures/textures_image_channel \
|
textures/textures_image_channel \
|
||||||
textures/textures_image_drawing \
|
textures/textures_image_drawing \
|
||||||
|
|
@ -599,9 +625,11 @@ TEXTURES = \
|
||||||
textures/textures_particles_blending \
|
textures/textures_particles_blending \
|
||||||
textures/textures_polygon_drawing \
|
textures/textures_polygon_drawing \
|
||||||
textures/textures_raw_data \
|
textures/textures_raw_data \
|
||||||
|
textures/textures_screen_buffer \
|
||||||
textures/textures_sprite_animation \
|
textures/textures_sprite_animation \
|
||||||
textures/textures_sprite_button \
|
textures/textures_sprite_button \
|
||||||
textures/textures_sprite_explosion \
|
textures/textures_sprite_explosion \
|
||||||
|
textures/textures_sprite_stacking \
|
||||||
textures/textures_srcrec_dstrec \
|
textures/textures_srcrec_dstrec \
|
||||||
textures/textures_textured_curve \
|
textures/textures_textured_curve \
|
||||||
textures/textures_tiled_drawing \
|
textures/textures_tiled_drawing \
|
||||||
|
|
@ -619,6 +647,7 @@ TEXT = \
|
||||||
text/text_input_box \
|
text/text_input_box \
|
||||||
text/text_rectangle_bounds \
|
text/text_rectangle_bounds \
|
||||||
text/text_sprite_fonts \
|
text/text_sprite_fonts \
|
||||||
|
text/text_strings_management \
|
||||||
text/text_unicode_emojis \
|
text/text_unicode_emojis \
|
||||||
text/text_unicode_ranges \
|
text/text_unicode_ranges \
|
||||||
text/text_words_alignment \
|
text/text_words_alignment \
|
||||||
|
|
@ -632,6 +661,8 @@ MODELS = \
|
||||||
models/models_bone_socket \
|
models/models_bone_socket \
|
||||||
models/models_box_collisions \
|
models/models_box_collisions \
|
||||||
models/models_cubicmap_rendering \
|
models/models_cubicmap_rendering \
|
||||||
|
models/models_decals \
|
||||||
|
models/models_directional_billboard \
|
||||||
models/models_first_person_maze \
|
models/models_first_person_maze \
|
||||||
models/models_geometric_shapes \
|
models/models_geometric_shapes \
|
||||||
models/models_heightmap_rendering \
|
models/models_heightmap_rendering \
|
||||||
|
|
@ -655,12 +686,14 @@ 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_color_correction \
|
||||||
shaders/shaders_custom_uniform \
|
shaders/shaders_custom_uniform \
|
||||||
shaders/shaders_deferred_rendering \
|
shaders/shaders_deferred_rendering \
|
||||||
shaders/shaders_depth_rendering \
|
shaders/shaders_depth_rendering \
|
||||||
shaders/shaders_depth_writing \
|
shaders/shaders_depth_writing \
|
||||||
shaders/shaders_eratosthenes_sieve \
|
shaders/shaders_eratosthenes_sieve \
|
||||||
shaders/shaders_fog_rendering \
|
shaders/shaders_fog_rendering \
|
||||||
|
shaders/shaders_game_of_life \
|
||||||
shaders/shaders_hot_reloading \
|
shaders/shaders_hot_reloading \
|
||||||
shaders/shaders_hybrid_rendering \
|
shaders/shaders_hybrid_rendering \
|
||||||
shaders/shaders_julia_set \
|
shaders/shaders_julia_set \
|
||||||
|
|
@ -692,6 +725,7 @@ AUDIO = \
|
||||||
audio/audio_sound_loading \
|
audio/audio_sound_loading \
|
||||||
audio/audio_sound_multi \
|
audio/audio_sound_multi \
|
||||||
audio/audio_sound_positioning \
|
audio/audio_sound_positioning \
|
||||||
|
audio/audio_spectrum_visualizer \
|
||||||
audio/audio_stream_effects
|
audio/audio_stream_effects
|
||||||
|
|
||||||
OTHERS = \
|
OTHERS = \
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ ifeq ($(ANDROID_ARCH),ARM)
|
||||||
CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
|
CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
|
||||||
endif
|
endif
|
||||||
ifeq ($(ANDROID_ARCH),ARM64)
|
ifeq ($(ANDROID_ARCH),ARM64)
|
||||||
CFLAGS = -std=c99 -target aarch64 -mfix-cortex-a53-835769
|
CFLAGS = -std=c99 -mfix-cortex-a53-835769
|
||||||
endif
|
endif
|
||||||
# Compilation functions attributes options
|
# Compilation functions attributes options
|
||||||
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC
|
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
# > PLATFORM_ANDROID:
|
# > PLATFORM_ANDROID:
|
||||||
# - Android (ARM, ARM64)
|
# - Android (ARM, ARM64)
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
|
# Copyright (c) 2013-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.
|
||||||
|
|
@ -208,12 +208,12 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
|
||||||
MAKE = mingw32-make
|
MAKE = mingw32-make
|
||||||
endif
|
endif
|
||||||
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
|
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||||
MAKE = mingw32-make
|
MAKE = mingw32-make
|
||||||
else
|
else
|
||||||
EMMAKE != type emmake
|
EMMAKE := $(shell command -v emmake)
|
||||||
ifneq (, $(EMMAKE))
|
ifneq (, $(EMMAKE))
|
||||||
MAKE = emmake make
|
MAKE = $(EMMAKE) make
|
||||||
else
|
else
|
||||||
MAKE = mingw32-make
|
MAKE = mingw32-make
|
||||||
endif
|
endif
|
||||||
|
|
@ -513,12 +513,13 @@ CORE = \
|
||||||
core/core_basic_screen_manager \
|
core/core_basic_screen_manager \
|
||||||
core/core_basic_window \
|
core/core_basic_window \
|
||||||
core/core_clipboard_text \
|
core/core_clipboard_text \
|
||||||
|
core/core_compute_hash \
|
||||||
core/core_custom_frame_control \
|
core/core_custom_frame_control \
|
||||||
core/core_custom_logging \
|
core/core_custom_logging \
|
||||||
core/core_delta_time \
|
core/core_delta_time \
|
||||||
core/core_directory_files \
|
core/core_directory_files \
|
||||||
core/core_drop_files \
|
core/core_drop_files \
|
||||||
core/core_high_dpi \
|
core/core_highdpi_demo \
|
||||||
core/core_highdpi_testbed \
|
core/core_highdpi_testbed \
|
||||||
core/core_input_actions \
|
core/core_input_actions \
|
||||||
core/core_input_gamepad \
|
core/core_input_gamepad \
|
||||||
|
|
@ -529,6 +530,7 @@ CORE = \
|
||||||
core/core_input_mouse_wheel \
|
core/core_input_mouse_wheel \
|
||||||
core/core_input_multitouch \
|
core/core_input_multitouch \
|
||||||
core/core_input_virtual_controls \
|
core/core_input_virtual_controls \
|
||||||
|
core/core_keyboard_testbed \
|
||||||
core/core_monitor_detector \
|
core/core_monitor_detector \
|
||||||
core/core_random_sequence \
|
core/core_random_sequence \
|
||||||
core/core_random_values \
|
core/core_random_values \
|
||||||
|
|
@ -539,6 +541,7 @@ CORE = \
|
||||||
core/core_storage_values \
|
core/core_storage_values \
|
||||||
core/core_text_file_loading \
|
core/core_text_file_loading \
|
||||||
core/core_undo_redo \
|
core/core_undo_redo \
|
||||||
|
core/core_viewport_scaling \
|
||||||
core/core_vr_simulator \
|
core/core_vr_simulator \
|
||||||
core/core_window_flags \
|
core/core_window_flags \
|
||||||
core/core_window_letterbox \
|
core/core_window_letterbox \
|
||||||
|
|
@ -546,6 +549,7 @@ CORE = \
|
||||||
core/core_world_screen
|
core/core_world_screen
|
||||||
|
|
||||||
SHAPES = \
|
SHAPES = \
|
||||||
|
shapes/shapes_ball_physics \
|
||||||
shapes/shapes_basic_shapes \
|
shapes/shapes_basic_shapes \
|
||||||
shapes/shapes_bouncing_ball \
|
shapes/shapes_bouncing_ball \
|
||||||
shapes/shapes_bullet_hell \
|
shapes/shapes_bullet_hell \
|
||||||
|
|
@ -560,17 +564,23 @@ SHAPES = \
|
||||||
shapes/shapes_easings_box \
|
shapes/shapes_easings_box \
|
||||||
shapes/shapes_easings_rectangles \
|
shapes/shapes_easings_rectangles \
|
||||||
shapes/shapes_following_eyes \
|
shapes/shapes_following_eyes \
|
||||||
|
shapes/shapes_hilbert_curve \
|
||||||
shapes/shapes_kaleidoscope \
|
shapes/shapes_kaleidoscope \
|
||||||
shapes/shapes_lines_bezier \
|
shapes/shapes_lines_bezier \
|
||||||
|
shapes/shapes_lines_drawing \
|
||||||
shapes/shapes_logo_raylib \
|
shapes/shapes_logo_raylib \
|
||||||
shapes/shapes_logo_raylib_anim \
|
shapes/shapes_logo_raylib_anim \
|
||||||
|
shapes/shapes_math_angle_rotation \
|
||||||
shapes/shapes_math_sine_cosine \
|
shapes/shapes_math_sine_cosine \
|
||||||
shapes/shapes_mouse_trail \
|
shapes/shapes_mouse_trail \
|
||||||
|
shapes/shapes_penrose_tile \
|
||||||
shapes/shapes_pie_chart \
|
shapes/shapes_pie_chart \
|
||||||
shapes/shapes_rectangle_advanced \
|
shapes/shapes_rectangle_advanced \
|
||||||
shapes/shapes_rectangle_scaling \
|
shapes/shapes_rectangle_scaling \
|
||||||
shapes/shapes_recursive_tree \
|
shapes/shapes_recursive_tree \
|
||||||
shapes/shapes_ring_drawing \
|
shapes/shapes_ring_drawing \
|
||||||
|
shapes/shapes_rlgl_color_wheel \
|
||||||
|
shapes/shapes_rlgl_triangle \
|
||||||
shapes/shapes_rounded_rectangle_drawing \
|
shapes/shapes_rounded_rectangle_drawing \
|
||||||
shapes/shapes_simple_particles \
|
shapes/shapes_simple_particles \
|
||||||
shapes/shapes_splines_drawing \
|
shapes/shapes_splines_drawing \
|
||||||
|
|
@ -583,7 +593,9 @@ TEXTURES = \
|
||||||
textures/textures_background_scrolling \
|
textures/textures_background_scrolling \
|
||||||
textures/textures_blend_modes \
|
textures/textures_blend_modes \
|
||||||
textures/textures_bunnymark \
|
textures/textures_bunnymark \
|
||||||
|
textures/textures_cellular_automata \
|
||||||
textures/textures_fog_of_war \
|
textures/textures_fog_of_war \
|
||||||
|
textures/textures_framebuffer_rendering \
|
||||||
textures/textures_gif_player \
|
textures/textures_gif_player \
|
||||||
textures/textures_image_channel \
|
textures/textures_image_channel \
|
||||||
textures/textures_image_drawing \
|
textures/textures_image_drawing \
|
||||||
|
|
@ -599,9 +611,11 @@ TEXTURES = \
|
||||||
textures/textures_particles_blending \
|
textures/textures_particles_blending \
|
||||||
textures/textures_polygon_drawing \
|
textures/textures_polygon_drawing \
|
||||||
textures/textures_raw_data \
|
textures/textures_raw_data \
|
||||||
|
textures/textures_screen_buffer \
|
||||||
textures/textures_sprite_animation \
|
textures/textures_sprite_animation \
|
||||||
textures/textures_sprite_button \
|
textures/textures_sprite_button \
|
||||||
textures/textures_sprite_explosion \
|
textures/textures_sprite_explosion \
|
||||||
|
textures/textures_sprite_stacking \
|
||||||
textures/textures_srcrec_dstrec \
|
textures/textures_srcrec_dstrec \
|
||||||
textures/textures_textured_curve \
|
textures/textures_textured_curve \
|
||||||
textures/textures_tiled_drawing \
|
textures/textures_tiled_drawing \
|
||||||
|
|
@ -619,6 +633,7 @@ TEXT = \
|
||||||
text/text_input_box \
|
text/text_input_box \
|
||||||
text/text_rectangle_bounds \
|
text/text_rectangle_bounds \
|
||||||
text/text_sprite_fonts \
|
text/text_sprite_fonts \
|
||||||
|
text/text_strings_management \
|
||||||
text/text_unicode_emojis \
|
text/text_unicode_emojis \
|
||||||
text/text_unicode_ranges \
|
text/text_unicode_ranges \
|
||||||
text/text_words_alignment \
|
text/text_words_alignment \
|
||||||
|
|
@ -632,6 +647,8 @@ MODELS = \
|
||||||
models/models_bone_socket \
|
models/models_bone_socket \
|
||||||
models/models_box_collisions \
|
models/models_box_collisions \
|
||||||
models/models_cubicmap_rendering \
|
models/models_cubicmap_rendering \
|
||||||
|
models/models_decals \
|
||||||
|
models/models_directional_billboard \
|
||||||
models/models_first_person_maze \
|
models/models_first_person_maze \
|
||||||
models/models_geometric_shapes \
|
models/models_geometric_shapes \
|
||||||
models/models_heightmap_rendering \
|
models/models_heightmap_rendering \
|
||||||
|
|
@ -655,12 +672,14 @@ 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_color_correction \
|
||||||
shaders/shaders_custom_uniform \
|
shaders/shaders_custom_uniform \
|
||||||
shaders/shaders_deferred_rendering \
|
shaders/shaders_deferred_rendering \
|
||||||
shaders/shaders_depth_rendering \
|
shaders/shaders_depth_rendering \
|
||||||
shaders/shaders_depth_writing \
|
shaders/shaders_depth_writing \
|
||||||
shaders/shaders_eratosthenes_sieve \
|
shaders/shaders_eratosthenes_sieve \
|
||||||
shaders/shaders_fog_rendering \
|
shaders/shaders_fog_rendering \
|
||||||
|
shaders/shaders_game_of_life \
|
||||||
shaders/shaders_hot_reloading \
|
shaders/shaders_hot_reloading \
|
||||||
shaders/shaders_hybrid_rendering \
|
shaders/shaders_hybrid_rendering \
|
||||||
shaders/shaders_julia_set \
|
shaders/shaders_julia_set \
|
||||||
|
|
@ -692,6 +711,7 @@ AUDIO = \
|
||||||
audio/audio_sound_loading \
|
audio/audio_sound_loading \
|
||||||
audio/audio_sound_multi \
|
audio/audio_sound_multi \
|
||||||
audio/audio_sound_positioning \
|
audio/audio_sound_positioning \
|
||||||
|
audio/audio_spectrum_visualizer \
|
||||||
audio/audio_stream_effects
|
audio/audio_stream_effects
|
||||||
|
|
||||||
# Default target entry
|
# Default target entry
|
||||||
|
|
@ -748,6 +768,9 @@ core/core_basic_window: core/core_basic_window.c
|
||||||
core/core_clipboard_text: core/core_clipboard_text.c
|
core/core_clipboard_text: core/core_clipboard_text.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_compute_hash: core/core_compute_hash.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_custom_frame_control: core/core_custom_frame_control.c
|
core/core_custom_frame_control: core/core_custom_frame_control.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -763,7 +786,7 @@ core/core_directory_files: core/core_directory_files.c
|
||||||
core/core_drop_files: core/core_drop_files.c
|
core/core_drop_files: core/core_drop_files.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_high_dpi: core/core_high_dpi.c
|
core/core_highdpi_demo: core/core_highdpi_demo.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_highdpi_testbed: core/core_highdpi_testbed.c
|
core/core_highdpi_testbed: core/core_highdpi_testbed.c
|
||||||
|
|
@ -798,6 +821,9 @@ core/core_input_multitouch: core/core_input_multitouch.c
|
||||||
core/core_input_virtual_controls: core/core_input_virtual_controls.c
|
core/core_input_virtual_controls: core/core_input_virtual_controls.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_keyboard_testbed: core/core_keyboard_testbed.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_monitor_detector: core/core_monitor_detector.c
|
core/core_monitor_detector: core/core_monitor_detector.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -829,6 +855,9 @@ core/core_text_file_loading: core/core_text_file_loading.c
|
||||||
core/core_undo_redo: core/core_undo_redo.c
|
core/core_undo_redo: core/core_undo_redo.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_viewport_scaling: core/core_viewport_scaling.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_vr_simulator: core/core_vr_simulator.c
|
core/core_vr_simulator: core/core_vr_simulator.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file core/resources/shaders/glsl100/distortion.fs@resources/shaders/glsl100/distortion.fs
|
--preload-file core/resources/shaders/glsl100/distortion.fs@resources/shaders/glsl100/distortion.fs
|
||||||
|
|
@ -846,6 +875,9 @@ core/core_world_screen: core/core_world_screen.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
# Compile SHAPES examples
|
# Compile SHAPES examples
|
||||||
|
shapes/shapes_ball_physics: shapes/shapes_ball_physics.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_basic_shapes: shapes/shapes_basic_shapes.c
|
shapes/shapes_basic_shapes: shapes/shapes_basic_shapes.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -888,24 +920,36 @@ shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c
|
||||||
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
|
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_hilbert_curve: shapes/shapes_hilbert_curve.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c
|
shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c
|
shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_lines_drawing: shapes/shapes_lines_drawing.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c
|
shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c
|
shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_math_angle_rotation: shapes/shapes_math_angle_rotation.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c
|
shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c
|
shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_penrose_tile: shapes/shapes_penrose_tile.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_pie_chart: shapes/shapes_pie_chart.c
|
shapes/shapes_pie_chart: shapes/shapes_pie_chart.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -921,6 +965,12 @@ shapes/shapes_recursive_tree: shapes/shapes_recursive_tree.c
|
||||||
shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c
|
shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_rlgl_color_wheel: shapes/shapes_rlgl_color_wheel.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_rlgl_triangle: shapes/shapes_rlgl_triangle.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_rounded_rectangle_drawing: shapes/shapes_rounded_rectangle_drawing.c
|
shapes/shapes_rounded_rectangle_drawing: shapes/shapes_rounded_rectangle_drawing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -956,11 +1006,17 @@ textures/textures_blend_modes: textures/textures_blend_modes.c
|
||||||
|
|
||||||
textures/textures_bunnymark: textures/textures_bunnymark.c
|
textures/textures_bunnymark: textures/textures_bunnymark.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/wabbit_alpha.png@resources/wabbit_alpha.png
|
--preload-file textures/resources/raybunny.png@resources/raybunny.png
|
||||||
|
|
||||||
|
textures/textures_cellular_automata: textures/textures_cellular_automata.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)
|
||||||
|
|
||||||
|
textures/textures_framebuffer_rendering: textures/textures_framebuffer_rendering.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
textures/textures_gif_player: textures/textures_gif_player.c
|
textures/textures_gif_player: textures/textures_gif_player.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/scarfy_run.gif@resources/scarfy_run.gif
|
--preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif
|
||||||
|
|
@ -1022,6 +1078,9 @@ textures/textures_raw_data: textures/textures_raw_data.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/fudesumi.raw@resources/fudesumi.raw
|
--preload-file textures/resources/fudesumi.raw@resources/fudesumi.raw
|
||||||
|
|
||||||
|
textures/textures_screen_buffer: textures/textures_screen_buffer.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
textures/textures_sprite_animation: textures/textures_sprite_animation.c
|
textures/textures_sprite_animation: textures/textures_sprite_animation.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/scarfy.png@resources/scarfy.png
|
--preload-file textures/resources/scarfy.png@resources/scarfy.png
|
||||||
|
|
@ -1036,6 +1095,10 @@ textures/textures_sprite_explosion: textures/textures_sprite_explosion.c
|
||||||
--preload-file textures/resources/boom.wav@resources/boom.wav \
|
--preload-file textures/resources/boom.wav@resources/boom.wav \
|
||||||
--preload-file textures/resources/explosion.png@resources/explosion.png
|
--preload-file textures/resources/explosion.png@resources/explosion.png
|
||||||
|
|
||||||
|
textures/textures_sprite_stacking: textures/textures_sprite_stacking.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file textures/resources/booth.png@resources/booth.png
|
||||||
|
|
||||||
textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c
|
textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.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/scarfy.png@resources/scarfy.png
|
--preload-file textures/resources/scarfy.png@resources/scarfy.png
|
||||||
|
|
@ -1102,6 +1165,9 @@ text/text_sprite_fonts: text/text_sprite_fonts.c
|
||||||
--preload-file text/resources/sprite_fonts/alpha_beta.png@resources/sprite_fonts/alpha_beta.png \
|
--preload-file text/resources/sprite_fonts/alpha_beta.png@resources/sprite_fonts/alpha_beta.png \
|
||||||
--preload-file text/resources/sprite_fonts/jupiter_crash.png@resources/sprite_fonts/jupiter_crash.png
|
--preload-file text/resources/sprite_fonts/jupiter_crash.png@resources/sprite_fonts/jupiter_crash.png
|
||||||
|
|
||||||
|
text/text_strings_management: text/text_strings_management.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
text/text_unicode_emojis: text/text_unicode_emojis.c
|
text/text_unicode_emojis: text/text_unicode_emojis.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/dejavu.fnt@resources/dejavu.fnt \
|
--preload-file text/resources/dejavu.fnt@resources/dejavu.fnt \
|
||||||
|
|
@ -1156,6 +1222,16 @@ models/models_cubicmap_rendering: models/models_cubicmap_rendering.c
|
||||||
--preload-file models/resources/cubicmap.png@resources/cubicmap.png \
|
--preload-file models/resources/cubicmap.png@resources/cubicmap.png \
|
||||||
--preload-file models/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png
|
--preload-file models/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png
|
||||||
|
|
||||||
|
models/models_decals: models/models_decals.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file models/resources/models/obj/character.obj@resources/models/obj/character.obj \
|
||||||
|
--preload-file models/resources/models/obj/character_diffuse.png@resources/models/obj/character_diffuse.png \
|
||||||
|
--preload-file models/resources/raylib_logo.png@resources/raylib_logo.png
|
||||||
|
|
||||||
|
models/models_directional_billboard: models/models_directional_billboard.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file models/resources/skillbot.png@resources/skillbot.png
|
||||||
|
|
||||||
models/models_first_person_maze: models/models_first_person_maze.c
|
models/models_first_person_maze: models/models_first_person_maze.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/cubicmap.png@resources/cubicmap.png \
|
--preload-file models/resources/cubicmap.png@resources/cubicmap.png \
|
||||||
|
|
@ -1261,6 +1337,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_color_correction: shaders/shaders_color_correction.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file shaders/resources/parrots.png@resources/parrots.png \
|
||||||
|
--preload-file shaders/resources/cat.png@resources/cat.png \
|
||||||
|
--preload-file shaders/resources/mandrill.png@resources/mandrill.png \
|
||||||
|
--preload-file shaders/resources/fudesumi.png@resources/fudesumi.png \
|
||||||
|
--preload-file shaders/resources/shaders/glsl100/color_correction.fs@resources/shaders/glsl100/color_correction.fs
|
||||||
|
|
||||||
shaders/shaders_custom_uniform: shaders/shaders_custom_uniform.c
|
shaders/shaders_custom_uniform: shaders/shaders_custom_uniform.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/models/barracks.obj@resources/models/barracks.obj \
|
--preload-file shaders/resources/models/barracks.obj@resources/models/barracks.obj \
|
||||||
|
|
@ -1292,6 +1376,19 @@ shaders/shaders_fog_rendering: shaders/shaders_fog_rendering.c
|
||||||
--preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs \
|
--preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs \
|
||||||
--preload-file shaders/resources/shaders/glsl100/fog.fs@resources/shaders/glsl100/fog.fs
|
--preload-file shaders/resources/shaders/glsl100/fog.fs@resources/shaders/glsl100/fog.fs
|
||||||
|
|
||||||
|
shaders/shaders_game_of_life: shaders/shaders_game_of_life.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file shaders/resources/shaders/glsl100/game_of_life.fs@resources/shaders/glsl100/game_of_life.fs \
|
||||||
|
--preload-file shaders/resources/game_of_life/r_pentomino.png@resources/game_of_life/r_pentomino.png \
|
||||||
|
--preload-file shaders/resources/game_of_life/glider.png@resources/game_of_life/glider.png \
|
||||||
|
--preload-file shaders/resources/game_of_life/acorn.png@resources/game_of_life/acorn.png \
|
||||||
|
--preload-file shaders/resources/game_of_life/spaceships.png@resources/game_of_life/spaceships.png \
|
||||||
|
--preload-file shaders/resources/game_of_life/still_lifes.png@resources/game_of_life/still_lifes.png \
|
||||||
|
--preload-file shaders/resources/game_of_life/oscillators.png@resources/game_of_life/oscillators.png \
|
||||||
|
--preload-file shaders/resources/game_of_life/puffer_train.png@resources/game_of_life/puffer_train.png \
|
||||||
|
--preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \
|
||||||
|
--preload-file shaders/resources/game_of_life/breeder.png@resources/game_of_life/breeder.png
|
||||||
|
|
||||||
shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c
|
shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.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/shaders/glsl100/reload.fs@resources/shaders/glsl100/reload.fs
|
--preload-file shaders/resources/shaders/glsl100/reload.fs@resources/shaders/glsl100/reload.fs
|
||||||
|
|
@ -1444,6 +1541,11 @@ audio/audio_sound_positioning: audio/audio_sound_positioning.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/coin.wav@resources/coin.wav
|
--preload-file audio/resources/coin.wav@resources/coin.wav
|
||||||
|
|
||||||
|
audio/audio_spectrum_visualizer: audio/audio_spectrum_visualizer.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file audio/resources/shaders/glsl100/fft.fs@resources/shaders/glsl100/fft.fs \
|
||||||
|
--preload-file audio/resources/country.mp3@resources/country.mp3
|
||||||
|
|
||||||
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,11 +17,11 @@ 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: 187]
|
## EXAMPLES COLLECTION [TOTAL: 208]
|
||||||
|
|
||||||
### category: core [45]
|
### category: core [48]
|
||||||
|
|
||||||
Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality.
|
Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality.
|
||||||
|
|
||||||
| 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 |
|
||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
|
|
@ -43,7 +43,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
|
||||||
| [core_3d_camera_free](core/core_3d_camera_free.c) | <img src="core/core_3d_camera_free.png" alt="core_3d_camera_free" width="80"> | ⭐☆☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_3d_camera_free](core/core_3d_camera_free.c) | <img src="core/core_3d_camera_free.png" alt="core_3d_camera_free" width="80"> | ⭐☆☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | <img src="core/core_3d_camera_first_person.png" alt="core_3d_camera_first_person" width="80"> | ⭐⭐☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | <img src="core/core_3d_camera_first_person.png" alt="core_3d_camera_first_person" width="80"> | ⭐⭐☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_3d_camera_split_screen](core/core_3d_camera_split_screen.c) | <img src="core/core_3d_camera_split_screen.png" alt="core_3d_camera_split_screen" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Jeffery Myers](https://github.com/JeffM2501) |
|
| [core_3d_camera_split_screen](core/core_3d_camera_split_screen.c) | <img src="core/core_3d_camera_split_screen.png" alt="core_3d_camera_split_screen" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||||
| [core_3d_camera_fps](core/core_3d_camera_fps.c) | <img src="core/core_3d_camera_fps.png" alt="core_3d_camera_fps" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) |
|
| [core_3d_camera_fps](core/core_3d_camera_fps.c) | <img src="core/core_3d_camera_fps.png" alt="core_3d_camera_fps" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
||||||
| [core_3d_picking](core/core_3d_picking.c) | <img src="core/core_3d_picking.png" alt="core_3d_picking" width="80"> | ⭐⭐☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_3d_picking](core/core_3d_picking.c) | <img src="core/core_3d_picking.png" alt="core_3d_picking" width="80"> | ⭐⭐☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_world_screen](core/core_world_screen.c) | <img src="core/core_world_screen.png" alt="core_world_screen" width="80"> | ⭐⭐☆☆ | 1.3 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_world_screen](core/core_world_screen.c) | <img src="core/core_world_screen.png" alt="core_world_screen" width="80"> | ⭐⭐☆☆ | 1.3 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_window_flags](core/core_window_flags.c) | <img src="core/core_window_flags.png" alt="core_window_flags" width="80"> | ⭐⭐⭐☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_window_flags](core/core_window_flags.c) | <img src="core/core_window_flags.png" alt="core_window_flags" width="80"> | ⭐⭐⭐☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
|
@ -61,17 +61,20 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
|
||||||
| [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) |
|
| [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) |
|
||||||
| [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_high_dpi](core/core_high_dpi.c) | <img src="core/core_high_dpi.png" alt="core_high_dpi" 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"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [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_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"> | ⭐☆☆☆ | 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"> | ⭐☆☆☆ | 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"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [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 | [Robin](https://github.com/RobinsAviary) |
|
| [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_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_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) |
|
||||||
|
|
||||||
### category: shapes [32]
|
### category: shapes [39]
|
||||||
|
|
||||||
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
|
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
|
||||||
|
|
||||||
|
|
@ -105,11 +108,19 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||||
| [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 | 5.6-dev | [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_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 | 5.6-dev | [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 | 5.6-dev | [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_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_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_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_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_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_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) |
|
||||||
|
|
||||||
### category: textures [26]
|
### category: textures [30]
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
|
@ -140,9 +151,13 @@ Examples using raylib textures functionality, including image/textures loading/g
|
||||||
| [textures_image_kernel](textures/textures_image_kernel.c) | <img src="textures/textures_image_kernel.png" alt="textures_image_kernel" width="80"> | ⭐⭐⭐⭐️ | 1.3 | 1.3 | [Karim Salem](https://github.com/kimo-s) |
|
| [textures_image_kernel](textures/textures_image_kernel.c) | <img src="textures/textures_image_kernel.png" alt="textures_image_kernel" width="80"> | ⭐⭐⭐⭐️ | 1.3 | 1.3 | [Karim Salem](https://github.com/kimo-s) |
|
||||||
| [textures_image_channel](textures/textures_image_channel.c) | <img src="textures/textures_image_channel.png" alt="textures_image_channel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Bruno Cabral](https://github.com/brccabral) |
|
| [textures_image_channel](textures/textures_image_channel.c) | <img src="textures/textures_image_channel.png" alt="textures_image_channel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Bruno Cabral](https://github.com/brccabral) |
|
||||||
| [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_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_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) |
|
||||||
|
|
||||||
### category: text [15]
|
### category: text [16]
|
||||||
|
|
||||||
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
|
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
|
||||||
|
|
||||||
|
|
@ -163,8 +178,9 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
||||||
| [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"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [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"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [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) |
|
||||||
|
|
||||||
### category: models [25]
|
### category: models [27]
|
||||||
|
|
||||||
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
|
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
|
||||||
|
|
||||||
|
|
@ -195,8 +211,10 @@ Examples using raylib models functionality, including models loading/generation
|
||||||
| [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"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [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"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [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_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) |
|
||||||
|
|
||||||
### category: shaders [31]
|
### category: shaders [33]
|
||||||
|
|
||||||
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.c) module.
|
||||||
|
|
||||||
|
|
@ -214,6 +232,8 @@ 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_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_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) |
|
||||||
|
|
@ -232,9 +252,9 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
||||||
| [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"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) |
|
||||||
| [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_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) |
|
||||||
|
|
||||||
### category: audio [8]
|
### category: audio [9]
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
|
@ -248,6 +268,7 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
||||||
| [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) |
|
||||||
|
|
||||||
### category: others [6]
|
### category: others [6]
|
||||||
|
|
||||||
|
|
@ -263,4 +284,4 @@ Examples showing raylib misc functionality that does not fit in other categories
|
||||||
| [web_basic_window](others/web_basic_window.c) | <img src="others/web_basic_window.png" alt="web_basic_window" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
| [web_basic_window](others/web_basic_window.c) | <img src="others/web_basic_window.png" alt="web_basic_window" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
|
||||||
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!
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,12 @@ int main(void)
|
||||||
float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f]
|
float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f]
|
||||||
bool pause = false; // Music playing paused
|
bool pause = false; // Music playing paused
|
||||||
|
|
||||||
|
float pan = 0.0f; // Default audio pan center [-1.0f..1.0f]
|
||||||
|
SetMusicPan(music, pan);
|
||||||
|
|
||||||
|
float volume = 0.8f; // Default audio volume [0.0f..1.0f]
|
||||||
|
SetMusicVolume(music, volume);
|
||||||
|
|
||||||
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
|
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -62,6 +68,34 @@ int main(void)
|
||||||
else ResumeMusicStream(music);
|
else ResumeMusicStream(music);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set audio pan
|
||||||
|
if (IsKeyDown(KEY_LEFT))
|
||||||
|
{
|
||||||
|
pan -= 0.05f;
|
||||||
|
if (pan < -1.0f) pan = -1.0f;
|
||||||
|
SetMusicPan(music, pan);
|
||||||
|
}
|
||||||
|
else if (IsKeyDown(KEY_RIGHT))
|
||||||
|
{
|
||||||
|
pan += 0.05f;
|
||||||
|
if (pan > 1.0f) pan = 1.0f;
|
||||||
|
SetMusicPan(music, pan);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set audio volume
|
||||||
|
if (IsKeyDown(KEY_DOWN))
|
||||||
|
{
|
||||||
|
volume -= 0.05f;
|
||||||
|
if (volume < 0.0f) volume = 0.0f;
|
||||||
|
SetMusicVolume(music, volume);
|
||||||
|
}
|
||||||
|
else if (IsKeyDown(KEY_UP))
|
||||||
|
{
|
||||||
|
volume += 0.05f;
|
||||||
|
if (volume > 1.0f) volume = 1.0f;
|
||||||
|
SetMusicVolume(music, volume);
|
||||||
|
}
|
||||||
|
|
||||||
// Get normalized time played for current music stream
|
// Get normalized time played for current music stream
|
||||||
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music);
|
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music);
|
||||||
|
|
||||||
|
|
@ -76,6 +110,11 @@ int main(void)
|
||||||
|
|
||||||
DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
|
DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE);
|
||||||
|
DrawRectangle(300, 100, 200, 12, LIGHTGRAY);
|
||||||
|
DrawRectangleLines(300, 100, 200, 12, GRAY);
|
||||||
|
DrawRectangle((int)(300 + (pan + 1.0f)/2.0f*200 - 5), 92, 10, 28, DARKGRAY);
|
||||||
|
|
||||||
DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
|
DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
|
||||||
DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON);
|
DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON);
|
||||||
DrawRectangleLines(200, 200, 400, 12, GRAY);
|
DrawRectangleLines(200, 200, 400, 12, GRAY);
|
||||||
|
|
@ -83,6 +122,11 @@ int main(void)
|
||||||
DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY);
|
DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY);
|
||||||
DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY);
|
DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN);
|
||||||
|
DrawRectangle(300, 360, 200, 12, LIGHTGRAY);
|
||||||
|
DrawRectangleLines(300, 360, 200, 12, GRAY);
|
||||||
|
DrawRectangle((int)(300 + volume*200 - 5), 352, 10, 28, DARKGRAY);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ int main(void)
|
||||||
memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short));
|
memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short));
|
||||||
|
|
||||||
// Update cursors and loop audio
|
// Update cursors and loop audio
|
||||||
readCursor = (readCursor + writeLength) % waveLength;
|
readCursor = (readCursor + writeLength)%waveLength;
|
||||||
|
|
||||||
writeCursor += writeLength;
|
writeCursor += writeLength;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ int main(void)
|
||||||
};
|
};
|
||||||
|
|
||||||
SetSoundPosition(camera, sound, spherePos, 20.0f);
|
SetSoundPosition(camera, sound, spherePos, 20.0f);
|
||||||
|
|
||||||
if (!IsSoundPlaying(sound)) PlaySound(sound);
|
if (!IsSoundPlaying(sound)) PlaySound(sound);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -94,6 +95,8 @@ int main(void)
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
285
examples/audio/audio_spectrum_visualizer.c
Normal file
|
|
@ -0,0 +1,285 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [audio] example - spectrum visualizer
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 6.0, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Inspired by Inigo Quilez's https://www.shadertoy.com/
|
||||||
|
* Resources/specification: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8
|
||||||
|
*
|
||||||
|
* Example created by created by IANN (@meisei4) 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) 2025 IANN (@meisei4)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
#define GLSL_VERSION 330
|
||||||
|
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||||
|
#define GLSL_VERSION 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MONO 1
|
||||||
|
#define SAMPLE_RATE 44100
|
||||||
|
#define SAMPLE_RATE_F 44100.0f
|
||||||
|
#define FFT_WINDOW_SIZE 1024
|
||||||
|
#define BUFFER_SIZE 512
|
||||||
|
#define PER_SAMPLE_BIT_DEPTH 16
|
||||||
|
#define AUDIO_STREAM_RING_BUFFER_SIZE (FFT_WINDOW_SIZE*2)
|
||||||
|
#define EFFECTIVE_SAMPLE_RATE (SAMPLE_RATE_F*0.5f)
|
||||||
|
#define WINDOW_TIME ((double)FFT_WINDOW_SIZE/(double)EFFECTIVE_SAMPLE_RATE)
|
||||||
|
#define FFT_HISTORICAL_SMOOTHING_DUR 2.0f
|
||||||
|
#define MIN_DECIBELS (-100.0f) // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/minDecibels
|
||||||
|
#define MAX_DECIBELS (-30.0f) // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/maxDecibels
|
||||||
|
#define INVERSE_DECIBEL_RANGE (1.0f/(MAX_DECIBELS - MIN_DECIBELS))
|
||||||
|
#define DB_TO_LINEAR_SCALE (20.0f/2.302585092994046f)
|
||||||
|
#define SMOOTHING_TIME_CONSTANT 0.8f // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/smoothingTimeConstant
|
||||||
|
#define TEXTURE_HEIGHT 1
|
||||||
|
#define FFT_ROW 0
|
||||||
|
#define UNUSED_CHANNEL 0.0f
|
||||||
|
|
||||||
|
typedef struct FFTComplex { float real, imaginary; } FFTComplex;
|
||||||
|
|
||||||
|
typedef struct FFTData {
|
||||||
|
FFTComplex *spectrum;
|
||||||
|
FFTComplex *workBuffer;
|
||||||
|
float *prevMagnitudes;
|
||||||
|
float (*fftHistory)[BUFFER_SIZE];
|
||||||
|
int fftHistoryLen;
|
||||||
|
int historyPos;
|
||||||
|
double lastFftTime;
|
||||||
|
float tapbackPos;
|
||||||
|
} FFTData;
|
||||||
|
|
||||||
|
static void CaptureFrame(FFTData *fftData, const float *audioSamples);
|
||||||
|
static void RenderFrame(const FFTData *fftData, Image *fftImage);
|
||||||
|
static void CooleyTukeyFFTSlow(FFTComplex *spectrum, int n);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//----------------------------------------------------------------------------------- ---
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [audio] example - spectrum visualizer");
|
||||||
|
|
||||||
|
Image fftImage = GenImageColor(BUFFER_SIZE, TEXTURE_HEIGHT, WHITE);
|
||||||
|
Texture2D fftTexture = LoadTextureFromImage(fftImage);
|
||||||
|
RenderTexture2D bufferA = LoadRenderTexture(screenWidth, screenHeight);
|
||||||
|
Vector2 iResolution = { (float)screenWidth, (float)screenHeight };
|
||||||
|
|
||||||
|
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/fft.fs", GLSL_VERSION));
|
||||||
|
|
||||||
|
int iResolutionLocation = GetShaderLocation(shader, "iResolution");
|
||||||
|
int iChannel0Location = GetShaderLocation(shader, "iChannel0");
|
||||||
|
SetShaderValue(shader, iResolutionLocation, &iResolution, SHADER_UNIFORM_VEC2);
|
||||||
|
SetShaderValueTexture(shader, iChannel0Location, fftTexture);
|
||||||
|
|
||||||
|
InitAudioDevice();
|
||||||
|
SetAudioStreamBufferSizeDefault(AUDIO_STREAM_RING_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// WARNING: Memory out-of-bounds on PLATFORM_WEB
|
||||||
|
Wave wav = LoadWave("resources/country.mp3");
|
||||||
|
WaveFormat(&wav, SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO);
|
||||||
|
|
||||||
|
AudioStream audioStream = LoadAudioStream(SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO);
|
||||||
|
PlayAudioStream(audioStream);
|
||||||
|
|
||||||
|
int fftHistoryLen = (int)ceilf(FFT_HISTORICAL_SMOOTHING_DUR/WINDOW_TIME) + 1;
|
||||||
|
|
||||||
|
FFTData fft = {
|
||||||
|
.spectrum = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE),
|
||||||
|
.workBuffer = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE),
|
||||||
|
.prevMagnitudes = RL_CALLOC(BUFFER_SIZE, sizeof(float)),
|
||||||
|
.fftHistory = RL_CALLOC(fftHistoryLen, sizeof(float[BUFFER_SIZE])),
|
||||||
|
.fftHistoryLen = fftHistoryLen,
|
||||||
|
.historyPos = 0,
|
||||||
|
.lastFftTime = 0.0,
|
||||||
|
.tapbackPos = 0.01f
|
||||||
|
};
|
||||||
|
|
||||||
|
int wavCursor = 0;
|
||||||
|
const short *wavPCM16 = wav.data;
|
||||||
|
|
||||||
|
short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 };
|
||||||
|
float audioSamples[FFT_WINDOW_SIZE] = { 0 };
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
while (IsAudioStreamProcessed(audioStream))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < AUDIO_STREAM_RING_BUFFER_SIZE; i++)
|
||||||
|
{
|
||||||
|
int left = (wav.channels == 2)? wavPCM16[wavCursor*2 + 0] : wavPCM16[wavCursor];
|
||||||
|
int right = (wav.channels == 2)? wavPCM16[wavCursor*2 + 1] : left;
|
||||||
|
chunkSamples[i] = (short)((left + right)/2);
|
||||||
|
|
||||||
|
if (++wavCursor >= wav.frameCount) wavCursor = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAudioStream(audioStream, chunkSamples, AUDIO_STREAM_RING_BUFFER_SIZE);
|
||||||
|
|
||||||
|
for (int i = 0; i < FFT_WINDOW_SIZE; i++) audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CaptureFrame(&fft, audioSamples);
|
||||||
|
RenderFrame(&fft, &fftImage);
|
||||||
|
UpdateTexture(fftTexture, fftImage.data);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginShaderMode(shader);
|
||||||
|
SetShaderValueTexture(shader, iChannel0Location, fftTexture);
|
||||||
|
DrawTextureRec(bufferA.texture,
|
||||||
|
(Rectangle){ 0, 0, (float)screenWidth, (float)-screenHeight },
|
||||||
|
(Vector2){ 0, 0 }, WHITE);
|
||||||
|
EndShaderMode();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadShader(shader);
|
||||||
|
UnloadRenderTexture(bufferA);
|
||||||
|
UnloadTexture(fftTexture);
|
||||||
|
UnloadImage(fftImage);
|
||||||
|
UnloadAudioStream(audioStream);
|
||||||
|
UnloadWave(wav);
|
||||||
|
CloseAudioDevice();
|
||||||
|
|
||||||
|
RL_FREE(fft.spectrum);
|
||||||
|
RL_FREE(fft.workBuffer);
|
||||||
|
RL_FREE(fft.prevMagnitudes);
|
||||||
|
RL_FREE(fft.fftHistory);
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cooley–Tukey FFT https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Data_reordering,_bit_reversal,_and_in-place_algorithms
|
||||||
|
static void CooleyTukeyFFTSlow(FFTComplex *spectrum, int n)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 1; i < n - 1; i++)
|
||||||
|
{
|
||||||
|
int bit = n >> 1;
|
||||||
|
while (j >= bit)
|
||||||
|
{
|
||||||
|
j -= bit;
|
||||||
|
bit >>= 1;
|
||||||
|
}
|
||||||
|
j += bit;
|
||||||
|
if (i < j)
|
||||||
|
{
|
||||||
|
FFTComplex temp = spectrum[i];
|
||||||
|
spectrum[i] = spectrum[j];
|
||||||
|
spectrum[j] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int len = 2; len <= n; len <<= 1)
|
||||||
|
{
|
||||||
|
float angle = -2.0f*PI/len;
|
||||||
|
FFTComplex twiddleUnit = { cosf(angle), sinf(angle) };
|
||||||
|
for (int i = 0; i < n; i += len)
|
||||||
|
{
|
||||||
|
FFTComplex twiddleCurrent = { 1.0f, 0.0f };
|
||||||
|
for (int j = 0; j < len/2; j++)
|
||||||
|
{
|
||||||
|
FFTComplex even = spectrum[i + j];
|
||||||
|
FFTComplex odd = spectrum[i + j + len/2];
|
||||||
|
FFTComplex twiddledOdd = {
|
||||||
|
odd.real*twiddleCurrent.real - odd.imaginary*twiddleCurrent.imaginary,
|
||||||
|
odd.real*twiddleCurrent.imaginary + odd.imaginary*twiddleCurrent.real
|
||||||
|
};
|
||||||
|
|
||||||
|
spectrum[i + j].real = even.real + twiddledOdd.real;
|
||||||
|
spectrum[i + j].imaginary = even.imaginary + twiddledOdd.imaginary;
|
||||||
|
spectrum[i + j + len/2].real = even.real - twiddledOdd.real;
|
||||||
|
spectrum[i + j + len/2].imaginary = even.imaginary - twiddledOdd.imaginary;
|
||||||
|
|
||||||
|
float twiddleRealNext = twiddleCurrent.real*twiddleUnit.real - twiddleCurrent.imaginary*twiddleUnit.imaginary;
|
||||||
|
twiddleCurrent.imaginary = twiddleCurrent.real*twiddleUnit.imaginary + twiddleCurrent.imaginary*twiddleUnit.real;
|
||||||
|
twiddleCurrent.real = twiddleRealNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CaptureFrame(FFTData *fftData, const float *audioSamples)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < FFT_WINDOW_SIZE; i++)
|
||||||
|
{
|
||||||
|
float x = (2.0f*PI*i)/(FFT_WINDOW_SIZE - 1.0f);
|
||||||
|
float blackmanWeight = 0.42f - 0.5f*cosf(x) + 0.08f*cosf(2.0f*x); // https://en.wikipedia.org/wiki/Window_function#Blackman_window
|
||||||
|
fftData->workBuffer[i].real = audioSamples[i]*blackmanWeight;
|
||||||
|
fftData->workBuffer[i].imaginary = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CooleyTukeyFFTSlow(fftData->workBuffer, FFT_WINDOW_SIZE);
|
||||||
|
memcpy(fftData->spectrum, fftData->workBuffer, sizeof(FFTComplex)*FFT_WINDOW_SIZE);
|
||||||
|
|
||||||
|
float smoothedSpectrum[BUFFER_SIZE];
|
||||||
|
|
||||||
|
for (int bin = 0; bin < BUFFER_SIZE; bin++)
|
||||||
|
{
|
||||||
|
float re = fftData->workBuffer[bin].real;
|
||||||
|
float im = fftData->workBuffer[bin].imaginary;
|
||||||
|
float linearMagnitude = sqrtf(re*re + im*im)/FFT_WINDOW_SIZE;
|
||||||
|
|
||||||
|
float smoothedMagnitude = SMOOTHING_TIME_CONSTANT*fftData->prevMagnitudes[bin] + (1.0f - SMOOTHING_TIME_CONSTANT)*linearMagnitude;
|
||||||
|
fftData->prevMagnitudes[bin] = smoothedMagnitude;
|
||||||
|
|
||||||
|
float db = logf(fmaxf(smoothedMagnitude, 1e-40f))*DB_TO_LINEAR_SCALE;
|
||||||
|
float normalized = (db - MIN_DECIBELS)*INVERSE_DECIBEL_RANGE;
|
||||||
|
smoothedSpectrum[bin] = Clamp(normalized, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
fftData->lastFftTime = GetTime();
|
||||||
|
memcpy(fftData->fftHistory[fftData->historyPos], smoothedSpectrum, sizeof(smoothedSpectrum));
|
||||||
|
fftData->historyPos = (fftData->historyPos + 1)%fftData->fftHistoryLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RenderFrame(const FFTData *fftData, Image *fftImage)
|
||||||
|
{
|
||||||
|
double framesSinceTapback = floor(fftData->tapbackPos/WINDOW_TIME);
|
||||||
|
framesSinceTapback = Clamp(framesSinceTapback, 0.0, fftData->fftHistoryLen - 1);
|
||||||
|
|
||||||
|
int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback)%fftData->fftHistoryLen;
|
||||||
|
if (historyPosition < 0) historyPosition += fftData->fftHistoryLen;
|
||||||
|
|
||||||
|
const float *amplitude = fftData->fftHistory[historyPosition];
|
||||||
|
for (int bin = 0; bin < BUFFER_SIZE; bin++) ImageDrawPixel(fftImage, bin, FFT_ROW, ColorFromNormalized((Vector4){ amplitude[bin], UNUSED_CHANNEL, UNUSED_CHANNEL, UNUSED_CHANNEL }));
|
||||||
|
}
|
||||||
BIN
examples/audio/audio_spectrum_visualizer.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
37
examples/audio/resources/shaders/glsl100/fft.fs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#version 100
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform vec2 iResolution;
|
||||||
|
uniform sampler2D iChannel0;
|
||||||
|
|
||||||
|
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
const float FFT_ROW = 0.0;
|
||||||
|
const float NUM_OF_BINS = 512.0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 fragCoord = fragTexCoord*iResolution;
|
||||||
|
float cellWidth = iResolution.x/NUM_OF_BINS;
|
||||||
|
float binIndex = floor(fragCoord.x/cellWidth);
|
||||||
|
float localX = mod(fragCoord.x, cellWidth);
|
||||||
|
float barWidth = cellWidth - 1.0;
|
||||||
|
vec4 color = WHITE;
|
||||||
|
|
||||||
|
if (localX <= barWidth)
|
||||||
|
{
|
||||||
|
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||||
|
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||||
|
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||||
|
|
||||||
|
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
||||||
35
examples/audio/resources/shaders/glsl120/fft.fs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform vec2 iResolution;
|
||||||
|
uniform sampler2D iChannel0;
|
||||||
|
|
||||||
|
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
const float FFT_ROW = 0.0;
|
||||||
|
const float NUM_OF_BINS = 512.0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 fragCoord = fragTexCoord*iResolution;
|
||||||
|
float cellWidth = iResolution.x/NUM_OF_BINS;
|
||||||
|
float binIndex = floor(fragCoord.x/cellWidth);
|
||||||
|
float localX = mod(fragCoord.x, cellWidth);
|
||||||
|
float barWidth = cellWidth - 1.0;
|
||||||
|
vec4 color = WHITE;
|
||||||
|
|
||||||
|
if (localX <= barWidth)
|
||||||
|
{
|
||||||
|
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||||
|
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||||
|
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||||
|
|
||||||
|
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
||||||
35
examples/audio/resources/shaders/glsl330/fft.fs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
uniform vec2 iResolution;
|
||||||
|
uniform sampler2D iChannel0;
|
||||||
|
|
||||||
|
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
const float FFT_ROW = 0.0;
|
||||||
|
const float NUM_OF_BINS = 512.0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 fragCoord = fragTexCoord*iResolution;
|
||||||
|
float cellWidth = iResolution.x/NUM_OF_BINS;
|
||||||
|
float binIndex = floor(fragCoord.x/cellWidth);
|
||||||
|
float localX = mod(fragCoord.x, cellWidth);
|
||||||
|
float barWidth = cellWidth - 1.0;
|
||||||
|
vec4 color = WHITE;
|
||||||
|
|
||||||
|
if (localX <= barWidth)
|
||||||
|
{
|
||||||
|
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||||
|
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||||
|
float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||||
|
|
||||||
|
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalColor = color;
|
||||||
|
}
|
||||||
|
|
@ -125,8 +125,8 @@ int main(void)
|
||||||
DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f));
|
DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f));
|
||||||
DrawRectangleLines( 10, 10, 250, 113, BLUE);
|
DrawRectangleLines( 10, 10, 250, 113, BLUE);
|
||||||
|
|
||||||
DrawText("Free 2d camera controls:", 20, 20, 10, BLACK);
|
DrawText("Free 2D camera controls:", 20, 20, 10, BLACK);
|
||||||
DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY);
|
DrawText("- Right/Left to move player", 40, 40, 10, DARKGRAY);
|
||||||
DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY);
|
DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY);
|
||||||
DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY);
|
DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY);
|
||||||
DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY);
|
DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY);
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 8.3 KiB |
|
|
@ -23,7 +23,7 @@
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
int main ()
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
@ -35,9 +35,9 @@ int main ()
|
||||||
Camera2D camera = { 0 };
|
Camera2D camera = { 0 };
|
||||||
camera.zoom = 1.0f;
|
camera.zoom = 1.0f;
|
||||||
|
|
||||||
int zoomMode = 0; // 0-Mouse Wheel, 1-Mouse Move
|
int zoomMode = 0; // 0-Mouse Wheel, 1-Mouse Move
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -93,6 +93,7 @@ int main ()
|
||||||
// under the cursor to the screen space point under the cursor at any zoom
|
// under the cursor to the screen space point under the cursor at any zoom
|
||||||
camera.target = mouseWorldPos;
|
camera.target = mouseWorldPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
|
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
|
||||||
{
|
{
|
||||||
// Zoom increment
|
// Zoom increment
|
||||||
|
|
@ -110,7 +111,6 @@ int main ()
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
BeginMode2D(camera);
|
BeginMode2D(camera);
|
||||||
|
|
||||||
// Draw the 3d grid, rotated 90 degrees and centered around 0,0
|
// Draw the 3d grid, rotated 90 degrees and centered around 0,0
|
||||||
// just so we have something in the XY plane
|
// just so we have something in the XY plane
|
||||||
rlPushMatrix();
|
rlPushMatrix();
|
||||||
|
|
@ -121,7 +121,6 @@ int main ()
|
||||||
|
|
||||||
// Draw a reference circle
|
// Draw a reference circle
|
||||||
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 50, MAROON);
|
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 50, MAROON);
|
||||||
|
|
||||||
EndMode2D();
|
EndMode2D();
|
||||||
|
|
||||||
// Draw mouse reference
|
// Draw mouse reference
|
||||||
|
|
@ -142,5 +141,6 @@ int main ()
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -226,10 +226,10 @@ void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envI
|
||||||
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera);
|
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera);
|
||||||
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera);
|
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera);
|
||||||
|
|
||||||
if (max.x < width) camera->offset.x = width - (max.x - width/2);
|
if (max.x < width) camera->offset.x = width - (max.x - (float)width/2);
|
||||||
if (max.y < height) camera->offset.y = height - (max.y - height/2);
|
if (max.y < height) camera->offset.y = height - (max.y - (float)height/2);
|
||||||
if (min.x > 0) camera->offset.x = width/2 - min.x;
|
if (min.x > 0) camera->offset.x = (float)width/2 - min.x;
|
||||||
if (min.y > 0) camera->offset.y = height/2 - min.y;
|
if (min.y > 0) camera->offset.y = (float)height/2 - min.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
|
void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,12 @@
|
||||||
*
|
*
|
||||||
* 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 5.5
|
||||||
*
|
*
|
||||||
* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* 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) 2025 Agnis Aldins (@nezvers)
|
* Copyright (c) 2025 Agnis Aldiņš (@nezvers)
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,10 +225,10 @@ int main(void)
|
||||||
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera);
|
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera);
|
||||||
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera);
|
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera);
|
||||||
|
|
||||||
if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - screenWidth/2);
|
if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - (float)screenWidth/2);
|
||||||
if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - screenHeight/2);
|
if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - (float)screenHeight/2);
|
||||||
if (min.x > 0) camera.offset.x = screenWidth/2 - min.x;
|
if (min.x > 0) camera.offset.x = (float)screenWidth/2 - min.x;
|
||||||
if (min.y > 0) camera.offset.y = screenHeight/2 - min.y;
|
if (min.y > 0) camera.offset.y = (float)screenHeight/2 - min.y;
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Events management
|
// Events management
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,25 @@
|
||||||
*
|
*
|
||||||
* raylib [core] example - clipboard text
|
* raylib [core] example - clipboard text
|
||||||
*
|
*
|
||||||
* Example complexity rating: [★☆☆☆] 1/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 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
*
|
*
|
||||||
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Ananth S (@Ananth1839) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* 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) 2025 Robin (@RobinsAviary)
|
* Copyright (c) 2025 Ananth S (@Ananth1839)
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "raygui.h"
|
||||||
|
|
||||||
|
#define MAX_TEXT_SAMPLES 5
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
|
|
@ -31,28 +34,32 @@ int main(void)
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - clipboard text");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - clipboard text");
|
||||||
|
|
||||||
const char* clipboardText = NULL;
|
// Define some sample texts
|
||||||
|
const char *sampleTexts[MAX_TEXT_SAMPLES] = {
|
||||||
|
"Hello from raylib!",
|
||||||
|
"The quick brown fox jumps over the lazy dog",
|
||||||
|
"Clipboard operations are useful!",
|
||||||
|
"raylib is a simple and easy-to-use library",
|
||||||
|
"Copy and paste me!"
|
||||||
|
};
|
||||||
|
|
||||||
// List of text the user can switch through and copy
|
const char *clipboardText = NULL;
|
||||||
const char* copyableText[] = {"raylib is fun", "hello, clipboard!", "potato chips"};
|
char inputBuffer[256] = "Hello from raylib!"; // Random initial string
|
||||||
|
|
||||||
unsigned int textIndex = 0;
|
// UI required variables
|
||||||
|
bool textBoxEditMode = false;
|
||||||
|
|
||||||
const char* popupText = NULL;
|
bool btnCutPressed = false;
|
||||||
|
bool btnCopyPressed = false;
|
||||||
|
bool btnPastePressed = false;
|
||||||
|
bool btnClearPressed = false;
|
||||||
|
bool btnRandomPressed = false;
|
||||||
|
|
||||||
// Initialize timers
|
// Set UI style
|
||||||
// The amount of time the pop-up text is on screen, before fading
|
GuiSetStyle(DEFAULT, TEXT_SIZE, 20);
|
||||||
const float maxTime = 3.0f;
|
GuiSetIconScale(2);
|
||||||
float textTimer = 0.0f;
|
|
||||||
// The length of time text is offset
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
const float animMaxTime = 0.1f;
|
|
||||||
float pasteAnim = 0.0f;
|
|
||||||
float copyAnim = 0.0f;
|
|
||||||
int copyAnimMult = 1;
|
|
||||||
float textAnim = 0.0f;
|
|
||||||
float textAlpha = 0.0f;
|
|
||||||
// Offset amount for animations
|
|
||||||
const int offsetAmount = -4;
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
|
|
@ -60,95 +67,55 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Check if the user has pressed the copy/paste key combinations
|
// Handle button interactions
|
||||||
bool pastePressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_V));
|
if (btnCutPressed)
|
||||||
bool copyPressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C));
|
|
||||||
|
|
||||||
// Update animation timers
|
|
||||||
if (textTimer > 0) textTimer -= GetFrameTime();
|
|
||||||
if (pasteAnim > 0) pasteAnim -= GetFrameTime();
|
|
||||||
if (copyAnim > 0) copyAnim -= GetFrameTime();
|
|
||||||
if (textAnim > 0) textAnim -= GetFrameTime();
|
|
||||||
|
|
||||||
// React to the user pressing paste
|
|
||||||
if (pastePressed)
|
|
||||||
{
|
{
|
||||||
// Most operating systems hide this information until the user presses Ctrl-V on the window.
|
SetClipboardText(inputBuffer);
|
||||||
|
clipboardText = GetClipboardText();
|
||||||
|
inputBuffer[0] = '\0'; // Quick solution to clear text
|
||||||
|
//memset(inputBuffer, 0, 256); // Clear full buffer properly
|
||||||
|
}
|
||||||
|
|
||||||
// Check to see if the clipboard contains an image
|
if (btnCopyPressed)
|
||||||
// This function does nothing outside of Windows, as it directly calls the Windows API
|
{
|
||||||
Image image = GetClipboardImage();
|
SetClipboardText(inputBuffer); // Copy text to clipboard
|
||||||
|
clipboardText = GetClipboardText(); // Get text from clipboard
|
||||||
|
}
|
||||||
|
|
||||||
if (IsImageValid(image))
|
if (btnPastePressed)
|
||||||
|
{
|
||||||
|
// Paste text from clipboard
|
||||||
|
clipboardText = GetClipboardText();
|
||||||
|
if (clipboardText != NULL) TextCopy(inputBuffer, clipboardText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btnClearPressed)
|
||||||
|
{
|
||||||
|
inputBuffer[0] = '\0'; // Quick solution to clear text
|
||||||
|
//memset(inputBuffer, 0, 256); // Clear full buffer properly
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btnRandomPressed)
|
||||||
|
{
|
||||||
|
// Get random text from sample list
|
||||||
|
TextCopy(inputBuffer, sampleTexts[GetRandomValue(0, MAX_TEXT_SAMPLES - 1)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick cut/copy/paste with keyboard shortcuts
|
||||||
|
if (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))
|
||||||
|
{
|
||||||
|
if (IsKeyPressed(KEY_X))
|
||||||
{
|
{
|
||||||
// Unload the image
|
SetClipboardText(inputBuffer);
|
||||||
UnloadImage(image);
|
inputBuffer[0] = '\0'; // Quick solution to clear text
|
||||||
// Update visuals
|
|
||||||
popupText = "clipboard contains image";
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (IsKeyPressed(KEY_C)) SetClipboardText(inputBuffer);
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_V))
|
||||||
{
|
{
|
||||||
// Get text from the user's clipboard
|
|
||||||
clipboardText = GetClipboardText();
|
clipboardText = GetClipboardText();
|
||||||
|
if (clipboardText != NULL) TextCopy(inputBuffer, clipboardText);
|
||||||
// Update visuals
|
|
||||||
popupText = "text pasted";
|
|
||||||
pasteAnim = animMaxTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset animation values
|
|
||||||
textTimer = maxTime;
|
|
||||||
textAnim = animMaxTime;
|
|
||||||
textAlpha = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// React to the user pressing copy
|
|
||||||
if (copyPressed)
|
|
||||||
{
|
|
||||||
// Set the text on the user's clipboard
|
|
||||||
SetClipboardText(copyableText[textIndex]);
|
|
||||||
|
|
||||||
// Reset values
|
|
||||||
textTimer = maxTime;
|
|
||||||
textAnim = animMaxTime;
|
|
||||||
copyAnim = animMaxTime;
|
|
||||||
copyAnimMult = 1;
|
|
||||||
textAlpha = 1;
|
|
||||||
// Update the text that pops up at the bottom of the screen
|
|
||||||
popupText = "text copied";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch to the next item in the list when the user presses up
|
|
||||||
if (IsKeyPressed(KEY_UP))
|
|
||||||
{
|
|
||||||
// Reset animation
|
|
||||||
copyAnim = animMaxTime;
|
|
||||||
copyAnimMult = 1;
|
|
||||||
|
|
||||||
textIndex += 1;
|
|
||||||
|
|
||||||
if (textIndex >= sizeof(copyableText) / sizeof(const char*)) // Length of array
|
|
||||||
{
|
|
||||||
// Loop back to the other end
|
|
||||||
textIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch to the previous item in the list when the user presses down
|
|
||||||
if (IsKeyPressed(KEY_DOWN))
|
|
||||||
{
|
|
||||||
// Reset animation
|
|
||||||
copyAnim = animMaxTime;
|
|
||||||
copyAnimMult = -1;
|
|
||||||
|
|
||||||
if (textIndex == 0)
|
|
||||||
{
|
|
||||||
// Loop back to the other end
|
|
||||||
textIndex = (sizeof(copyableText) / sizeof(const char*)) - 1; // Length of array minus one
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
textIndex -= 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -157,43 +124,32 @@ int main(void)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
// Draw the user's pasted text, if there is any yet
|
// Draw instructions
|
||||||
if (clipboardText)
|
GuiLabel((Rectangle){ 50, 20, 700, 36 }, "Use the BUTTONS or KEY SHORTCUTS:");
|
||||||
{
|
DrawText("[CTRL+X] - CUT | [CTRL+C] COPY | [CTRL+V] | PASTE", 50, 60, 20, MAROON);
|
||||||
// Offset animation
|
|
||||||
int offset = 0;
|
|
||||||
if (pasteAnim > 0) offset = offsetAmount;
|
|
||||||
|
|
||||||
// Draw the pasted text
|
// Draw text box
|
||||||
DrawText("pasted clipboard:", 10, 10 + offset, 20, DARKGREEN);
|
if (GuiTextBox((Rectangle){ 50, 120, 652, 40 }, inputBuffer, 256, textBoxEditMode)) textBoxEditMode = !textBoxEditMode;
|
||||||
DrawText(clipboardText, 10, 30 + offset, 20, DARKGRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Offset animation
|
// Random text button
|
||||||
int textOffset = 0;
|
btnRandomPressed = GuiButton((Rectangle){ 50 + 652 + 8, 120, 40, 40 }, "#77#");
|
||||||
if (copyAnim > 0) textOffset = offsetAmount;
|
|
||||||
|
|
||||||
// Draw copyable text and controls
|
// Draw buttons
|
||||||
DrawText(copyableText[textIndex], 10, 330 + (textOffset * copyAnimMult), 20, MAROON);
|
btnCutPressed = GuiButton((Rectangle){ 50, 180, 158, 40 }, "#17#CUT");
|
||||||
DrawText("up/down to change string, ctrl-c to copy, ctrl-v to paste", 10, 355, 20, DARKGRAY);
|
btnCopyPressed = GuiButton((Rectangle){ 50 + 165, 180, 158, 40 }, "#16#COPY");
|
||||||
|
btnPastePressed = GuiButton((Rectangle){ 50 + 165*2, 180, 158, 40 }, "#18#PASTE");
|
||||||
|
btnClearPressed = GuiButton((Rectangle){ 50 + 165*3, 180, 158, 40 }, "#143#CLEAR");
|
||||||
|
|
||||||
// Alpha / Offset animation
|
// Draw clipboard status
|
||||||
if (textAlpha > 0)
|
GuiSetState(STATE_DISABLED);
|
||||||
{
|
GuiLabel((Rectangle){ 50, 260, 700, 40 }, "Clipboard current text data:");
|
||||||
// Offset animation
|
GuiSetStyle(TEXTBOX, TEXT_READONLY, 1);
|
||||||
int offset = 0;
|
GuiTextBox((Rectangle){ 50, 300, 700, 40 }, (char *)clipboardText, 256, false);
|
||||||
if (textAnim > 0) offset = offsetAmount;
|
GuiSetStyle(TEXTBOX, TEXT_READONLY, 0);
|
||||||
// Draw pop up text
|
GuiLabel((Rectangle){ 50, 360, 700, 40 }, "Try copying text from other applications and pasting here!");
|
||||||
DrawText(popupText, 10, 425 + offset, 20, ColorAlpha(DARKGREEN, textAlpha));
|
GuiSetState(STATE_NORMAL);
|
||||||
|
|
||||||
// Fade-out animation
|
|
||||||
if (textTimer < 0)
|
|
||||||
{
|
|
||||||
textAlpha -= GetFrameTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
143
examples/core/core_compute_hash.c
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - compute hash
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* 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) 2025 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "raygui.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
static char *GetDataAsHexText(const unsigned int *data, int dataSize);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - compute hash");
|
||||||
|
|
||||||
|
// UI controls variables
|
||||||
|
char textInput[96] = "The quick brown fox jumps over the lazy dog.";
|
||||||
|
bool textBoxEditMode = false;
|
||||||
|
bool btnComputeHashes = false;
|
||||||
|
|
||||||
|
// Data hash values
|
||||||
|
unsigned int hashCRC32 = 0;
|
||||||
|
unsigned int *hashMD5 = NULL;
|
||||||
|
unsigned int *hashSHA1 = NULL;
|
||||||
|
unsigned int *hashSHA256 = NULL;
|
||||||
|
|
||||||
|
// Base64 encoded data
|
||||||
|
char *base64Text = NULL;
|
||||||
|
int base64TextSize = 0;
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (btnComputeHashes)
|
||||||
|
{
|
||||||
|
int textInputLen = strlen(textInput);
|
||||||
|
|
||||||
|
// Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
|
||||||
|
base64Text = EncodeDataBase64((unsigned char *)textInput, textInputLen, &base64TextSize);
|
||||||
|
|
||||||
|
hashCRC32 = ComputeCRC32((unsigned char *)textInput, textInputLen); // Compute CRC32 hash code (4 bytes)
|
||||||
|
hashMD5 = ComputeMD5((unsigned char *)textInput, textInputLen); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||||
|
hashSHA1 = ComputeSHA1((unsigned char *)textInput, textInputLen); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||||
|
hashSHA256 = ComputeSHA256((unsigned char *)textInput, textInputLen); // Compute SHA256 hash code, returns static int[8] (32 bytes)
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
GuiSetStyle(DEFAULT, TEXT_SIZE, 20);
|
||||||
|
GuiSetStyle(DEFAULT, TEXT_SPACING, 2);
|
||||||
|
GuiLabel((Rectangle){ 40, 26, 720, 32 }, "INPUT DATA (TEXT):");
|
||||||
|
GuiSetStyle(DEFAULT, TEXT_SPACING, 1);
|
||||||
|
GuiSetStyle(DEFAULT, TEXT_SIZE, 10);
|
||||||
|
|
||||||
|
if (GuiTextBox((Rectangle){ 40, 64, 720, 32 }, textInput, 95, textBoxEditMode)) textBoxEditMode = !textBoxEditMode;
|
||||||
|
|
||||||
|
btnComputeHashes = GuiButton((Rectangle){ 40, 64 + 40, 720, 32 }, "COMPUTE INPUT DATA HASHES");
|
||||||
|
|
||||||
|
GuiSetStyle(DEFAULT, TEXT_SIZE, 20);
|
||||||
|
GuiSetStyle(DEFAULT, TEXT_SPACING, 2);
|
||||||
|
GuiLabel((Rectangle){ 40, 160, 720, 32 }, "INPUT DATA HASH VALUES:");
|
||||||
|
GuiSetStyle(DEFAULT, TEXT_SPACING, 1);
|
||||||
|
GuiSetStyle(DEFAULT, TEXT_SIZE, 10);
|
||||||
|
|
||||||
|
GuiSetStyle(TEXTBOX, TEXT_READONLY, 1);
|
||||||
|
GuiLabel((Rectangle){ 40, 200, 120, 32 }, "CRC32 [32 bit]:");
|
||||||
|
GuiTextBox((Rectangle){ 40 + 120, 200, 720 - 120, 32 }, GetDataAsHexText(&hashCRC32, 1), 120, false);
|
||||||
|
GuiLabel((Rectangle){ 40, 200 + 36, 120, 32 }, "MD5 [128 bit]:");
|
||||||
|
GuiTextBox((Rectangle){ 40 + 120, 200 + 36, 720 - 120, 32 }, GetDataAsHexText(hashMD5, 4), 120, false);
|
||||||
|
GuiLabel((Rectangle){ 40, 200 + 36*2, 120, 32 }, "SHA1 [160 bit]:");
|
||||||
|
GuiTextBox((Rectangle){ 40 + 120, 200 + 36*2, 720 - 120, 32 }, GetDataAsHexText(hashSHA1, 5), 120, false);
|
||||||
|
GuiLabel((Rectangle){ 40, 200 + 36*3, 120, 32 }, "SHA256 [256 bit]:");
|
||||||
|
GuiTextBox((Rectangle){ 40 + 120, 200 + 36*3, 720 - 120, 32 }, GetDataAsHexText(hashSHA256, 8), 120, false);
|
||||||
|
|
||||||
|
GuiSetState(STATE_FOCUSED);
|
||||||
|
GuiLabel((Rectangle){ 40, 200 + 36*5 - 30, 320, 32 }, "BONUS - BAS64 ENCODED STRING:");
|
||||||
|
GuiSetState(STATE_NORMAL);
|
||||||
|
GuiLabel((Rectangle){ 40, 200 + 36*5, 120, 32 }, "BASE64 ENCODING:");
|
||||||
|
GuiTextBox((Rectangle){ 40 + 120, 200 + 36*5, 720 - 120, 32 }, base64Text, 120, false);
|
||||||
|
GuiSetStyle(TEXTBOX, TEXT_READONLY, 0);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
MemFree(base64Text); // Free Base64 text data
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
static char *GetDataAsHexText(const unsigned int *data, int dataSize)
|
||||||
|
{
|
||||||
|
static char text[128] = { 0 };
|
||||||
|
memset(text, 0, 128);
|
||||||
|
|
||||||
|
if ((data != NULL) && (dataSize > 0) && (dataSize < ((128/8) - 1)))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < dataSize; i++) TextCopy(text + i*8, TextFormat("%08X", data[i]));
|
||||||
|
}
|
||||||
|
else TextCopy(text, "00000000");
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
BIN
examples/core/core_compute_hash.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
|
|
@ -17,11 +17,11 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <stdio.h> // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen()
|
#include <stdio.h> // Required for: printf(), vprintf(), fprintf()
|
||||||
#include <time.h> // Required for: time_t, tm, time(), localtime(), strftime()
|
#include <time.h> // Required for: time_t, tm, time(), localtime(), strftime()
|
||||||
|
|
||||||
// Custom logging function
|
// Custom logging function
|
||||||
void CustomLog(int msgType, const char *text, va_list args)
|
void CustomTraceLog(int msgType, const char *text, va_list args)
|
||||||
{
|
{
|
||||||
char timeStr[64] = { 0 };
|
char timeStr[64] = { 0 };
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
@ -54,7 +54,7 @@ int main(void)
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
// Set custom logger
|
// Set custom logger
|
||||||
SetTraceLogCallback(CustomLog);
|
SetTraceLogCallback(CustomTraceLog);
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,7 @@
|
||||||
#define RAYGUI_IMPLEMENTATION
|
#define RAYGUI_IMPLEMENTATION
|
||||||
#include "raygui.h" // Required for GUI controls
|
#include "raygui.h" // Required for GUI controls
|
||||||
|
|
||||||
#include <string.h> // Required for: strcpy()
|
#define MAX_FILEPATH_SIZE 1024
|
||||||
|
|
||||||
#define MAX_FILEPATH_SIZE 2048
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
|
|
@ -53,12 +51,10 @@ int main(void)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
if (btnBackPressed)
|
if (btnBackPressed)
|
||||||
{
|
{
|
||||||
strcpy(directory, GetPrevDirectoryPath(directory));
|
TextCopy(directory, GetPrevDirectoryPath(directory));
|
||||||
UnloadDirectoryFiles(files);
|
UnloadDirectoryFiles(files);
|
||||||
files = LoadDirectoryFiles(directory);
|
files = LoadDirectoryFiles(directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
|
@ -68,19 +64,20 @@ int main(void)
|
||||||
|
|
||||||
DrawText(directory, 100, 40, 20, DARKGRAY);
|
DrawText(directory, 100, 40, 20, DARKGRAY);
|
||||||
|
|
||||||
btnBackPressed = GuiButton((Rectangle){ 40.0f, 40.0f, 20, 20 }, "<");
|
btnBackPressed = GuiButton((Rectangle){ 40.0f, 38.0f, 48, 24 }, "<");
|
||||||
|
|
||||||
for (int i = 0; i < (int)files.count; i++)
|
for (int i = 0; i < (int)files.count; i++)
|
||||||
{
|
{
|
||||||
Color color = Fade(LIGHTGRAY, 0.3f);
|
Color color = Fade(LIGHTGRAY, 0.3f);
|
||||||
|
|
||||||
if (!IsPathFile(files.paths[i]))
|
if (!IsPathFile(files.paths[i]) && DirectoryExists(files.paths[i]))
|
||||||
{
|
{
|
||||||
if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, ""))
|
if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, ""))
|
||||||
{
|
{
|
||||||
strcpy(directory, files.paths[i]);
|
TextCopy(directory, files.paths[i]);
|
||||||
UnloadDirectoryFiles(files);
|
UnloadDirectoryFiles(files);
|
||||||
files = LoadDirectoryFiles(directory);
|
files = LoadDirectoryFiles(directory);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
*
|
*
|
||||||
* raylib [core] example - high dpi
|
* raylib [core] example - highdpi demo
|
||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
*
|
*
|
||||||
|
|
@ -33,7 +33,7 @@ int main(void)
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
|
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - high dpi");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi demo");
|
||||||
SetWindowMinSize(450, 450);
|
SetWindowMinSize(450, 450);
|
||||||
|
|
||||||
int logicalGridDescY = 120;
|
int logicalGridDescY = 120;
|
||||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
|
@ -27,9 +27,15 @@ int main(void)
|
||||||
const int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
|
||||||
|
|
||||||
// TODO: Load resources / Initialize variables at this point
|
Vector2 scaleDpi = GetWindowScaleDPI();
|
||||||
|
Vector2 mousePos = GetMousePosition();
|
||||||
|
int currentMonitor = GetCurrentMonitor();
|
||||||
|
Vector2 windowPos = GetWindowPosition();
|
||||||
|
|
||||||
|
int gridSpacing = 40; // Grid spacing in pixels
|
||||||
|
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
@ -39,7 +45,13 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// TODO: Update variables / Implement example logic at this point
|
mousePos = GetMousePosition();
|
||||||
|
currentMonitor = GetCurrentMonitor();
|
||||||
|
scaleDpi = GetWindowScaleDPI();
|
||||||
|
windowPos = GetWindowPosition();
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed();
|
||||||
|
if (IsKeyPressed(KEY_F)) ToggleFullscreen();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
|
@ -48,11 +60,36 @@ int main(void)
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
// TODO: Draw everything that requires to be drawn at this point
|
// Draw grid
|
||||||
|
for (int h = 0; h < GetScreenHeight()/gridSpacing + 1; h++)
|
||||||
|
{
|
||||||
|
DrawText(TextFormat("%02i", h*gridSpacing), 4, h*gridSpacing - 4, 10, GRAY);
|
||||||
|
DrawLine(24, h*gridSpacing, GetScreenWidth(), h*gridSpacing, LIGHTGRAY);
|
||||||
|
}
|
||||||
|
for (int v = 0; v < GetScreenWidth()/gridSpacing + 1; v++)
|
||||||
|
{
|
||||||
|
DrawText(TextFormat("%02i", v*gridSpacing), v*gridSpacing - 10, 4, 10, GRAY);
|
||||||
|
DrawLine(v*gridSpacing, 20, v*gridSpacing, GetScreenHeight(), LIGHTGRAY);
|
||||||
|
}
|
||||||
|
|
||||||
DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
|
// Draw UI info
|
||||||
DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
|
DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
|
||||||
DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
|
GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY);
|
||||||
|
DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY);
|
||||||
|
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);
|
||||||
|
DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 170, 20, DARKGRAY);
|
||||||
|
DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY);
|
||||||
|
|
||||||
|
// Draw reference rectangles, top-left and bottom-right corners
|
||||||
|
DrawRectangle(0, 0, 30, 60, RED);
|
||||||
|
DrawRectangle(GetScreenWidth() - 30, GetScreenHeight() - 60, 30, 60, BLUE);
|
||||||
|
|
||||||
|
// Draw mouse position
|
||||||
|
DrawCircleV(GetMousePosition(), 20, MAROON);
|
||||||
|
DrawRectangle(mousePos.x - 25, mousePos.y, 50, 2, BLACK);
|
||||||
|
DrawRectangle(mousePos.x, mousePos.y - 25, 2, 50, BLACK);
|
||||||
|
DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), mousePos.x - 44,
|
||||||
|
(mousePos.y > GetScreenHeight() - 60)? mousePos.y - 46 : mousePos.y + 30, 20, BLACK);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
|
|
@ -71,6 +71,7 @@ int main(void)
|
||||||
// Set default actions
|
// Set default actions
|
||||||
char actionSet = 0;
|
char actionSet = 0;
|
||||||
SetActionsDefault();
|
SetActionsDefault();
|
||||||
|
bool releaseAction = false;
|
||||||
|
|
||||||
Vector2 position = (Vector2){ 400.0f, 200.0f };
|
Vector2 position = (Vector2){ 400.0f, 200.0f };
|
||||||
Vector2 size = (Vector2){ 40.0f, 40.0f };
|
Vector2 size = (Vector2){ 40.0f, 40.0f };
|
||||||
|
|
@ -83,7 +84,8 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
gamepadIndex = 0; // set this to gamepad being checked
|
gamepadIndex = 0; // Set gamepad being checked
|
||||||
|
|
||||||
if (IsActionDown(ACTION_UP)) position.y -= 2;
|
if (IsActionDown(ACTION_UP)) position.y -= 2;
|
||||||
if (IsActionDown(ACTION_DOWN)) position.y += 2;
|
if (IsActionDown(ACTION_DOWN)) position.y += 2;
|
||||||
if (IsActionDown(ACTION_LEFT)) position.x -= 2;
|
if (IsActionDown(ACTION_LEFT)) position.x -= 2;
|
||||||
|
|
@ -94,6 +96,10 @@ int main(void)
|
||||||
position.y = (screenHeight-size.y)/2;
|
position.y = (screenHeight-size.y)/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register release action for one frame
|
||||||
|
releaseAction = false;
|
||||||
|
if (IsActionReleased(ACTION_FIRE)) releaseAction = true;
|
||||||
|
|
||||||
// Switch control scheme by pressing TAB
|
// Switch control scheme by pressing TAB
|
||||||
if (IsKeyPressed(KEY_TAB))
|
if (IsKeyPressed(KEY_TAB))
|
||||||
{
|
{
|
||||||
|
|
@ -109,7 +115,7 @@ int main(void)
|
||||||
|
|
||||||
ClearBackground(GRAY);
|
ClearBackground(GRAY);
|
||||||
|
|
||||||
DrawRectangleV(position, size, RED);
|
DrawRectangleV(position, size, releaseAction? BLUE : RED);
|
||||||
|
|
||||||
DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE);
|
DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE);
|
||||||
DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN);
|
DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN);
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ int main(void)
|
||||||
const float leftTriggerDeadzone = -0.9f;
|
const float leftTriggerDeadzone = -0.9f;
|
||||||
const float rightTriggerDeadzone = -0.9f;
|
const float rightTriggerDeadzone = -0.9f;
|
||||||
|
|
||||||
|
Rectangle vibrateButton = { 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
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -61,7 +63,12 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// ...
|
if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--;
|
||||||
|
if (IsKeyPressed(KEY_RIGHT)) gamepad++;
|
||||||
|
Vector2 mousePosition = GetMousePosition();
|
||||||
|
|
||||||
|
vibrateButton = (Rectangle){ 10, 70.0f + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 };
|
||||||
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
|
@ -70,9 +77,6 @@ int main(void)
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--;
|
|
||||||
if (IsKeyPressed(KEY_RIGHT)) gamepad++;
|
|
||||||
|
|
||||||
if (IsGamepadAvailable(gamepad))
|
if (IsGamepadAvailable(gamepad))
|
||||||
{
|
{
|
||||||
DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK);
|
DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK);
|
||||||
|
|
@ -93,7 +97,8 @@ int main(void)
|
||||||
if (leftTrigger < leftTriggerDeadzone) leftTrigger = -1.0f;
|
if (leftTrigger < leftTriggerDeadzone) leftTrigger = -1.0f;
|
||||||
if (rightTrigger < rightTriggerDeadzone) rightTrigger = -1.0f;
|
if (rightTrigger < rightTriggerDeadzone) rightTrigger = -1.0f;
|
||||||
|
|
||||||
if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1 || TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1)
|
if ((TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1) ||
|
||||||
|
(TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1))
|
||||||
{
|
{
|
||||||
DrawTexture(texXboxPad, 0, 0, DARKGRAY);
|
DrawTexture(texXboxPad, 0, 0, DARKGRAY);
|
||||||
|
|
||||||
|
|
@ -125,16 +130,14 @@ int main(void)
|
||||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||||
DrawCircle(259, 152, 39, BLACK);
|
DrawCircle(259, 152, 39, BLACK);
|
||||||
DrawCircle(259, 152, 34, LIGHTGRAY);
|
DrawCircle(259, 152, 34, LIGHTGRAY);
|
||||||
DrawCircle(259 + (int)(leftStickX*20),
|
DrawCircle(259 + (int)(leftStickX*20), 152 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||||
152 + (int)(leftStickY*20), 25, leftGamepadColor);
|
|
||||||
|
|
||||||
// Draw axis: right joystick
|
// Draw axis: right joystick
|
||||||
Color rightGamepadColor = BLACK;
|
Color rightGamepadColor = BLACK;
|
||||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||||
DrawCircle(461, 237, 38, BLACK);
|
DrawCircle(461, 237, 38, BLACK);
|
||||||
DrawCircle(461, 237, 33, LIGHTGRAY);
|
DrawCircle(461, 237, 33, LIGHTGRAY);
|
||||||
DrawCircle(461 + (int)(rightStickX*20),
|
DrawCircle(461 + (int)(rightStickX*20), 237 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||||
237 + (int)(rightStickY*20), 25, rightGamepadColor);
|
|
||||||
|
|
||||||
// Draw axis: left-right triggers
|
// Draw axis: left-right triggers
|
||||||
DrawRectangle(170, 30, 15, 70, GRAY);
|
DrawRectangle(170, 30, 15, 70, GRAY);
|
||||||
|
|
@ -177,16 +180,14 @@ int main(void)
|
||||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||||
DrawCircle(319, 255, 35, BLACK);
|
DrawCircle(319, 255, 35, BLACK);
|
||||||
DrawCircle(319, 255, 31, LIGHTGRAY);
|
DrawCircle(319, 255, 31, LIGHTGRAY);
|
||||||
DrawCircle(319 + (int)(leftStickX*20),
|
DrawCircle(319 + (int)(leftStickX*20), 255 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||||
255 + (int)(leftStickY*20), 25, leftGamepadColor);
|
|
||||||
|
|
||||||
// Draw axis: right joystick
|
// Draw axis: right joystick
|
||||||
Color rightGamepadColor = BLACK;
|
Color rightGamepadColor = BLACK;
|
||||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||||
DrawCircle(475, 255, 35, BLACK);
|
DrawCircle(475, 255, 35, BLACK);
|
||||||
DrawCircle(475, 255, 31, LIGHTGRAY);
|
DrawCircle(475, 255, 31, LIGHTGRAY);
|
||||||
DrawCircle(475 + (int)(rightStickX*20),
|
DrawCircle(475 + (int)(rightStickX*20), 255 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||||
255 + (int)(rightStickY*20), 25, rightGamepadColor);
|
|
||||||
|
|
||||||
// Draw axis: left-right triggers
|
// Draw axis: left-right triggers
|
||||||
DrawRectangle(169, 48, 15, 70, GRAY);
|
DrawRectangle(169, 48, 15, 70, GRAY);
|
||||||
|
|
@ -196,7 +197,6 @@ int main(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// Draw background: generic
|
// Draw background: generic
|
||||||
DrawRectangleRounded((Rectangle){ 175, 110, 460, 220}, 0.3f, 16, DARKGRAY);
|
DrawRectangleRounded((Rectangle){ 175, 110, 460, 220}, 0.3f, 16, DARKGRAY);
|
||||||
|
|
||||||
|
|
@ -237,23 +237,20 @@ int main(void)
|
||||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||||
DrawCircle(345, 260, 40, BLACK);
|
DrawCircle(345, 260, 40, BLACK);
|
||||||
DrawCircle(345, 260, 35, LIGHTGRAY);
|
DrawCircle(345, 260, 35, LIGHTGRAY);
|
||||||
DrawCircle(345 + (int)(leftStickX*20),
|
DrawCircle(345 + (int)(leftStickX*20), 260 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||||
260 + (int)(leftStickY*20), 25, leftGamepadColor);
|
|
||||||
|
|
||||||
// Draw axis: right joystick
|
// Draw axis: right joystick
|
||||||
Color rightGamepadColor = BLACK;
|
Color rightGamepadColor = BLACK;
|
||||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||||
DrawCircle(465, 260, 40, BLACK);
|
DrawCircle(465, 260, 40, BLACK);
|
||||||
DrawCircle(465, 260, 35, LIGHTGRAY);
|
DrawCircle(465, 260, 35, LIGHTGRAY);
|
||||||
DrawCircle(465 + (int)(rightStickX*20),
|
DrawCircle(465 + (int)(rightStickX*20), 260 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||||
260 + (int)(rightStickY*20), 25, rightGamepadColor);
|
|
||||||
|
|
||||||
// Draw axis: left-right triggers
|
// Draw axis: left-right triggers
|
||||||
DrawRectangle(151, 110, 15, 70, GRAY);
|
DrawRectangle(151, 110, 15, 70, GRAY);
|
||||||
DrawRectangle(644, 110, 15, 70, GRAY);
|
DrawRectangle(644, 110, 15, 70, GRAY);
|
||||||
DrawRectangle(151, 110, 15, (int)(((1 + leftTrigger)/2)*70), RED);
|
DrawRectangle(151, 110, 15, (int)(((1 + leftTrigger)/2)*70), RED);
|
||||||
DrawRectangle(644, 110, 15, (int)(((1 + rightTrigger)/2)*70), RED);
|
DrawRectangle(644, 110, 15, (int)(((1 + rightTrigger)/2)*70), RED);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(gamepad)), 10, 50, 10, MAROON);
|
DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(gamepad)), 10, 50, 10, MAROON);
|
||||||
|
|
@ -263,13 +260,16 @@ int main(void)
|
||||||
DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(gamepad, i)), 20, 70 + 20*i, 10, DARKGRAY);
|
DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(gamepad, i)), 20, 70 + 20*i, 10, DARKGRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw vibrate button
|
||||||
|
DrawRectangleRec(vibrateButton, SKYBLUE);
|
||||||
|
DrawText("VIBRATE", (int)(vibrateButton.x + 14), (int)(vibrateButton.y + 1), 10, DARKGRAY);
|
||||||
|
|
||||||
if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED);
|
if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED);
|
||||||
else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY);
|
else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DrawText(TextFormat("GP%d: NOT DETECTED", gamepad), 10, 10, 10, GRAY);
|
DrawText(TextFormat("GP%d: NOT DETECTED", gamepad), 10, 10, 10, GRAY);
|
||||||
|
|
||||||
DrawTexture(texXboxPad, 0, 0, LIGHTGRAY);
|
DrawTexture(texXboxPad, 0, 0, LIGHTGRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,4 +118,6 @@ int main(void)
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
#define GESTURE_LOG_SIZE 20
|
#define GESTURE_LOG_SIZE 20
|
||||||
#define MAX_TOUCH_COUNT 32
|
#define MAX_TOUCH_COUNT 32
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module Functions Declaration
|
// Module Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
static char const *GetGestureName(int gesture); // Get text string for gesture value
|
static char const *GetGestureName(int gesture); // Get text string for gesture value
|
||||||
static Color GetGestureColor(int gesture); // Get color for gesture value
|
static Color GetGestureColor(int gesture); // Get color for gesture value
|
||||||
|
|
||||||
|
|
@ -69,7 +69,6 @@ int main(void)
|
||||||
float angleLength = 90.0f;
|
float angleLength = 90.0f;
|
||||||
float currentAngleDegrees = 0.0f;
|
float currentAngleDegrees = 0.0f;
|
||||||
Vector2 finalVector = { 0.0f, 0.0f };
|
Vector2 finalVector = { 0.0f, 0.0f };
|
||||||
char currentAngleStr[7] = "";
|
|
||||||
Vector2 protractorPosition = { 266.0f, 315.0f };
|
Vector2 protractorPosition = { 266.0f, 315.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
|
||||||
|
|
@ -203,7 +202,7 @@ int main(void)
|
||||||
DrawText("Log", (int)gestureLogPosition.x, (int)gestureLogPosition.y, 20, BLACK);
|
DrawText("Log", (int)gestureLogPosition.x, (int)gestureLogPosition.y, 20, BLACK);
|
||||||
|
|
||||||
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
|
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
|
||||||
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], (int)gestureLogPosition.x, (int)gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
|
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1)%GESTURE_LOG_SIZE) DrawText(gestureLog[ii], (int)gestureLogPosition.x, (int)gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
|
||||||
Color logButton1Color, logButton2Color;
|
Color logButton1Color, logButton2Color;
|
||||||
switch (logMode)
|
switch (logMode)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -40,14 +40,8 @@ int main(void)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
if (IsKeyPressed(KEY_H))
|
if (IsKeyPressed(KEY_H))
|
||||||
{
|
{
|
||||||
if (IsCursorHidden())
|
if (IsCursorHidden()) ShowCursor();
|
||||||
{
|
else HideCursor();
|
||||||
ShowCursor();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HideCursor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ballPosition = GetMousePosition();
|
ballPosition = GetMousePosition();
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ int main(void)
|
||||||
// Clamp touch points available ( set the maximum touch points allowed )
|
// Clamp touch points available ( set the maximum touch points allowed )
|
||||||
if (tCount > MAX_TOUCH_POINTS) tCount = MAX_TOUCH_POINTS;
|
if (tCount > MAX_TOUCH_POINTS) tCount = MAX_TOUCH_POINTS;
|
||||||
// Get touch points positions
|
// Get touch points positions
|
||||||
for (int i = 0; i < tCount; ++i) touchPositions[i] = GetTouchPosition(i);
|
for (int i = 0; i < tCount; i++) touchPositions[i] = GetTouchPosition(i);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
|
@ -55,7 +55,7 @@ int main(void)
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
for (int i = 0; i < tCount; ++i)
|
for (int i = 0; i < tCount; i++)
|
||||||
{
|
{
|
||||||
// Make sure point is not (0, 0) as this means there is no touch for it
|
// Make sure point is not (0, 0) as this means there is no touch for it
|
||||||
if ((touchPositions[i].x > 0) && (touchPositions[i].y > 0))
|
if ((touchPositions[i].x > 0) && (touchPositions[i].y > 0))
|
||||||
|
|
|
||||||
333
examples/core/core_keyboard_testbed.c
Normal file
|
|
@ -0,0 +1,333 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - keyboard testbed
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* NOTE: raylib defined keys refer to ENG-US Keyboard layout,
|
||||||
|
* mapping to other layouts is up to the user
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* 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 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#define KEY_REC_SPACING 4 // Space in pixels between key rectangles
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static const char *GetKeyText(int key);
|
||||||
|
static void GuiKeyboardKey(Rectangle bounds, int key);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard testbed");
|
||||||
|
SetExitKey(KEY_NULL); // Avoid exit on KEY_ESCAPE
|
||||||
|
|
||||||
|
// Keyboard line 01
|
||||||
|
int line01KeyWidths[15] = { 0 };
|
||||||
|
for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45;
|
||||||
|
line01KeyWidths[13] = 62; // PRINTSCREEN
|
||||||
|
int line01Keys[15] = {
|
||||||
|
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
|
||||||
|
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
|
||||||
|
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keyboard line 02
|
||||||
|
int line02KeyWidths[15] = { 0 };
|
||||||
|
for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45;
|
||||||
|
line02KeyWidths[0] = 25; // GRAVE
|
||||||
|
line02KeyWidths[13] = 82; // BACKSPACE
|
||||||
|
int line02Keys[15] = {
|
||||||
|
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
|
||||||
|
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
|
||||||
|
KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE };
|
||||||
|
|
||||||
|
// Keyboard line 03
|
||||||
|
int line03KeyWidths[15] = { 0 };
|
||||||
|
for (int i = 0; i < 15; i++) line03KeyWidths[i] = 45;
|
||||||
|
line03KeyWidths[0] = 50; // TAB
|
||||||
|
line03KeyWidths[13] = 57; // BACKSLASH
|
||||||
|
int line03Keys[15] = {
|
||||||
|
KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y,
|
||||||
|
KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFT_BRACKET,
|
||||||
|
KEY_RIGHT_BRACKET, KEY_BACKSLASH, KEY_INSERT
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keyboard line 04
|
||||||
|
int line04KeyWidths[14] = { 0 };
|
||||||
|
for (int i = 0; i < 14; i++) line04KeyWidths[i] = 45;
|
||||||
|
line04KeyWidths[0] = 68; // CAPS
|
||||||
|
line04KeyWidths[12] = 88; // ENTER
|
||||||
|
int line04Keys[14] = {
|
||||||
|
KEY_CAPS_LOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G,
|
||||||
|
KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
|
||||||
|
KEY_APOSTROPHE, KEY_ENTER, KEY_PAGE_UP
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keyboard line 05
|
||||||
|
int line05KeyWidths[14] = { 0 };
|
||||||
|
for (int i = 0; i < 14; i++) line05KeyWidths[i] = 45;
|
||||||
|
line05KeyWidths[0] = 80; // LSHIFT
|
||||||
|
line05KeyWidths[11] = 76; // RSHIFT
|
||||||
|
int line05Keys[14] = {
|
||||||
|
KEY_LEFT_SHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B,
|
||||||
|
KEY_N, KEY_M, KEY_COMMA, KEY_PERIOD, /*KEY_MINUS*/
|
||||||
|
KEY_SLASH, KEY_RIGHT_SHIFT, KEY_UP, KEY_PAGE_DOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keyboard line 06
|
||||||
|
int line06KeyWidths[11] = { 0 };
|
||||||
|
for (int i = 0; i < 11; i++) line06KeyWidths[i] = 45;
|
||||||
|
line06KeyWidths[0] = 80; // LCTRL
|
||||||
|
line06KeyWidths[3] = 208; // SPACE
|
||||||
|
line06KeyWidths[7] = 60; // RCTRL
|
||||||
|
int line06Keys[11] = {
|
||||||
|
KEY_LEFT_CONTROL, KEY_LEFT_SUPER, KEY_LEFT_ALT,
|
||||||
|
KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL,
|
||||||
|
KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector2 keyboardOffset = { 26, 80 };
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
int key = GetKeyPressed(); // Get pressed keycode
|
||||||
|
if (key > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: KEY PRESSED: %d", key);
|
||||||
|
|
||||||
|
int ch = GetCharPressed(); // Get pressed char for text input, using OS mapping
|
||||||
|
if (ch > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: CHAR PRESSED: %c (%d)", ch, ch);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
// Keyboard line 01 - 15 keys
|
||||||
|
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
|
||||||
|
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||||
|
{
|
||||||
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, line01KeyWidths[i], 30 }, line01Keys[i]);
|
||||||
|
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard line 02 - 15 keys
|
||||||
|
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
|
||||||
|
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]);
|
||||||
|
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard line 03 - 15 keys
|
||||||
|
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
|
||||||
|
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]);
|
||||||
|
recOffsetX += line03KeyWidths[i] + KEY_REC_SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard line 04 - 14 keys
|
||||||
|
// MAYUS, A, S, D, F, G, H, J, K, L, ;, ', ENTER, REPAG
|
||||||
|
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]);
|
||||||
|
recOffsetX += line04KeyWidths[i] + KEY_REC_SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard line 05 - 14 keys
|
||||||
|
// LSHIFT, Z, X, C, V, B, N, M, ,, ., /, RSHIFT, UP, AVPAG
|
||||||
|
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]);
|
||||||
|
recOffsetX += line05KeyWidths[i] + KEY_REC_SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard line 06 - 11 keys
|
||||||
|
// LCTRL, WIN, LALT, SPACE, ALTGR, \, FN, RCTRL, LEFT, DOWN, RIGHT
|
||||||
|
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]);
|
||||||
|
recOffsetX += line06KeyWidths[i] + KEY_REC_SPACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Get keyboard keycode as text (US keyboard)
|
||||||
|
// NOTE: Mapping for other keyboard layouts can be done here
|
||||||
|
static const char *GetKeyText(int key)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case KEY_APOSTROPHE : return "'"; // Key: '
|
||||||
|
case KEY_COMMA : return ","; // Key: ,
|
||||||
|
case KEY_MINUS : return "-"; // Key: -
|
||||||
|
case KEY_PERIOD : return "."; // Key: .
|
||||||
|
case KEY_SLASH : return "/"; // Key: /
|
||||||
|
case KEY_ZERO : return "0"; // Key: 0
|
||||||
|
case KEY_ONE : return "1"; // Key: 1
|
||||||
|
case KEY_TWO : return "2"; // Key: 2
|
||||||
|
case KEY_THREE : return "3"; // Key: 3
|
||||||
|
case KEY_FOUR : return "4"; // Key: 4
|
||||||
|
case KEY_FIVE : return "5"; // Key: 5
|
||||||
|
case KEY_SIX : return "6"; // Key: 6
|
||||||
|
case KEY_SEVEN : return "7"; // Key: 7
|
||||||
|
case KEY_EIGHT : return "8"; // Key: 8
|
||||||
|
case KEY_NINE : return "9"; // Key: 9
|
||||||
|
case KEY_SEMICOLON : return ";"; // Key: ;
|
||||||
|
case KEY_EQUAL : return "="; // Key: =
|
||||||
|
case KEY_A : return "A"; // Key: A | a
|
||||||
|
case KEY_B : return "B"; // Key: B | b
|
||||||
|
case KEY_C : return "C"; // Key: C | c
|
||||||
|
case KEY_D : return "D"; // Key: D | d
|
||||||
|
case KEY_E : return "E"; // Key: E | e
|
||||||
|
case KEY_F : return "F"; // Key: F | f
|
||||||
|
case KEY_G : return "G"; // Key: G | g
|
||||||
|
case KEY_H : return "H"; // Key: H | h
|
||||||
|
case KEY_I : return "I"; // Key: I | i
|
||||||
|
case KEY_J : return "J"; // Key: J | j
|
||||||
|
case KEY_K : return "K"; // Key: K | k
|
||||||
|
case KEY_L : return "L"; // Key: L | l
|
||||||
|
case KEY_M : return "M"; // Key: M | m
|
||||||
|
case KEY_N : return "N"; // Key: N | n
|
||||||
|
case KEY_O : return "O"; // Key: O | o
|
||||||
|
case KEY_P : return "P"; // Key: P | p
|
||||||
|
case KEY_Q : return "Q"; // Key: Q | q
|
||||||
|
case KEY_R : return "R"; // Key: R | r
|
||||||
|
case KEY_S : return "S"; // Key: S | s
|
||||||
|
case KEY_T : return "T"; // Key: T | t
|
||||||
|
case KEY_U : return "U"; // Key: U | u
|
||||||
|
case KEY_V : return "V"; // Key: V | v
|
||||||
|
case KEY_W : return "W"; // Key: W | w
|
||||||
|
case KEY_X : return "X"; // Key: X | x
|
||||||
|
case KEY_Y : return "Y"; // Key: Y | y
|
||||||
|
case KEY_Z : return "Z"; // Key: Z | z
|
||||||
|
case KEY_LEFT_BRACKET : return "["; // Key: [
|
||||||
|
case KEY_BACKSLASH : return "\\"; // Key: '\'
|
||||||
|
case KEY_RIGHT_BRACKET : return "]"; // Key: ]
|
||||||
|
case KEY_GRAVE : return "`"; // Key: `
|
||||||
|
case KEY_SPACE : return "SPACE"; // Key: Space
|
||||||
|
case KEY_ESCAPE : return "ESC"; // Key: Esc
|
||||||
|
case KEY_ENTER : return "ENTER"; // Key: Enter
|
||||||
|
case KEY_TAB : return "TAB"; // Key: Tab
|
||||||
|
case KEY_BACKSPACE : return "BACK"; // Key: Backspace
|
||||||
|
case KEY_INSERT : return "INS"; // Key: Ins
|
||||||
|
case KEY_DELETE : return "DEL"; // Key: Del
|
||||||
|
case KEY_RIGHT : return "RIGHT"; // Key: Cursor right
|
||||||
|
case KEY_LEFT : return "LEFT"; // Key: Cursor left
|
||||||
|
case KEY_DOWN : return "DOWN"; // Key: Cursor down
|
||||||
|
case KEY_UP : return "UP"; // Key: Cursor up
|
||||||
|
case KEY_PAGE_UP : return "PGUP"; // Key: Page up
|
||||||
|
case KEY_PAGE_DOWN : return "PGDOWN"; // Key: Page down
|
||||||
|
case KEY_HOME : return "HOME"; // Key: Home
|
||||||
|
case KEY_END : return "END"; // Key: End
|
||||||
|
case KEY_CAPS_LOCK : return "CAPS"; // Key: Caps lock
|
||||||
|
case KEY_SCROLL_LOCK : return "LOCK"; // Key: Scroll down
|
||||||
|
case KEY_NUM_LOCK : return "NUMLOCK"; // Key: Num lock
|
||||||
|
case KEY_PRINT_SCREEN : return "PRINTSCR"; // Key: Print screen
|
||||||
|
case KEY_PAUSE : return "PAUSE"; // Key: Pause
|
||||||
|
case KEY_F1 : return "F1"; // Key: F1
|
||||||
|
case KEY_F2 : return "F2"; // Key: F2
|
||||||
|
case KEY_F3 : return "F3"; // Key: F3
|
||||||
|
case KEY_F4 : return "F4"; // Key: F4
|
||||||
|
case KEY_F5 : return "F5"; // Key: F5
|
||||||
|
case KEY_F6 : return "F6"; // Key: F6
|
||||||
|
case KEY_F7 : return "F7"; // Key: F7
|
||||||
|
case KEY_F8 : return "F8"; // Key: F8
|
||||||
|
case KEY_F9 : return "F9"; // Key: F9
|
||||||
|
case KEY_F10 : return "F10"; // Key: F10
|
||||||
|
case KEY_F11 : return "F11"; // Key: F11
|
||||||
|
case KEY_F12 : return "F12"; // Key: F12
|
||||||
|
case KEY_LEFT_SHIFT : return "LSHIFT"; // Key: Shift left
|
||||||
|
case KEY_LEFT_CONTROL : return "LCTRL"; // Key: Control left
|
||||||
|
case KEY_LEFT_ALT : return "LALT"; // Key: Alt left
|
||||||
|
case KEY_LEFT_SUPER : return "WIN"; // Key: Super left
|
||||||
|
case KEY_RIGHT_SHIFT : return "RSHIFT"; // Key: Shift right
|
||||||
|
case KEY_RIGHT_CONTROL : return "RCTRL"; // Key: Control right
|
||||||
|
case KEY_RIGHT_ALT : return "ALTGR"; // Key: Alt right
|
||||||
|
case KEY_RIGHT_SUPER : return "RSUPER"; // Key: Super right
|
||||||
|
case KEY_KB_MENU : return "KBMENU"; // Key: KB menu
|
||||||
|
case KEY_KP_0 : return "KP0"; // Key: Keypad 0
|
||||||
|
case KEY_KP_1 : return "KP1"; // Key: Keypad 1
|
||||||
|
case KEY_KP_2 : return "KP2"; // Key: Keypad 2
|
||||||
|
case KEY_KP_3 : return "KP3"; // Key: Keypad 3
|
||||||
|
case KEY_KP_4 : return "KP4"; // Key: Keypad 4
|
||||||
|
case KEY_KP_5 : return "KP5"; // Key: Keypad 5
|
||||||
|
case KEY_KP_6 : return "KP6"; // Key: Keypad 6
|
||||||
|
case KEY_KP_7 : return "KP7"; // Key: Keypad 7
|
||||||
|
case KEY_KP_8 : return "KP8"; // Key: Keypad 8
|
||||||
|
case KEY_KP_9 : return "KP9"; // Key: Keypad 9
|
||||||
|
case KEY_KP_DECIMAL : return "KPDEC"; // Key: Keypad .
|
||||||
|
case KEY_KP_DIVIDE : return "KPDIV"; // Key: Keypad /
|
||||||
|
case KEY_KP_MULTIPLY : return "KPMUL"; // Key: Keypad *
|
||||||
|
case KEY_KP_SUBTRACT : return "KPSUB"; // Key: Keypad -
|
||||||
|
case KEY_KP_ADD : return "KPADD"; // Key: Keypad +
|
||||||
|
case KEY_KP_ENTER : return "KPENTER"; // Key: Keypad Enter
|
||||||
|
case KEY_KP_EQUAL : return "KPEQU"; // Key: Keypad =
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw keyboard key
|
||||||
|
static void GuiKeyboardKey(Rectangle bounds, int key)
|
||||||
|
{
|
||||||
|
if (key == KEY_NULL) DrawRectangleLinesEx(bounds, 2.0f, LIGHTGRAY);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IsKeyDown(key))
|
||||||
|
{
|
||||||
|
DrawRectangleLinesEx(bounds, 2.0f, MAROON);
|
||||||
|
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, MAROON);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawRectangleLinesEx(bounds, 2.0f, DARKGRAY);
|
||||||
|
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, DARKGRAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckCollisionPointRec(GetMousePosition(), bounds))
|
||||||
|
{
|
||||||
|
DrawRectangleRec(bounds, Fade(RED, 0.2f));
|
||||||
|
DrawRectangleLinesEx(bounds, 3.0f, RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
examples/core/core_keyboard_testbed.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
|
@ -40,10 +40,9 @@ int main(void)
|
||||||
const int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
MonitorInfo monitors[MAX_MONITORS] = { 0 };
|
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - monitor detector");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - monitor detector");
|
||||||
|
|
||||||
|
MonitorInfo monitors[MAX_MONITORS] = { 0 };
|
||||||
int currentMonitorIndex = GetCurrentMonitor();
|
int currentMonitorIndex = GetCurrentMonitor();
|
||||||
int monitorCount = 0;
|
int monitorCount = 0;
|
||||||
|
|
||||||
|
|
@ -55,7 +54,6 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Variables to find the max x and Y to calculate the scale
|
// Variables to find the max x and Y to calculate the scale
|
||||||
int maxWidth = 1;
|
int maxWidth = 1;
|
||||||
int maxHeight = 1;
|
int maxHeight = 1;
|
||||||
|
|
@ -76,7 +74,8 @@ int main(void)
|
||||||
GetMonitorPhysicalHeight(i),
|
GetMonitorPhysicalHeight(i),
|
||||||
GetMonitorRefreshRate(i)
|
GetMonitorRefreshRate(i)
|
||||||
};
|
};
|
||||||
if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = (int)monitors[i].position.x*-1;
|
|
||||||
|
if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = -(int)monitors[i].position.x;
|
||||||
|
|
||||||
const int width = (int)monitors[i].position.x + monitors[i].width;
|
const int width = (int)monitors[i].position.x + monitors[i].width;
|
||||||
const int height = (int)monitors[i].position.y + monitors[i].height;
|
const int height = (int)monitors[i].position.y + monitors[i].height;
|
||||||
|
|
@ -85,25 +84,22 @@ int main(void)
|
||||||
if (maxHeight < height) maxHeight = height;
|
if (maxHeight < height) maxHeight = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_ENTER) && monitorCount > 1)
|
if (IsKeyPressed(KEY_ENTER) && (monitorCount > 1))
|
||||||
{
|
{
|
||||||
currentMonitorIndex += 1;
|
currentMonitorIndex += 1;
|
||||||
|
|
||||||
// Set index to 0 if the last one
|
// Set index to 0 if the last one
|
||||||
if(currentMonitorIndex == monitorCount) currentMonitorIndex = 0;
|
if (currentMonitorIndex == monitorCount) currentMonitorIndex = 0;
|
||||||
|
|
||||||
SetWindowMonitor(currentMonitorIndex); // Move window to currentMonitorIndex
|
SetWindowMonitor(currentMonitorIndex); // Move window to currentMonitorIndex
|
||||||
}
|
}
|
||||||
else
|
else currentMonitorIndex = GetCurrentMonitor(); // Get currentMonitorIndex if manually moved
|
||||||
{
|
|
||||||
// Get currentMonitorIndex if manually moved
|
|
||||||
currentMonitorIndex = GetCurrentMonitor();
|
|
||||||
}
|
|
||||||
|
|
||||||
float monitorScale = 0.6f;
|
float monitorScale = 0.6f;
|
||||||
|
|
||||||
if(maxHeight > maxWidth + monitorOffsetX) monitorScale *= ((float)screenHeight/(float)maxHeight);
|
if (maxHeight > (maxWidth + monitorOffsetX)) monitorScale *= ((float)screenHeight/(float)maxHeight);
|
||||||
else monitorScale *= ((float)screenWidth/(float)(maxWidth + monitorOffsetX));
|
else monitorScale *= ((float)screenWidth/(float)(maxWidth + monitorOffsetX));
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -120,10 +116,10 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Calculate retangle position and size using monitorScale
|
// Calculate retangle position and size using monitorScale
|
||||||
const Rectangle rec = (Rectangle){
|
const Rectangle rec = (Rectangle){
|
||||||
(monitors[i].position.x + monitorOffsetX) * monitorScale + 140,
|
(monitors[i].position.x + monitorOffsetX)*monitorScale + 140,
|
||||||
monitors[i].position.y * monitorScale + 80,
|
monitors[i].position.y*monitorScale + 80,
|
||||||
monitors[i].width * monitorScale,
|
monitors[i].width*monitorScale,
|
||||||
monitors[i].height * monitorScale
|
monitors[i].height*monitorScale
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw monitor name and information inside the rectangle
|
// Draw monitor name and information inside the rectangle
|
||||||
|
|
@ -146,16 +142,11 @@ int main(void)
|
||||||
Vector2 windowPosition = (Vector2){ (GetWindowPosition().x + monitorOffsetX)*monitorScale + 140, GetWindowPosition().y*monitorScale + 80 };
|
Vector2 windowPosition = (Vector2){ (GetWindowPosition().x + monitorOffsetX)*monitorScale + 140, GetWindowPosition().y*monitorScale + 80 };
|
||||||
|
|
||||||
// Draw window position based on monitors
|
// Draw window position based on monitors
|
||||||
DrawRectangleV(windowPosition, (Vector2){screenWidth * monitorScale, screenHeight * monitorScale}, Fade(GREEN, 0.5));
|
DrawRectangleV(windowPosition, (Vector2){screenWidth*monitorScale, screenHeight*monitorScale}, Fade(GREEN, 0.5));
|
||||||
}
|
}
|
||||||
else
|
else DrawRectangleLinesEx(rec, 5, GRAY);
|
||||||
{
|
|
||||||
DrawRectangleLinesEx(rec, 5, GRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,10 @@
|
||||||
*
|
*
|
||||||
* raylib [core] example - screen recording
|
* raylib [core] example - screen recording
|
||||||
*
|
*
|
||||||
* Example complexity rating: [★☆☆☆] 1/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 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
*
|
*
|
||||||
* Example contributed by Ramon Santamaria (@raysan5) and reviewed by Ramon Santamaria (@raysan5)
|
|
||||||
*
|
|
||||||
* 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
|
||||||
*
|
*
|
||||||
|
|
@ -17,6 +15,16 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
|
// Using msf_gif library to record frames into GIF
|
||||||
|
#define MSF_GIF_IMPL
|
||||||
|
#include "msf_gif.h" // GIF recording functionality
|
||||||
|
|
||||||
|
#include <math.h> // Required for: sinf()
|
||||||
|
|
||||||
|
#define GIF_RECORD_FRAMERATE 5 // Record framerate, we get a frame every N frames
|
||||||
|
|
||||||
|
#define MAX_SINEWAVE_POINTS 256
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
@ -29,7 +37,20 @@ int main(void)
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - screen recording");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - screen recording");
|
||||||
|
|
||||||
// TODO: Load resources / Initialize variables at this point
|
bool gifRecording = false; // GIF recording state
|
||||||
|
unsigned int gifFrameCounter = 0; // GIF frames counter
|
||||||
|
MsfGifState gifState = { 0 }; // MSGIF context state
|
||||||
|
|
||||||
|
Vector2 circlePosition = { 0.0f, screenHeight/2.0f };
|
||||||
|
float timeCounter = 0.0f;
|
||||||
|
|
||||||
|
// Get sine wave points for line drawing
|
||||||
|
Vector2 sinePoints[MAX_SINEWAVE_POINTS] = { 0 };
|
||||||
|
for (int i = 0; i < MAX_SINEWAVE_POINTS; i++)
|
||||||
|
{
|
||||||
|
sinePoints[i].x = i*GetScreenWidth()/180.0f;
|
||||||
|
sinePoints[i].y = screenHeight/2.0f + 150*sinf((2*PI/1.5f)*(1.0f/60.0f)*(float)i); // Calculate for 60 fps
|
||||||
|
}
|
||||||
|
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
@ -39,7 +60,59 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// TODO: Update variables / Implement example logic at this point
|
// Update circle sinusoidal movement
|
||||||
|
timeCounter += GetFrameTime();
|
||||||
|
circlePosition.x += GetScreenWidth()/180.0f;
|
||||||
|
circlePosition.y = screenHeight/2.0f + 150*sinf((2*PI/1.5f)*timeCounter);
|
||||||
|
if (circlePosition.x > screenWidth)
|
||||||
|
{
|
||||||
|
circlePosition.x = 0.0f;
|
||||||
|
circlePosition.y = screenHeight/2.0f;
|
||||||
|
timeCounter = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start-Stop GIF recording on CTRL+R
|
||||||
|
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_R))
|
||||||
|
{
|
||||||
|
if (gifRecording)
|
||||||
|
{
|
||||||
|
// Stop current recording and save file
|
||||||
|
gifRecording = false;
|
||||||
|
MsfGifResult result = msf_gif_end(&gifState);
|
||||||
|
SaveFileData(TextFormat("%s/screenrecording.gif", GetApplicationDirectory()), result.data, (unsigned int)result.dataSize);
|
||||||
|
msf_gif_free(result);
|
||||||
|
|
||||||
|
TraceLog(LOG_INFO, "Finish animated GIF recording");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Start a new recording
|
||||||
|
gifRecording = true;
|
||||||
|
gifFrameCounter = 0;
|
||||||
|
msf_gif_begin(&gifState, GetRenderWidth(), GetRenderHeight());
|
||||||
|
|
||||||
|
TraceLog(LOG_INFO, "Start animated GIF recording");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gifRecording)
|
||||||
|
{
|
||||||
|
gifFrameCounter++;
|
||||||
|
|
||||||
|
// NOTE: We record one gif frame depending on the desired gif framerate
|
||||||
|
if (gifFrameCounter > GIF_RECORD_FRAMERATE)
|
||||||
|
{
|
||||||
|
// Get image data for the current frame (from backbuffer)
|
||||||
|
// WARNING: This process is quite slow, it can generate stuttering
|
||||||
|
Image imScreen = LoadImageFromScreen();
|
||||||
|
|
||||||
|
// Add the frame to the gif recording, providing and "estimated" time for display in centiseconds
|
||||||
|
msf_gif_frame(&gifState, imScreen.data, (int)((1.0f/60.0f)*GIF_RECORD_FRAMERATE)/10, 16, imScreen.width*4);
|
||||||
|
gifFrameCounter = 0;
|
||||||
|
|
||||||
|
UnloadImage(imScreen); // Free image data
|
||||||
|
}
|
||||||
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
|
@ -48,20 +121,43 @@ int main(void)
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
// TODO: Draw everything that requires to be drawn at this point
|
for (int i = 0; i < (MAX_SINEWAVE_POINTS - 1); i++)
|
||||||
|
{
|
||||||
|
DrawLineV(sinePoints[i], sinePoints[i + 1], MAROON);
|
||||||
|
DrawCircleV(sinePoints[i], 3, MAROON);
|
||||||
|
}
|
||||||
|
|
||||||
DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
|
DrawCircleV(circlePosition, 30, RED);
|
||||||
DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
|
|
||||||
DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
|
|
||||||
|
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Draw record indicator
|
||||||
|
// WARNING: If drawn here, it will appear in the recorded image,
|
||||||
|
// use a render texture instead for the recording and LoadImageFromTexture(rt.texture)
|
||||||
|
if (gifRecording)
|
||||||
|
{
|
||||||
|
// Display the recording indicator every half-second
|
||||||
|
if ((int)(GetTime()/0.5)%2 == 1)
|
||||||
|
{
|
||||||
|
DrawCircle(30, GetScreenHeight() - 20, 10, MAROON);
|
||||||
|
DrawText("GIF RECORDING", 50, GetScreenHeight() - 25, 10, RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
// If still recording a GIF on close window, just finish
|
||||||
// TODO: Unload all loaded resources at this point
|
if (gifRecording)
|
||||||
|
{
|
||||||
|
MsfGifResult result = msf_gif_end(&gifState);
|
||||||
|
msf_gif_free(result);
|
||||||
|
gifRecording = false;
|
||||||
|
}
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "raymath.h" // Required for: Lerp()
|
#include "raymath.h" // Required for: Lerp()
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
@ -59,10 +61,11 @@ int main(void)
|
||||||
int lastSpace = 0; // Keeping track of last valid space to insert '\n'
|
int lastSpace = 0; // Keeping track of last valid space to insert '\n'
|
||||||
int lastWrapStart = 0; // Keeping track of the start of this wrapped line.
|
int lastWrapStart = 0; // Keeping track of the start of this wrapped line.
|
||||||
|
|
||||||
while (lines[i][j] != '\0')
|
while (j <= strlen(lines[i]))
|
||||||
{
|
{
|
||||||
if (lines[i][j] == ' ')
|
if (lines[i][j] == ' ' || lines[i][j] == '\0')
|
||||||
{
|
{
|
||||||
|
char before = lines[i][j];
|
||||||
// Making a C Style string by adding a '\0' at the required location so that we can use the MeasureText function
|
// Making a C Style string by adding a '\0' at the required location so that we can use the MeasureText function
|
||||||
lines[i][j] = '\0';
|
lines[i][j] = '\0';
|
||||||
|
|
||||||
|
|
@ -75,7 +78,7 @@ int main(void)
|
||||||
lastWrapStart = lastSpace + 1;
|
lastWrapStart = lastSpace + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lines[i][j] = ' '; // Resetting the space back
|
if(before != '\0') lines[i][j] = ' '; // Resetting the space back
|
||||||
lastSpace = j; // Since we encountered a new space we update our last encountered space location
|
lastSpace = j; // Since we encountered a new space we update our last encountered space location
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,7 +95,7 @@ int main(void)
|
||||||
textHeight += (int)size.y + 10;
|
textHeight += (int)size.y + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A simple scrollbar on the side to show how far we have red into the file
|
// A simple scrollbar on the side to show how far we have read into the file
|
||||||
Rectangle scrollBar = {
|
Rectangle scrollBar = {
|
||||||
.x = (float)screenWidth - 5,
|
.x = (float)screenWidth - 5,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
|
|
@ -132,7 +135,13 @@ int main(void)
|
||||||
for (int i = 0, t = textTop; i < lineCount; i++)
|
for (int i = 0, t = textTop; i < lineCount; i++)
|
||||||
{
|
{
|
||||||
// Each time we go through and calculate the height of the text to move the cursor appropriately
|
// Each time we go through and calculate the height of the text to move the cursor appropriately
|
||||||
Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], (float)fontSize, 2);
|
Vector2 size;
|
||||||
|
if(strcmp(lines[i], "")){
|
||||||
|
// Fix for empty line in the text file
|
||||||
|
size = MeasureTextEx( GetFontDefault(), lines[i], (float)fontSize, 2);
|
||||||
|
}else{
|
||||||
|
size = MeasureTextEx( GetFontDefault(), " ", (float)fontSize, 2);
|
||||||
|
}
|
||||||
|
|
||||||
DrawText(lines[i], 10, t, fontSize, RED);
|
DrawText(lines[i], 10, t, fontSize, RED);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ int main(void)
|
||||||
if (lastUndoIndex > firstUndoIndex)
|
if (lastUndoIndex > firstUndoIndex)
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
||||||
DrawRectangleRec((Rectangle){gridPosition.x + states[i].cell.x * GRID_CELL_SIZE, gridPosition.y + states[i].cell.y * GRID_CELL_SIZE,
|
DrawRectangleRec((Rectangle){gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
|
||||||
GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY);
|
GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY);
|
||||||
}
|
}
|
||||||
else if (firstUndoIndex > lastUndoIndex)
|
else if (firstUndoIndex > lastUndoIndex)
|
||||||
|
|
@ -195,7 +195,7 @@ int main(void)
|
||||||
if ((currentUndoIndex < MAX_UNDO_STATES) && (currentUndoIndex > lastUndoIndex))
|
if ((currentUndoIndex < MAX_UNDO_STATES) && (currentUndoIndex > lastUndoIndex))
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
||||||
DrawRectangleRec((Rectangle) { gridPosition.x + states[i].cell.x * GRID_CELL_SIZE, gridPosition.y + states[i].cell.y * GRID_CELL_SIZE,
|
DrawRectangleRec((Rectangle) { gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
|
||||||
GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY);
|
GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
321
examples/core/core_viewport_scaling.c
Normal file
|
|
@ -0,0 +1,321 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - viewport scaling
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||||
|
*
|
||||||
|
* Example contributed by Agnis Aldiņš (@nezvers) 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) 2025 Agnis Aldiņš (@nezvers)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#define RESOLUTION_COUNT 4 // For iteration purposes and teaching example
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// Only upscale, useful for pixel art
|
||||||
|
KEEP_ASPECT_INTEGER,
|
||||||
|
KEEP_HEIGHT_INTEGER,
|
||||||
|
KEEP_WIDTH_INTEGER,
|
||||||
|
// Can also downscale
|
||||||
|
KEEP_ASPECT,
|
||||||
|
KEEP_HEIGHT,
|
||||||
|
KEEP_WIDTH,
|
||||||
|
// For itteration purposes and as a teaching example
|
||||||
|
VIEWPORT_TYPE_COUNT,
|
||||||
|
} ViewportType;
|
||||||
|
|
||||||
|
// For displaying on GUI
|
||||||
|
const char *ViewportTypeNames[VIEWPORT_TYPE_COUNT] = {
|
||||||
|
"KEEP_ASPECT_INTEGER",
|
||||||
|
"KEEP_HEIGHT_INTEGER",
|
||||||
|
"KEEP_WIDTH_INTEGER",
|
||||||
|
"KEEP_ASPECT",
|
||||||
|
"KEEP_HEIGHT",
|
||||||
|
"KEEP_WIDTH",
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||||
|
static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||||
|
static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||||
|
static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||||
|
static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||||
|
static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||||
|
static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target);
|
||||||
|
|
||||||
|
// Example how to calculate position on RenderTexture
|
||||||
|
static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//---------------------------------------------------------
|
||||||
|
int screenWidth = 800;
|
||||||
|
int screenHeight = 450;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - viewport scaling");
|
||||||
|
|
||||||
|
// Preset resolutions that could be created by subdividing screen resolution
|
||||||
|
Vector2 resolutionList[RESOLUTION_COUNT] = {
|
||||||
|
(Vector2){ 64, 64 },
|
||||||
|
(Vector2){ 256, 240 },
|
||||||
|
(Vector2){ 320, 180 },
|
||||||
|
// 4K doesn't work with integer scaling but included for example purposes with non-integer scaling
|
||||||
|
(Vector2){ 3840, 2160 },
|
||||||
|
};
|
||||||
|
|
||||||
|
int resolutionIndex = 0;
|
||||||
|
int gameWidth = 64;
|
||||||
|
int gameHeight = 64;
|
||||||
|
|
||||||
|
RenderTexture2D target = (RenderTexture2D){ 0 };
|
||||||
|
Rectangle sourceRect = (Rectangle){ 0 };
|
||||||
|
Rectangle destRect = (Rectangle){ 0 };
|
||||||
|
|
||||||
|
ViewportType viewportType = KEEP_ASPECT_INTEGER;
|
||||||
|
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||||
|
|
||||||
|
// Button rectangles
|
||||||
|
Rectangle decreaseResolutionButton = (Rectangle){ 200, 30, 10, 10 };
|
||||||
|
Rectangle increaseResolutionButton = (Rectangle){ 215, 30, 10, 10 };
|
||||||
|
Rectangle decreaseTypeButton = (Rectangle){ 200, 45, 10, 10 };
|
||||||
|
Rectangle increaseTypeButton = (Rectangle){ 215, 45, 10, 10 };
|
||||||
|
|
||||||
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
|
//----------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (IsWindowResized()) ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||||
|
|
||||||
|
Vector2 mousePosition = GetMousePosition();
|
||||||
|
bool mousePressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
|
||||||
|
|
||||||
|
// Check buttons and rescale
|
||||||
|
if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed)
|
||||||
|
{
|
||||||
|
resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT;
|
||||||
|
gameWidth = (int)resolutionList[resolutionIndex].x;
|
||||||
|
gameHeight = (int)resolutionList[resolutionIndex].y;
|
||||||
|
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed)
|
||||||
|
{
|
||||||
|
resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT;
|
||||||
|
gameWidth = (int)resolutionList[resolutionIndex].x;
|
||||||
|
gameHeight = (int)resolutionList[resolutionIndex].y;
|
||||||
|
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckCollisionPointRec(mousePosition, decreaseTypeButton) && mousePressed)
|
||||||
|
{
|
||||||
|
viewportType = (viewportType + VIEWPORT_TYPE_COUNT - 1)%VIEWPORT_TYPE_COUNT;
|
||||||
|
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CheckCollisionPointRec(mousePosition, increaseTypeButton) && mousePressed)
|
||||||
|
{
|
||||||
|
viewportType = (viewportType + 1)%VIEWPORT_TYPE_COUNT;
|
||||||
|
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 textureMousePosition = Screen2RenderTexturePosition(mousePosition, &sourceRect, &destRect);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Draw our scene to the render texture
|
||||||
|
BeginTextureMode(target);
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
DrawCircleV(textureMousePosition, 20.0f, LIME);
|
||||||
|
EndTextureMode();
|
||||||
|
|
||||||
|
// Draw render texture to main framebuffer
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(BLACK);
|
||||||
|
|
||||||
|
// Draw our render texture with rotation applied
|
||||||
|
DrawTexturePro(target.texture, sourceRect, destRect, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
|
||||||
|
|
||||||
|
// Draw Native resolution (GUI or anything)
|
||||||
|
// Draw info box
|
||||||
|
Rectangle infoRect = (Rectangle){5, 5, 330, 105};
|
||||||
|
DrawRectangleRec(infoRect, Fade(LIGHTGRAY, 0.7f));
|
||||||
|
DrawRectangleLinesEx(infoRect, 1, BLUE);
|
||||||
|
|
||||||
|
DrawText(TextFormat("Window Resolution: %d x %d", screenWidth, screenHeight), 15, 15, 10, BLACK);
|
||||||
|
DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK);
|
||||||
|
|
||||||
|
DrawText(TextFormat("Type: %s", ViewportTypeNames[viewportType]), 15, 45, 10, BLACK);
|
||||||
|
Vector2 scaleRatio = (Vector2){destRect.width/sourceRect.width, -destRect.height/sourceRect.height};
|
||||||
|
if (scaleRatio.x < 0.001f || scaleRatio.y < 0.001f) DrawText(TextFormat("Scale ratio: INVALID"), 15, 60, 10, BLACK);
|
||||||
|
else DrawText(TextFormat("Scale ratio: %.2f x %.2f", scaleRatio.x, scaleRatio.y), 15, 60, 10, BLACK);
|
||||||
|
|
||||||
|
DrawText(TextFormat("Source size: %.2f x %.2f", sourceRect.width, -sourceRect.height), 15, 75, 10, BLACK);
|
||||||
|
DrawText(TextFormat("Destination size: %.2f x %.2f", destRect.width, destRect.height), 15, 90, 10, BLACK);
|
||||||
|
|
||||||
|
// Draw buttons
|
||||||
|
DrawRectangleRec(decreaseTypeButton, SKYBLUE);
|
||||||
|
DrawRectangleRec(increaseTypeButton, SKYBLUE);
|
||||||
|
DrawRectangleRec(decreaseResolutionButton, SKYBLUE);
|
||||||
|
DrawRectangleRec(increaseResolutionButton, SKYBLUE);
|
||||||
|
DrawText("<", decreaseTypeButton.x + 3, decreaseTypeButton.y + 1, 10, BLACK);
|
||||||
|
DrawText(">", increaseTypeButton.x + 3, increaseTypeButton.y + 1, 10, BLACK);
|
||||||
|
DrawText("<", decreaseResolutionButton.x + 3, decreaseResolutionButton.y + 1, 10, BLACK);
|
||||||
|
DrawText(">", increaseResolutionButton.x + 3, increaseResolutionButton.y + 1, 10, BLACK);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||||
|
{
|
||||||
|
sourceRect->x = 0.0f;
|
||||||
|
sourceRect->y = (float)gameHeight;
|
||||||
|
sourceRect->width = (float)gameWidth;
|
||||||
|
sourceRect->height = (float)-gameHeight;
|
||||||
|
|
||||||
|
const int ratio_x = (screenWidth/gameWidth);
|
||||||
|
const int ratio_y = (screenHeight/gameHeight);
|
||||||
|
const float resizeRatio = (float)((ratio_x < ratio_y)? ratio_x : ratio_y);
|
||||||
|
|
||||||
|
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
|
||||||
|
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
|
||||||
|
destRect->width = (float)(int)(gameWidth*resizeRatio);
|
||||||
|
destRect->height = (float)(int)(gameHeight*resizeRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||||
|
{
|
||||||
|
const float resizeRatio = (float)screenHeight/gameHeight;
|
||||||
|
sourceRect->x = 0.0f;
|
||||||
|
sourceRect->y = 0.0f;
|
||||||
|
sourceRect->width = (float)(int)(screenWidth/resizeRatio);
|
||||||
|
sourceRect->height = (float)-gameHeight;
|
||||||
|
|
||||||
|
destRect->x = (float)(int)((screenWidth - (sourceRect->width*resizeRatio))*0.5f);
|
||||||
|
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
|
||||||
|
destRect->width = (float)(int)(sourceRect->width*resizeRatio);
|
||||||
|
destRect->height = (float)(int)(gameHeight*resizeRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||||
|
{
|
||||||
|
const float resizeRatio = (float)screenWidth/gameWidth;
|
||||||
|
sourceRect->x = 0.0f;
|
||||||
|
sourceRect->y = 0.0f;
|
||||||
|
sourceRect->width = (float)gameWidth;
|
||||||
|
sourceRect->height = (float)(int)(screenHeight/resizeRatio);
|
||||||
|
|
||||||
|
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
|
||||||
|
destRect->y = (float)(int)((screenHeight - (sourceRect->height*resizeRatio))*0.5f);
|
||||||
|
destRect->width = (float)(int)(gameWidth*resizeRatio);
|
||||||
|
destRect->height = (float)(int)(sourceRect->height*resizeRatio);
|
||||||
|
|
||||||
|
sourceRect->height *= -1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||||
|
{
|
||||||
|
sourceRect->x = 0.0f;
|
||||||
|
sourceRect->y = (float)gameHeight;
|
||||||
|
sourceRect->width = (float)gameWidth;
|
||||||
|
sourceRect->height = (float)-gameHeight;
|
||||||
|
|
||||||
|
const float ratio_x = ((float)screenWidth/(float)gameWidth);
|
||||||
|
const float ratio_y = ((float)screenHeight/(float)gameHeight);
|
||||||
|
const float resizeRatio = (ratio_x < ratio_y ? ratio_x : ratio_y);
|
||||||
|
|
||||||
|
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
|
||||||
|
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
|
||||||
|
destRect->width = (float)(int)(gameWidth*resizeRatio);
|
||||||
|
destRect->height = (float)(int)(gameHeight*resizeRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||||
|
{
|
||||||
|
const float resizeRatio = ((float)screenHeight/(float)gameHeight);
|
||||||
|
sourceRect->x = 0.0f;
|
||||||
|
sourceRect->y = 0.0f;
|
||||||
|
sourceRect->width = (float)(int)((float)screenWidth/resizeRatio);
|
||||||
|
sourceRect->height = (float)-gameHeight;
|
||||||
|
|
||||||
|
destRect->x = (float)(int)((screenWidth - (sourceRect->width*resizeRatio))*0.5f);
|
||||||
|
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
|
||||||
|
destRect->width = (float)(int)(sourceRect->width*resizeRatio);
|
||||||
|
destRect->height = (float)(int)(gameHeight*resizeRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||||
|
{
|
||||||
|
const float resizeRatio = ((float)screenWidth/(float)gameWidth);
|
||||||
|
sourceRect->x = 0.0f;
|
||||||
|
sourceRect->y = 0.0f;
|
||||||
|
sourceRect->width = (float)gameWidth;
|
||||||
|
sourceRect->height = (float)(int)((float)screenHeight/resizeRatio);
|
||||||
|
|
||||||
|
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
|
||||||
|
destRect->y = (float)(int)((screenHeight - (sourceRect->height*resizeRatio))*0.5f);
|
||||||
|
destRect->width = (float)(int)(gameWidth*resizeRatio);
|
||||||
|
destRect->height = (float)(int)(sourceRect->height*resizeRatio);
|
||||||
|
|
||||||
|
sourceRect->height *= -1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target)
|
||||||
|
{
|
||||||
|
*screenWidth = GetScreenWidth();
|
||||||
|
*screenHeight = GetScreenHeight();
|
||||||
|
|
||||||
|
switch(viewportType)
|
||||||
|
{
|
||||||
|
case KEEP_ASPECT_INTEGER: KeepAspectCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||||
|
case KEEP_HEIGHT_INTEGER: KeepHeightCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||||
|
case KEEP_WIDTH_INTEGER: KeepWidthCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||||
|
case KEEP_ASPECT: KeepAspectCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||||
|
case KEEP_HEIGHT: KeepHeightCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||||
|
case KEEP_WIDTH: KeepWidthCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnloadRenderTexture(*target);
|
||||||
|
*target = LoadRenderTexture(sourceRect->width, -sourceRect->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example how to calculate position on RenderTexture
|
||||||
|
static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect)
|
||||||
|
{
|
||||||
|
Vector2 relativePosition = {point.x - scaledRect->x, point.y - scaledRect->y};
|
||||||
|
Vector2 ratio = {textureRect->width/scaledRect->width, -textureRect->height/scaledRect->height};
|
||||||
|
|
||||||
|
return (Vector2){relativePosition.x*ratio.x, relativePosition.y*ratio.x};
|
||||||
|
}
|
||||||
BIN
examples/core/core_viewport_scaling.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
|
|
@ -43,7 +43,7 @@ int main(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Set configuration flags for window creation
|
// Set configuration flags for window creation
|
||||||
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
|
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);// | FLAG_WINDOW_TRANSPARENT);
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - window flags");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - window flags");
|
||||||
|
|
||||||
Vector2 ballPosition = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
Vector2 ballPosition = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||||
|
|
@ -97,7 +97,8 @@ int main(void)
|
||||||
if (IsWindowState(FLAG_WINDOW_MINIMIZED))
|
if (IsWindowState(FLAG_WINDOW_MINIMIZED))
|
||||||
{
|
{
|
||||||
framesCounter++;
|
framesCounter++;
|
||||||
if (framesCounter >= 240) {
|
if (framesCounter >= 240)
|
||||||
|
{
|
||||||
RestoreWindow(); // Restore window after 3 seconds
|
RestoreWindow(); // Restore window after 3 seconds
|
||||||
framesCounter = 0;
|
framesCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
int main()
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -413,7 +413,7 @@ static MsfGifBuffer * msf_compress_frame(void * allocContext, int width, int hei
|
||||||
|
|
||||||
//generate palette
|
//generate palette
|
||||||
typedef struct { uint8_t r, g, b; } Color3;
|
typedef struct { uint8_t r, g, b; } Color3;
|
||||||
Color3 table[256] = { {0} };
|
Color3 table[256] = { { 0 } };
|
||||||
int tableIdx = 1; //we start counting at 1 because 0 is the transparent color
|
int tableIdx = 1; //we start counting at 1 because 0 is the transparent color
|
||||||
//transparent is always last in the table
|
//transparent is always last in the table
|
||||||
tlb[tlbSize-1] = 0;
|
tlb[tlbSize-1] = 0;
|
||||||
|
|
@ -550,7 +550,7 @@ static void msf_free_gif_state(MsfGifState * handle) {
|
||||||
|
|
||||||
int msf_gif_begin(MsfGifState * handle, int width, int height) { MsfTimeFunc
|
int msf_gif_begin(MsfGifState * handle, int width, int height) { MsfTimeFunc
|
||||||
//NOTE: we cannot stomp the entire struct to zero because we must preserve `customAllocatorContext`.
|
//NOTE: we cannot stomp the entire struct to zero because we must preserve `customAllocatorContext`.
|
||||||
MsfCookedFrame empty = {0}; //god I hate MSVC...
|
MsfCookedFrame empty = { 0 }; //god I hate MSVC...
|
||||||
handle->previousFrame = empty;
|
handle->previousFrame = empty;
|
||||||
handle->currentFrame = empty;
|
handle->currentFrame = empty;
|
||||||
handle->width = width;
|
handle->width = width;
|
||||||
|
|
@ -614,7 +614,7 @@ int msf_gif_frame(MsfGifState * handle, uint8_t * pixelData, int centiSecondsPer
|
||||||
}
|
}
|
||||||
|
|
||||||
MsfGifResult msf_gif_end(MsfGifState * handle) { MsfTimeFunc
|
MsfGifResult msf_gif_end(MsfGifState * handle) { MsfTimeFunc
|
||||||
if (!handle->listHead) { MsfGifResult empty = {0}; return empty; }
|
if (!handle->listHead) { MsfGifResult empty = { 0 }; return empty; }
|
||||||
|
|
||||||
//first pass: determine total size
|
//first pass: determine total size
|
||||||
size_t total = 1; //1 byte for trailing marker
|
size_t total = 1; //1 byte for trailing marker
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
#
|
#
|
||||||
# raylib examples list used to generate/update collection
|
# raylib examples list with available .c example files
|
||||||
# examples must be provided as: <example_category>;<example_name>;<example_stars>;<raylib_created_version>;<raylib_last_update_version>;<year_created>;<year_reviewed>;"<example_author_name>";<author_github_user>
|
#
|
||||||
|
# WARNING: List is not ordered by example name but by the display order on web,
|
||||||
|
# so it can not be automatically generated scanning available .c code files, only updated
|
||||||
|
# new examples are added at the end of each category; it's up to the user to reorder them as desired
|
||||||
|
#
|
||||||
|
# examples data is listed as: <example_category>;<example_name>;<example_stars>;<raylib_created_version>;<raylib_last_update_version>;<year_created>;<year_reviewed>;"<example_author_name>";<author_github_user>
|
||||||
#
|
#
|
||||||
# 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
|
||||||
# New examples must be added to this list and any possible rename must be made on this list first
|
|
||||||
#
|
|
||||||
# WARNING: List is not ordered by example name but by the display order on web
|
|
||||||
#
|
#
|
||||||
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;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||||
|
|
@ -25,7 +27,7 @@ core;core_3d_camera_mode;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@rays
|
||||||
core;core_3d_camera_free;★☆☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
core;core_3d_camera_free;★☆☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_3d_camera_first_person;★★☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
core;core_3d_camera_first_person;★★☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_3d_camera_split_screen;★★★☆;3.7;4.0;2021;2025;"Jeffery Myers";@JeffM2501
|
core;core_3d_camera_split_screen;★★★☆;3.7;4.0;2021;2025;"Jeffery Myers";@JeffM2501
|
||||||
core;core_3d_camera_fps;★★★☆;5.5;5.5;2025;2025;"Agnis Aldins";@nezvers
|
core;core_3d_camera_fps;★★★☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||||
core;core_3d_picking;★★☆☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5
|
core;core_3d_picking;★★☆☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_world_screen;★★☆☆;1.3;1.4;2015;2025;"Ramon Santamaria";@raysan5
|
core;core_world_screen;★★☆☆;1.3;1.4;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
core;core_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -43,15 +45,18 @@ core;core_custom_frame_control;★★★★;4.0;4.0;2021;2025;"Ramon Santamaria"
|
||||||
core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessandroni";@NotManyIdeasDev
|
core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessandroni";@NotManyIdeasDev
|
||||||
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_high_dpi;★★☆☆;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;★☆☆☆;5.6-dev;5.6-dev;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_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;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_screen_recording;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
core;core_screen_recording;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_clipboard_text;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;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_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"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
|
||||||
shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower
|
shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower
|
||||||
|
|
@ -84,6 +89,13 @@ shapes;shapes_math_sine_cosine;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe"
|
||||||
shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2025;2025;"Balamurugan R";@Bala050814
|
shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;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;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
|
shapes;shapes_lines_drawing;★☆☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
||||||
|
shapes;shapes_math_angle_rotation;★☆☆☆;5.6-dev;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_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||||
|
shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||||
|
shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||||
|
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
||||||
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
|
||||||
|
|
@ -109,7 +121,11 @@ textures;textures_gif_player;★★★☆;4.2;4.2;2021;2025;"Ramon Santamaria";@
|
||||||
textures;textures_image_kernel;★★★★;1.3;1.3;2015;2025;"Karim Salem";@kimo-s
|
textures;textures_image_kernel;★★★★;1.3;1.3;2015;2025;"Karim Salem";@kimo-s
|
||||||
textures;textures_image_channel;★★☆☆;5.5;5.5;2024;2025;"Bruno Cabral";@brccabral
|
textures;textures_image_channel;★★☆☆;5.5;5.5;2024;2025;"Bruno Cabral";@brccabral
|
||||||
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_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_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||||
|
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
|
||||||
text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -125,6 +141,7 @@ 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;★★★☆;5.6-dev;5.6-dev;2025;2025;"Wagner Barongello";@SultansOfCode
|
||||||
text;text_words_alignment;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
text;text_words_alignment;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
|
text;text_strings_management;★★★☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||||
models;models_animation_playing;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant
|
models;models_animation_playing;★★☆☆;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
|
||||||
|
|
@ -150,6 +167,8 @@ 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;★★☆☆;5.6-dev;5.6-dev;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;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||||
|
models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
|
models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
||||||
shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
|
shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;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
|
||||||
|
|
@ -163,6 +182,7 @@ shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff";
|
||||||
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;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||||
|
shaders;shaders_color_correction;★★☆☆;5.6;5.6;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
|
||||||
|
|
@ -181,6 +201,7 @@ 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;★★★☆;5.6-dev;5.6-dev;2025;2025;"Luís Almeida";@luis605
|
||||||
|
shaders;shaders_game_of_life;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||||
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;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -189,6 +210,7 @@ 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
|
||||||
others;rlgl_standalone;★★★★;1.6;4.0;2014;2025;"Ramon Santamaria";@raysan5
|
others;rlgl_standalone;★★★★;1.6;4.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
others;rlgl_compute_shader;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
others;rlgl_compute_shader;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
||||||
others;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flashback-fx
|
others;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flashback-fx
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* Example complexity rating: [★★★★] 4/4
|
* Example complexity rating: [★★★★] 4/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6-dev
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
*
|
*
|
||||||
* 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
|
||||||
|
|
@ -43,8 +43,10 @@ typedef struct MeshBuilder {
|
||||||
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]);
|
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]);
|
||||||
static void FreeMeshBuilder(MeshBuilder *mb);
|
static void FreeMeshBuilder(MeshBuilder *mb);
|
||||||
static Mesh BuildMesh(MeshBuilder *mb);
|
static Mesh BuildMesh(MeshBuilder *mb);
|
||||||
static Mesh GenMeshDecal(Mesh inputMesh, Ray ray);
|
static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset);
|
||||||
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s);
|
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s);
|
||||||
|
static void FreeDecalMeshData(void) { GenMeshDecal((Model){ .meshCount = -1 }, (Matrix){ 0 }, 0.0f, 0.0f); }
|
||||||
|
static bool GuiButton(Rectangle rec, const char *label);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
|
|
@ -105,10 +107,6 @@ int main(void)
|
||||||
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture;
|
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture;
|
||||||
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
||||||
|
|
||||||
// We're going to use these to build up our decal meshes
|
|
||||||
// They'll resize automatically as we go, we'll free them at the end
|
|
||||||
MeshBuilder meshBuilders[2] = { 0 };
|
|
||||||
|
|
||||||
bool showModel = true;
|
bool showModel = true;
|
||||||
Model decalModels[MAX_DECALS] = { 0 };
|
Model decalModels[MAX_DECALS] = { 0 };
|
||||||
int decalCount = 0;
|
int decalCount = 0;
|
||||||
|
|
@ -123,8 +121,6 @@ int main(void)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_SPACE)) showModel = !showModel;
|
|
||||||
|
|
||||||
// Display information about closest hit
|
// Display information about closest hit
|
||||||
RayCollision collision = { 0 };
|
RayCollision collision = { 0 };
|
||||||
collision.distance = FLT_MAX;
|
collision.distance = FLT_MAX;
|
||||||
|
|
@ -165,206 +161,14 @@ int main(void)
|
||||||
|
|
||||||
// Spin the placement around a bit
|
// Spin the placement around a bit
|
||||||
splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD*((float)GetRandomValue(-180, 180))));
|
splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD*((float)GetRandomValue(-180, 180))));
|
||||||
Matrix splatInv = MatrixInvert(splat);
|
|
||||||
|
|
||||||
// Reset the mesh builders
|
Mesh decalMesh = GenMeshDecal(model, splat, decalSize, decalOffset);
|
||||||
meshBuilders[0].vertexCount = 0;
|
|
||||||
meshBuilders[1].vertexCount = 0;
|
|
||||||
|
|
||||||
// We'll be flip-flopping between the two mesh builders
|
if (decalMesh.vertexCount > 0)
|
||||||
// Reading from one and writing to the other, then swapping
|
|
||||||
int mbIndex = 0;
|
|
||||||
|
|
||||||
// First pass, just get any triangle inside the bounding box (for each mesh of the model)
|
|
||||||
for (int meshIndex = 0; meshIndex < model.meshCount; meshIndex++)
|
|
||||||
{
|
{
|
||||||
Mesh mesh = model.meshes[meshIndex];
|
|
||||||
for (int tri = 0; tri < mesh.triangleCount; tri++)
|
|
||||||
{
|
|
||||||
Vector3 vertices[3] = { 0 };
|
|
||||||
|
|
||||||
// The way we calculate the vertices of the mesh triangle
|
|
||||||
// depend on whether the mesh vertices are indexed or not
|
|
||||||
if (mesh.indices == 0)
|
|
||||||
{
|
|
||||||
for (int v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
vertices[v] = (Vector3){
|
|
||||||
mesh.vertices[3*3*tri + 3*v + 0],
|
|
||||||
mesh.vertices[3*3*tri + 3*v + 1],
|
|
||||||
mesh.vertices[3*3*tri + 3*v + 2]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int v = 0; v < 3; v++)
|
|
||||||
{
|
|
||||||
vertices[v] = (Vector3){
|
|
||||||
mesh.vertices[ 3*mesh.indices[3*tri+0] + v],
|
|
||||||
mesh.vertices[ 3*mesh.indices[3*tri+1] + v],
|
|
||||||
mesh.vertices[ 3*mesh.indices[3*tri+2] + v]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform all 3 vertices of the triangle
|
|
||||||
// and check if they are inside our decal box
|
|
||||||
int insideCount = 0;
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
// To splat space
|
|
||||||
Vector3 v = Vector3Transform(vertices[i], splat);
|
|
||||||
|
|
||||||
if ((fabsf(v.x) < decalSize) || (fabsf(v.y) <= decalSize) || (fabsf(v.z) <= decalSize)) insideCount++;
|
|
||||||
|
|
||||||
// We need to keep the transformed vertex
|
|
||||||
vertices[i] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If any of them are inside, we add the triangle - we'll clip it later
|
|
||||||
if (insideCount > 0) AddTriangleToMeshBuilder(&meshBuilders[mbIndex], vertices);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clipping time! We need to clip against all 6 directions
|
|
||||||
Vector3 planes[6] = {
|
|
||||||
{ 1, 0, 0 },
|
|
||||||
{ -1, 0, 0 },
|
|
||||||
{ 0, 1, 0 },
|
|
||||||
{ 0, -1, 0 },
|
|
||||||
{ 0, 0, 1 },
|
|
||||||
{ 0, 0, -1 }
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int face = 0; face < 6; face++)
|
|
||||||
{
|
|
||||||
// Swap current model builder (so we read from the one we just wrote to)
|
|
||||||
mbIndex = 1 - mbIndex;
|
|
||||||
|
|
||||||
MeshBuilder *inMesh = &meshBuilders[1 - mbIndex];
|
|
||||||
MeshBuilder *outMesh = &meshBuilders[mbIndex];
|
|
||||||
|
|
||||||
// Reset write builder
|
|
||||||
outMesh->vertexCount = 0;
|
|
||||||
|
|
||||||
float s = 0.5f*decalSize;
|
|
||||||
|
|
||||||
for (int i = 0; i < inMesh->vertexCount; i += 3)
|
|
||||||
{
|
|
||||||
Vector3 nV1, nV2, nV3, nV4;
|
|
||||||
|
|
||||||
float d1 = Vector3DotProduct(inMesh->vertices[ i + 0 ], planes[face] ) - s;
|
|
||||||
float d2 = Vector3DotProduct(inMesh->vertices[ i + 1 ], planes[face] ) - s;
|
|
||||||
float d3 = Vector3DotProduct(inMesh->vertices[ i + 2 ], planes[face] ) - s;
|
|
||||||
|
|
||||||
int v1Out = (d1 > 0);
|
|
||||||
int v2Out = (d2 > 0);
|
|
||||||
int v3Out = (d3 > 0);
|
|
||||||
|
|
||||||
// Calculate, how many vertices of the face lie outside of the clipping plane
|
|
||||||
int total = v1Out + v2Out + v3Out;
|
|
||||||
|
|
||||||
switch (total)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
// The entire face lies inside of the plane, no clipping needed
|
|
||||||
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){inMesh->vertices[i], inMesh->vertices[i+1], inMesh->vertices[i+2]});
|
|
||||||
} break;
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
// One vertex lies outside of the plane, perform clipping
|
|
||||||
if (v1Out)
|
|
||||||
{
|
|
||||||
nV1 = inMesh->vertices[i + 1];
|
|
||||||
nV2 = inMesh->vertices[i + 2];
|
|
||||||
nV3 = ClipSegment(inMesh->vertices[i], nV1, planes[face], s);
|
|
||||||
nV4 = ClipSegment(inMesh->vertices[i], nV2, planes[face], s);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v2Out)
|
|
||||||
{
|
|
||||||
nV1 = inMesh->vertices[i];
|
|
||||||
nV2 = inMesh->vertices[i + 2];
|
|
||||||
nV3 = ClipSegment(inMesh->vertices[i + 1], nV1, planes[face], s);
|
|
||||||
nV4 = ClipSegment(inMesh->vertices[i + 1], nV2, planes[face], s);
|
|
||||||
|
|
||||||
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV3, nV2, nV1});
|
|
||||||
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV2, nV3, nV4});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v3Out)
|
|
||||||
{
|
|
||||||
nV1 = inMesh->vertices[i];
|
|
||||||
nV2 = inMesh->vertices[i + 1];
|
|
||||||
nV3 = ClipSegment(inMesh->vertices[i + 2], nV1, planes[face], s);
|
|
||||||
nV4 = ClipSegment(inMesh->vertices[i + 2], nV2, planes[face], s);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
|
||||||
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV4, nV3, nV2});
|
|
||||||
} break;
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
// Two vertices lies outside of the plane, perform clipping
|
|
||||||
if (!v1Out)
|
|
||||||
{
|
|
||||||
nV1 = inMesh->vertices[i];
|
|
||||||
nV2 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s);
|
|
||||||
nV3 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s);
|
|
||||||
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!v2Out)
|
|
||||||
{
|
|
||||||
nV1 = inMesh->vertices[i + 1];
|
|
||||||
nV2 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s);
|
|
||||||
nV3 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s);
|
|
||||||
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!v3Out)
|
|
||||||
{
|
|
||||||
nV1 = inMesh->vertices[i + 2];
|
|
||||||
nV2 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s);
|
|
||||||
nV3 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s);
|
|
||||||
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case 3: // The entire face lies outside of the plane, so let's discard the corresponding vertices
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we just need to re-transform the vertices
|
|
||||||
MeshBuilder *theMesh = &meshBuilders[mbIndex];
|
|
||||||
|
|
||||||
// Allocate room for UVs
|
|
||||||
if (theMesh->vertexCount > 0)
|
|
||||||
{
|
|
||||||
theMesh->uvs = (Vector2 *)MemAlloc(sizeof(Vector2)*theMesh->vertexCount);
|
|
||||||
|
|
||||||
for (int i = 0; i < theMesh->vertexCount; i++)
|
|
||||||
{
|
|
||||||
// Calculate the UVs based on the projected coords
|
|
||||||
// They are clipped to (-decalSize .. decalSize) and we want them (0..1)
|
|
||||||
theMesh->uvs[i].x = (theMesh->vertices[i].x/decalSize + 0.5f);
|
|
||||||
theMesh->uvs[i].y = (theMesh->vertices[i].y/decalSize + 0.5f);
|
|
||||||
|
|
||||||
// From splat space to world space
|
|
||||||
theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], splatInv);
|
|
||||||
|
|
||||||
// Tiny nudge in the normal direction so it renders properly over the mesh
|
|
||||||
theMesh->vertices[i] = Vector3Add(theMesh->vertices[i], Vector3Scale(collision.normal, decalOffset));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decal model data ready, create it and add it
|
|
||||||
int decalIndex = decalCount++;
|
int decalIndex = decalCount++;
|
||||||
decalModels[decalIndex] = LoadModelFromMesh(BuildMesh(theMesh));
|
decalModels[decalIndex] = LoadModelFromMesh(decalMesh);
|
||||||
decalModels[decalIndex].materials[0] = decalMaterial;
|
decalModels[decalIndex].materials[0].maps[0] = decalMaterial.maps[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -379,7 +183,7 @@ int main(void)
|
||||||
if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
|
if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
|
||||||
|
|
||||||
// Draw the decal models
|
// Draw the decal models
|
||||||
for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){0}, 1.0f, WHITE);
|
for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){ 0 }, 1.0f, WHITE);
|
||||||
|
|
||||||
// If we hit the mesh, draw the box for the decal
|
// If we hit the mesh, draw the box for the decal
|
||||||
if (collision.hit)
|
if (collision.hit)
|
||||||
|
|
@ -387,19 +191,19 @@ int main(void)
|
||||||
Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f));
|
Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f));
|
||||||
Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0});
|
Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0});
|
||||||
placementCube.transform = MatrixInvert(splat);
|
placementCube.transform = MatrixInvert(splat);
|
||||||
DrawModel(placementCube, (Vector3){0}, 1.0f, Fade(WHITE, 0.5f));
|
DrawModel(placementCube, (Vector3){ 0 }, 1.0f, Fade(WHITE, 0.5f));
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawGrid(10, 10.0f);
|
DrawGrid(10, 10.0f);
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
float yPos = 10;
|
float yPos = 10;
|
||||||
float x0 = GetScreenWidth() - 300;
|
float x0 = GetScreenWidth() - 300.0f;
|
||||||
float x1 = x0 + 100;
|
float x1 = x0 + 100;
|
||||||
float x2 = x1 + 100;
|
float x2 = x1 + 100;
|
||||||
|
|
||||||
DrawText("Vertices", x1, yPos, 10, LIME);
|
DrawText("Vertices", (int)x1, (int)yPos, 10, LIME);
|
||||||
DrawText("Triangles", x2, yPos, 10, LIME);
|
DrawText("Triangles", (int)x2, (int)yPos, 10, LIME);
|
||||||
yPos += 15;
|
yPos += 15;
|
||||||
|
|
||||||
int vertexCount = 0;
|
int vertexCount = 0;
|
||||||
|
|
@ -411,30 +215,49 @@ int main(void)
|
||||||
triangleCount += model.meshes[i].triangleCount;
|
triangleCount += model.meshes[i].triangleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawText("Main model", x0, yPos, 10, LIME);
|
DrawText("Main model", (int)x0, (int)yPos, 10, LIME);
|
||||||
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME);
|
DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME);
|
||||||
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME);
|
DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME);
|
||||||
yPos += 15;
|
yPos += 15;
|
||||||
|
|
||||||
for (int i = 0; i < decalCount; i++)
|
for (int i = 0; i < decalCount; i++)
|
||||||
{
|
{
|
||||||
DrawText(TextFormat("Decal #%d", i+1), x0, yPos, 10, LIME);
|
if (i == 20)
|
||||||
DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), x1, yPos, 10, LIME);
|
{
|
||||||
DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), x2, yPos, 10, LIME);
|
DrawText("...", (int)x0, (int)yPos, 10, LIME);
|
||||||
|
yPos += 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < 20)
|
||||||
|
{
|
||||||
|
DrawText(TextFormat("Decal #%d", i+1), (int)x0, (int)yPos, 10, LIME);
|
||||||
|
DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), (int)x1, (int)yPos, 10, LIME);
|
||||||
|
DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), (int)x2, (int)yPos, 10, LIME);
|
||||||
|
yPos += 15;
|
||||||
|
}
|
||||||
|
|
||||||
vertexCount += decalModels[i].meshes[0].vertexCount;
|
vertexCount += decalModels[i].meshes[0].vertexCount;
|
||||||
triangleCount += decalModels[i].meshes[0].triangleCount;
|
triangleCount += decalModels[i].meshes[0].triangleCount;
|
||||||
yPos += 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawText("TOTAL", x0, yPos, 10, LIME);
|
DrawText("TOTAL", (int)x0, (int)yPos, 10, LIME);
|
||||||
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME);
|
DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME);
|
||||||
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME);
|
DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME);
|
||||||
yPos += 15;
|
yPos += 15;
|
||||||
|
|
||||||
DrawText("Hold RMB to move camera", 10, 430, 10, GRAY);
|
DrawText("Hold RMB to move camera", 10, 430, 10, GRAY);
|
||||||
DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY);
|
DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY);
|
||||||
|
|
||||||
|
// UI elements
|
||||||
|
if (GuiButton((Rectangle){ 10, screenHeight - 1000.f, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel;
|
||||||
|
|
||||||
|
if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100.0f, 100, 60 }, "Clear Decals"))
|
||||||
|
{
|
||||||
|
// Clear decals, unload all decal models
|
||||||
|
for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
|
||||||
|
decalCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|
@ -446,13 +269,12 @@ int main(void)
|
||||||
UnloadModel(model);
|
UnloadModel(model);
|
||||||
UnloadTexture(modelTexture);
|
UnloadTexture(modelTexture);
|
||||||
|
|
||||||
// TODO: WARNING: This line crashes program on closing
|
// Unload decal models
|
||||||
//for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
|
for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
|
||||||
|
|
||||||
UnloadTexture(decalTexture);
|
UnloadTexture(decalTexture);
|
||||||
|
|
||||||
FreeMeshBuilder(&meshBuilders[0]);
|
FreeDecalMeshData(); // Free the data for decal generation
|
||||||
FreeMeshBuilder(&meshBuilders[1]);
|
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
@ -536,3 +358,248 @@ static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s)
|
||||||
|
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate mesh decals for provided model
|
||||||
|
static Mesh GenMeshDecal(Model target, Matrix projection, float decalSize, float decalOffset)
|
||||||
|
{
|
||||||
|
// We're going to use these to build up our decal meshes
|
||||||
|
// They'll resize automatically as we go, we'll free them at the end
|
||||||
|
static MeshBuilder meshBuilders[2] = { 0 };
|
||||||
|
|
||||||
|
// Ugly way of telling us to free the static MeshBuilder data
|
||||||
|
if (target.meshCount == -1)
|
||||||
|
{
|
||||||
|
FreeMeshBuilder(&meshBuilders[0]);
|
||||||
|
FreeMeshBuilder(&meshBuilders[1]);
|
||||||
|
return (Mesh){ 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're going to need the inverse matrix
|
||||||
|
Matrix invProj = MatrixInvert(projection);
|
||||||
|
|
||||||
|
// Reset the mesh builders
|
||||||
|
meshBuilders[0].vertexCount = 0;
|
||||||
|
meshBuilders[1].vertexCount = 0;
|
||||||
|
|
||||||
|
// We'll be flip-flopping between the two mesh builders
|
||||||
|
// Reading from one and writing to the other, then swapping
|
||||||
|
int mbIndex = 0;
|
||||||
|
|
||||||
|
// First pass, just get any triangle inside the bounding box (for each mesh of the model)
|
||||||
|
for (int meshIndex = 0; meshIndex < target.meshCount; meshIndex++)
|
||||||
|
{
|
||||||
|
Mesh mesh = target.meshes[meshIndex];
|
||||||
|
for (int tri = 0; tri < mesh.triangleCount; tri++)
|
||||||
|
{
|
||||||
|
Vector3 vertices[3] = { 0 };
|
||||||
|
|
||||||
|
// The way we calculate the vertices of the mesh triangle
|
||||||
|
// depend on whether the mesh vertices are indexed or not
|
||||||
|
if (mesh.indices == 0)
|
||||||
|
{
|
||||||
|
for (int v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
vertices[v] = (Vector3){
|
||||||
|
mesh.vertices[3*3*tri + 3*v + 0],
|
||||||
|
mesh.vertices[3*3*tri + 3*v + 1],
|
||||||
|
mesh.vertices[3*3*tri + 3*v + 2]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
vertices[v] = (Vector3){
|
||||||
|
mesh.vertices[ 3*mesh.indices[3*tri+0] + v],
|
||||||
|
mesh.vertices[ 3*mesh.indices[3*tri+1] + v],
|
||||||
|
mesh.vertices[ 3*mesh.indices[3*tri+2] + v]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform all 3 vertices of the triangle
|
||||||
|
// and check if they are inside our decal box
|
||||||
|
int insideCount = 0;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
// To projection space
|
||||||
|
Vector3 v = Vector3Transform(vertices[i], projection);
|
||||||
|
|
||||||
|
if ((fabsf(v.x) < decalSize) || (fabsf(v.y) <= decalSize) || (fabsf(v.z) <= decalSize)) insideCount++;
|
||||||
|
|
||||||
|
// We need to keep the transformed vertex
|
||||||
|
vertices[i] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If any of them are inside, we add the triangle - we'll clip it later
|
||||||
|
if (insideCount > 0) AddTriangleToMeshBuilder(&meshBuilders[mbIndex], vertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clipping time! We need to clip against all 6 directions
|
||||||
|
Vector3 planes[6] = {
|
||||||
|
{ 1, 0, 0 },
|
||||||
|
{ -1, 0, 0 },
|
||||||
|
{ 0, 1, 0 },
|
||||||
|
{ 0, -1, 0 },
|
||||||
|
{ 0, 0, 1 },
|
||||||
|
{ 0, 0, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int face = 0; face < 6; face++)
|
||||||
|
{
|
||||||
|
// Swap current model builder (so we read from the one we just wrote to)
|
||||||
|
mbIndex = 1 - mbIndex;
|
||||||
|
|
||||||
|
MeshBuilder *inMesh = &meshBuilders[1 - mbIndex];
|
||||||
|
MeshBuilder *outMesh = &meshBuilders[mbIndex];
|
||||||
|
|
||||||
|
// Reset write builder
|
||||||
|
outMesh->vertexCount = 0;
|
||||||
|
|
||||||
|
float s = 0.5f*decalSize;
|
||||||
|
|
||||||
|
for (int i = 0; i < inMesh->vertexCount; i += 3)
|
||||||
|
{
|
||||||
|
Vector3 nV1, nV2, nV3, nV4;
|
||||||
|
|
||||||
|
float d1 = Vector3DotProduct(inMesh->vertices[ i + 0 ], planes[face] ) - s;
|
||||||
|
float d2 = Vector3DotProduct(inMesh->vertices[ i + 1 ], planes[face] ) - s;
|
||||||
|
float d3 = Vector3DotProduct(inMesh->vertices[ i + 2 ], planes[face] ) - s;
|
||||||
|
|
||||||
|
int v1Out = (d1 > 0);
|
||||||
|
int v2Out = (d2 > 0);
|
||||||
|
int v3Out = (d3 > 0);
|
||||||
|
|
||||||
|
// Calculate, how many vertices of the face lie outside of the clipping plane
|
||||||
|
int total = v1Out + v2Out + v3Out;
|
||||||
|
|
||||||
|
switch (total)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
// The entire face lies inside of the plane, no clipping needed
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){inMesh->vertices[i], inMesh->vertices[i+1], inMesh->vertices[i+2]});
|
||||||
|
} break;
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// One vertex lies outside of the plane, perform clipping
|
||||||
|
if (v1Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i + 1];
|
||||||
|
nV2 = inMesh->vertices[i + 2];
|
||||||
|
nV3 = ClipSegment(inMesh->vertices[i], nV1, planes[face], s);
|
||||||
|
nV4 = ClipSegment(inMesh->vertices[i], nV2, planes[face], s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v2Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i];
|
||||||
|
nV2 = inMesh->vertices[i + 2];
|
||||||
|
nV3 = ClipSegment(inMesh->vertices[i + 1], nV1, planes[face], s);
|
||||||
|
nV4 = ClipSegment(inMesh->vertices[i + 1], nV2, planes[face], s);
|
||||||
|
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV3, nV2, nV1});
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV2, nV3, nV4});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v3Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i];
|
||||||
|
nV2 = inMesh->vertices[i + 1];
|
||||||
|
nV3 = ClipSegment(inMesh->vertices[i + 2], nV1, planes[face], s);
|
||||||
|
nV4 = ClipSegment(inMesh->vertices[i + 2], nV2, planes[face], s);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV4, nV3, nV2});
|
||||||
|
} break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// Two vertices lies outside of the plane, perform clipping
|
||||||
|
if (!v1Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i];
|
||||||
|
nV2 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s);
|
||||||
|
nV3 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s);
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v2Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i + 1];
|
||||||
|
nV2 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s);
|
||||||
|
nV3 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s);
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v3Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i + 2];
|
||||||
|
nV2 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s);
|
||||||
|
nV3 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s);
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case 3: // The entire face lies outside of the plane, so let's discard the corresponding vertices
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we just need to re-transform the vertices
|
||||||
|
MeshBuilder *theMesh = &meshBuilders[mbIndex];
|
||||||
|
|
||||||
|
// Allocate room for UVs
|
||||||
|
if (theMesh->vertexCount > 0)
|
||||||
|
{
|
||||||
|
theMesh->uvs = (Vector2 *)MemAlloc(sizeof(Vector2)*theMesh->vertexCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < theMesh->vertexCount; i++)
|
||||||
|
{
|
||||||
|
// Calculate the UVs based on the projected coords
|
||||||
|
// They are clipped to (-decalSize .. decalSize) and we want them (0..1)
|
||||||
|
theMesh->uvs[i].x = (theMesh->vertices[i].x/decalSize + 0.5f);
|
||||||
|
theMesh->uvs[i].y = (theMesh->vertices[i].y/decalSize + 0.5f);
|
||||||
|
|
||||||
|
// Tiny nudge in the normal direction so it renders properly over the mesh
|
||||||
|
theMesh->vertices[i].z -= decalOffset;
|
||||||
|
|
||||||
|
// From projection space to world space
|
||||||
|
theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], invProj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decal model data ready, create the mesh and return it
|
||||||
|
return BuildMesh(theMesh);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Return a blank mesh as there's nothing to add
|
||||||
|
return (Mesh){ 0 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button UI element
|
||||||
|
static bool GuiButton(Rectangle rec, const char *label)
|
||||||
|
{
|
||||||
|
Color bgColor = GRAY;
|
||||||
|
bool pressed = false;
|
||||||
|
|
||||||
|
if (CheckCollisionPointRec(GetMousePosition(), rec))
|
||||||
|
{
|
||||||
|
bgColor = LIGHTGRAY;
|
||||||
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) pressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawRectangleRec(rec, bgColor);
|
||||||
|
DrawRectangleLinesEx(rec, 2.0f, DARKGRAY);
|
||||||
|
|
||||||
|
int fontSize = 10;
|
||||||
|
int textWidth = MeasureText(label, fontSize);
|
||||||
|
|
||||||
|
DrawText(label, (int)(rec.x + rec.width*0.5f - textWidth*0.5f), (int)(rec.y + rec.height*0.5f - fontSize*0.5f), fontSize, DARKGRAY);
|
||||||
|
|
||||||
|
return pressed;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 66 KiB |
116
examples/models/models_directional_billboard.c
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - directional billboard
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Robin (@RobinsAviary) 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) 2025 Robin (@RobinsAviary)
|
||||||
|
* Killbot art by patvanmackelberg https://opengameart.org/content/killbot-8-directional under CC0
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - directional billboard");
|
||||||
|
|
||||||
|
// Set up the camera
|
||||||
|
Camera camera = { 0 };
|
||||||
|
camera.position = (Vector3){ 2.0f, 1.0f, 2.0f }; // Starting position
|
||||||
|
camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Target position
|
||||||
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Up vector
|
||||||
|
camera.fovy = 45.0f; // FOV
|
||||||
|
camera.projection = CAMERA_PERSPECTIVE; // Projection type (Standard 3D perspective)
|
||||||
|
|
||||||
|
// Load billboard texture
|
||||||
|
Texture skillbot = LoadTexture("resources/skillbot.png");
|
||||||
|
|
||||||
|
// Timer to update animation
|
||||||
|
float anim_timer = 0.0f;
|
||||||
|
// Animation frame
|
||||||
|
unsigned int anim = 0;
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
|
// Update timer with delta time
|
||||||
|
anim_timer += GetFrameTime();
|
||||||
|
|
||||||
|
// Update frame index after a certain amount of time (half a second)
|
||||||
|
if (anim_timer > 0.5f)
|
||||||
|
{
|
||||||
|
anim_timer = 0.0f;
|
||||||
|
anim += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset frame index to zero on overflow
|
||||||
|
if (anim >= 4) anim = 0;
|
||||||
|
|
||||||
|
// Find the current direction frame based on the camera position to the billboard object
|
||||||
|
float dir = (float)floor(((Vector2Angle((Vector2){ 2.0f, 0.0f }, (Vector2){ camera.position.x, camera.position.z })/PI)*4.0f) + 0.25f);
|
||||||
|
|
||||||
|
// Correct frame index if angle is negative
|
||||||
|
if (dir < 0.0f)
|
||||||
|
{
|
||||||
|
dir = 8.0f - (float)abs((int)dir);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode3D(camera);
|
||||||
|
|
||||||
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
|
// Draw billboard pointing straight up to the sky, rotated relative to the camera and offset from the bottom
|
||||||
|
DrawBillboardPro(camera, skillbot, (Rectangle){ 0.0f + (anim*24.0f), 0.0f + (dir*24.0f), 24.0f, 24.0f }, Vector3Zero(), (Vector3){ 0.0f, 1.0f, 0.0f }, Vector2One(), (Vector2){ 0.5f, 0.0f }, 0, WHITE);
|
||||||
|
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
// Render various variables for reference
|
||||||
|
DrawText(TextFormat("animation: %d", anim), 10, 10, 20, DARKGRAY);
|
||||||
|
DrawText(TextFormat("direction frame: %.0f", dir), 10, 40, 20, DARKGRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Unload billboard texture
|
||||||
|
UnloadTexture(skillbot);
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/models/models_directional_billboard.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
|
@ -80,18 +80,23 @@ int main(void)
|
||||||
if (playerCellY < 0) playerCellY = 0;
|
if (playerCellY < 0) playerCellY = 0;
|
||||||
else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1;
|
else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1;
|
||||||
|
|
||||||
// Check map collisions using image data and player position
|
// Check map collisions using image data and player position against surrounding cells only
|
||||||
// TODO: Improvement: Just check player surrounding cells for collision
|
for (int y = playerCellY - 1; y <= playerCellY + 1; y++)
|
||||||
for (int y = 0; y < cubicmap.height; y++)
|
|
||||||
{
|
{
|
||||||
for (int x = 0; x < cubicmap.width; x++)
|
// Avoid map accessing out of bounds
|
||||||
|
if ((y >= 0) && (y < cubicmap.height))
|
||||||
{
|
{
|
||||||
if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel
|
for (int x = playerCellX - 1; x <= playerCellX + 1; x++)
|
||||||
(CheckCollisionCircleRec(playerPos, playerRadius,
|
|
||||||
(Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f })))
|
|
||||||
{
|
{
|
||||||
// Collision detected, reset camera position
|
// NOTE: Collision: Only checking R channel for white pixel
|
||||||
camera.position = oldCamPos;
|
if (((x >= 0) && (x < cubicmap.width)) &&
|
||||||
|
(mapPixels[y*cubicmap.width + x].r == 255) &&
|
||||||
|
(CheckCollisionCircleRec(playerPos, playerRadius,
|
||||||
|
(Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f })))
|
||||||
|
{
|
||||||
|
// Collision detected, reset camera position
|
||||||
|
camera.position = oldCamPos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,171 +35,157 @@
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
const int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
const char *voxFileNames[] = {
|
const char *voxFileNames[] = {
|
||||||
"resources/models/vox/chr_knight.vox",
|
"resources/models/vox/chr_knight.vox",
|
||||||
"resources/models/vox/chr_sword.vox",
|
"resources/models/vox/chr_sword.vox",
|
||||||
"resources/models/vox/monu9.vox",
|
"resources/models/vox/monu9.vox",
|
||||||
"resources/models/vox/fez.vox"
|
"resources/models/vox/fez.vox"
|
||||||
};
|
};
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - loading vox");
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - loading vox");
|
||||||
|
|
||||||
// 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, 0.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 MagicaVoxel files
|
// Load MagicaVoxel files
|
||||||
Model models[MAX_VOX_FILES] = { 0 };
|
Model models[MAX_VOX_FILES] = { 0 };
|
||||||
|
|
||||||
for (int i = 0; i < MAX_VOX_FILES; i++)
|
for (int i = 0; i < MAX_VOX_FILES; i++)
|
||||||
{
|
{
|
||||||
// Load VOX file and measure time
|
// Load VOX file and measure time
|
||||||
double t0 = GetTime()*1000.0;
|
double t0 = GetTime()*1000.0;
|
||||||
models[i] = LoadModel(voxFileNames[i]);
|
models[i] = LoadModel(voxFileNames[i]);
|
||||||
double t1 = GetTime()*1000.0;
|
double t1 = GetTime()*1000.0;
|
||||||
|
|
||||||
TraceLog(LOG_WARNING, TextFormat("[%s] File loaded in %.3f ms", voxFileNames[i], t1 - t0));
|
TraceLog(LOG_INFO, TextFormat("[%s] Model file loaded in %.3f ms", voxFileNames[i], t1 - t0));
|
||||||
|
|
||||||
// Compute model translation matrix to center model on draw position (0, 0 , 0)
|
// Compute model translation matrix to center model on draw position (0, 0 , 0)
|
||||||
BoundingBox bb = GetModelBoundingBox(models[i]);
|
BoundingBox bb = GetModelBoundingBox(models[i]);
|
||||||
Vector3 center = { 0 };
|
Vector3 center = { 0 };
|
||||||
center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));
|
center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));
|
||||||
center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));
|
center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));
|
||||||
|
|
||||||
Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
|
Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
|
||||||
models[i].transform = matTranslate;
|
models[i].transform = matTranslate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentModel = 0;
|
int currentModel = 0;
|
||||||
|
Vector3 modelpos = { 0 };
|
||||||
|
Vector3 camerarot = { 0 };
|
||||||
|
|
||||||
// Load voxel shader
|
// Load voxel shader
|
||||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION),
|
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION),
|
||||||
TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION));
|
TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION));
|
||||||
|
|
||||||
// Get some required shader locations
|
// Get some required shader locations
|
||||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||||
// NOTE: "matModel" location name is automatically assigned on shader loading,
|
// NOTE: "matModel" location name is automatically assigned on shader loading,
|
||||||
// no need to get the location again if using that uniform name
|
// no need to get the location again if using that uniform name
|
||||||
//shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
|
//shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
|
||||||
|
|
||||||
// Ambient light level (some basic lighting)
|
// Ambient light level (some basic lighting)
|
||||||
int ambientLoc = GetShaderLocation(shader, "ambient");
|
int ambientLoc = GetShaderLocation(shader, "ambient");
|
||||||
SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4);
|
SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4);
|
||||||
|
|
||||||
// Assign out lighting shader to model
|
// Assign out lighting shader to model
|
||||||
for (int i = 0; i < MAX_VOX_FILES; i++)
|
for (int i = 0; i < MAX_VOX_FILES; i++)
|
||||||
{
|
{
|
||||||
Model m = models[i];
|
for (int j = 0; j < models[i].materialCount; j++) models[i].materials[j].shader = shader;
|
||||||
for (int j = 0; j < m.materialCount; j++)
|
}
|
||||||
{
|
|
||||||
m.materials[j].shader = shader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create lights
|
// Create lights
|
||||||
Light lights[MAX_LIGHTS] = { 0 };
|
Light lights[MAX_LIGHTS] = { 0 };
|
||||||
lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader);
|
lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader);
|
||||||
lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader);
|
lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader);
|
||||||
lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader);
|
lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader);
|
||||||
lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader);
|
lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader);
|
||||||
|
|
||||||
|
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
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))
|
||||||
|
{
|
||||||
|
const Vector2 mouseDelta = GetMouseDelta();
|
||||||
|
camerarot.x = mouseDelta.x*0.05f;
|
||||||
|
camerarot.y = mouseDelta.y*0.05f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
camerarot.x = 0;
|
||||||
|
camerarot.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
UpdateCameraPro(&camera,
|
||||||
Vector3 modelpos = { 0 };
|
(Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward
|
||||||
Vector3 camerarot = { 0 };
|
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left
|
||||||
|
0.0f }, // Move up-down
|
||||||
|
camerarot, // Camera rotation
|
||||||
|
GetMouseWheelMove()*-2.0f); // Move to target (zoom)
|
||||||
|
|
||||||
// Main game loop
|
// Cycle between models on mouse click
|
||||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1)%MAX_VOX_FILES;
|
||||||
{
|
|
||||||
// Update
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))
|
|
||||||
{
|
|
||||||
const Vector2 mouseDelta = GetMouseDelta();
|
|
||||||
camerarot.x = mouseDelta.x*0.05f;
|
|
||||||
camerarot.y = mouseDelta.y*0.05f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
camerarot.x = 0;
|
|
||||||
camerarot.y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateCameraPro(&camera,
|
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
|
||||||
(Vector3) {
|
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
|
||||||
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
|
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
|
||||||
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
|
|
||||||
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
|
|
||||||
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
|
|
||||||
0.0f // Move up-down
|
|
||||||
},
|
|
||||||
camerarot,
|
|
||||||
GetMouseWheelMove()*-2.0f); // Move to target (zoom)
|
|
||||||
|
|
||||||
// Cycle between models on mouse click
|
// Update light values (actually, only enable/disable them)
|
||||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES;
|
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
|
// Draw
|
||||||
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
|
//----------------------------------------------------------------------------------
|
||||||
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
|
BeginDrawing();
|
||||||
|
|
||||||
// Update light values (actually, only enable/disable them)
|
ClearBackground(RAYWHITE);
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]);
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
// Draw 3D model
|
||||||
// Draw
|
BeginMode3D(camera);
|
||||||
//----------------------------------------------------------------------------------
|
DrawModel(models[currentModel], modelpos, 1.0f, WHITE);
|
||||||
BeginDrawing();
|
DrawGrid(10, 1.0);
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
// Draw spheres to show where the lights are
|
||||||
|
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||||
|
{
|
||||||
|
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color);
|
||||||
|
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f));
|
||||||
|
}
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
// Draw 3D model
|
// Display info
|
||||||
BeginMode3D(camera);
|
DrawRectangle(10, 40, 340, 70, Fade(SKYBLUE, 0.5f));
|
||||||
|
DrawRectangleLines(10, 40, 340, 70, Fade(DARKBLUE, 0.5f));
|
||||||
|
DrawText("- MOUSE LEFT BUTTON: CYCLE VOX MODELS", 20, 50, 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(TextFormat("Model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
|
||||||
|
|
||||||
DrawModel(models[currentModel], modelpos, 1.0f, WHITE);
|
EndDrawing();
|
||||||
DrawGrid(10, 1.0);
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
// Draw spheres to show where the lights are
|
// De-Initialization
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
//--------------------------------------------------------------------------------------
|
||||||
{
|
// Unload models data (GPU VRAM)
|
||||||
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color);
|
for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
|
||||||
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f));
|
|
||||||
}
|
|
||||||
|
|
||||||
EndMode3D();
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Display info
|
return 0;
|
||||||
DrawRectangle(10, 400, 340, 60, Fade(SKYBLUE, 0.5f));
|
|
||||||
DrawRectangleLines(10, 400, 340, 60, Fade(DARKBLUE, 0.5f));
|
|
||||||
DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);
|
|
||||||
DrawText("MOUSE MIDDLE BUTTON to ZOOM OR ROTATE CAMERA", 40, 420, 10, BLUE);
|
|
||||||
DrawText("UP-DOWN-LEFT-RIGHT KEYS to MOVE CAMERA", 40, 430, 10, BLUE);
|
|
||||||
DrawText(TextFormat("File: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
|
|
||||||
|
|
||||||
EndDrawing();
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
}
|
|
||||||
|
|
||||||
// De-Initialization
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
// Unload models data (GPU VRAM)
|
|
||||||
for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
|
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ static Mesh GenMeshPoints(int numPoints);
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
int main()
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
@ -57,7 +57,7 @@ int main()
|
||||||
Mesh mesh = GenMeshPoints(numPoints);
|
Mesh mesh = GenMeshPoints(numPoints);
|
||||||
Model model = LoadModelFromMesh(mesh);
|
Model model = LoadModelFromMesh(mesh);
|
||||||
|
|
||||||
//SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
|
|
@ -92,15 +92,12 @@ int main()
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground(BLACK);
|
ClearBackground(BLACK);
|
||||||
|
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
|
|
||||||
// The new method only uploads the points once to the GPU
|
// The new method only uploads the points once to the GPU
|
||||||
if (useDrawModelPoints)
|
if (useDrawModelPoints) DrawModelPoints(model, position, 1.0f, WHITE);
|
||||||
{
|
|
||||||
DrawModelPoints(model, position, 1.0f, WHITE);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The old method must continually draw the "points" (lines)
|
// The old method must continually draw the "points" (lines)
|
||||||
|
|
@ -124,17 +121,16 @@ int main()
|
||||||
|
|
||||||
// Draw a unit sphere for reference
|
// Draw a unit sphere for reference
|
||||||
DrawSphereWires(position, 1.0f, 10, 10, YELLOW);
|
DrawSphereWires(position, 1.0f, 10, 10, YELLOW);
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
// Draw UI text
|
// Draw UI text
|
||||||
DrawText(TextFormat("Point Count: %d", numPoints), 20, screenHeight - 50, 40, WHITE);
|
DrawText(TextFormat("Point Count: %d", numPoints), 10, screenHeight - 50, 40, WHITE);
|
||||||
DrawText("Up - increase points", 20, 70, 20, WHITE);
|
DrawText("UP - Increase points", 10, 40, 20, WHITE);
|
||||||
DrawText("Down - decrease points", 20, 100, 20, WHITE);
|
DrawText("DOWN - Decrease points", 10, 70, 20, WHITE);
|
||||||
DrawText("Space - drawing function", 20, 130, 20, WHITE);
|
DrawText("SPACE - Drawing function", 10, 100, 20, WHITE);
|
||||||
|
|
||||||
if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 20, 160, 20, GREEN);
|
if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 10, 130, 20, GREEN);
|
||||||
else DrawText("Using: DrawPoint3D()", 20, 160, 20, RED);
|
else DrawText("Using: DrawPoint3D()", 10, 130, 20, RED);
|
||||||
|
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,25 +148,25 @@ void DrawSphereBasic(Color color)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < slices; j++)
|
for (int j = 0; j < slices; j++)
|
||||||
{
|
{
|
||||||
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)),
|
||||||
sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
|
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)),
|
||||||
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices)));
|
||||||
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
|
||||||
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
|
||||||
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
|
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
|
||||||
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360.0f/slices)),
|
||||||
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
|
||||||
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360.0f/slices)));
|
||||||
|
|
||||||
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)),
|
||||||
sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
|
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)),
|
||||||
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
|
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices)));
|
||||||
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
|
||||||
sinf(DEG2RAD*(270+(180/(rings + 1))*(i))),
|
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i))),
|
||||||
cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices)));
|
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
|
||||||
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
|
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
|
||||||
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
|
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
|
||||||
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
|
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rlEnd();
|
rlEnd();
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@ int main(void)
|
||||||
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
|
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
|
||||||
Model skybox = LoadModelFromMesh(cube);
|
Model skybox = LoadModelFromMesh(cube);
|
||||||
|
|
||||||
// Set this to true to use an HDR Texture, Note that raylib must be built with HDR Support for this to work SUPPORT_FILEFORMAT_HDR
|
// Set this to true to use an HDR Texture
|
||||||
|
// NOTE: raylib must be built with HDR Support for this to work: SUPPORT_FILEFORMAT_HDR
|
||||||
bool useHDR = false;
|
bool useHDR = false;
|
||||||
|
|
||||||
// Load skybox shader and set required locations
|
// Load skybox shader and set required locations
|
||||||
|
|
@ -63,8 +64,8 @@ int main(void)
|
||||||
TextFormat("resources/shaders/glsl%i/skybox.fs", GLSL_VERSION));
|
TextFormat("resources/shaders/glsl%i/skybox.fs", GLSL_VERSION));
|
||||||
|
|
||||||
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "environmentMap"), (int[1]){ MATERIAL_MAP_CUBEMAP }, SHADER_UNIFORM_INT);
|
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "environmentMap"), (int[1]){ MATERIAL_MAP_CUBEMAP }, SHADER_UNIFORM_INT);
|
||||||
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "doGamma"), (int[1]) { useHDR ? 1 : 0 }, SHADER_UNIFORM_INT);
|
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "doGamma"), (int[1]){ useHDR? 1 : 0 }, SHADER_UNIFORM_INT);
|
||||||
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ useHDR ? 1 : 0 }, SHADER_UNIFORM_INT);
|
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ useHDR? 1 : 0 }, SHADER_UNIFORM_INT);
|
||||||
|
|
||||||
// Load cubemap shader and setup required shader locations
|
// Load cubemap shader and setup required shader locations
|
||||||
Shader shdrCubemap = LoadShader(TextFormat("resources/shaders/glsl%i/cubemap.vs", GLSL_VERSION),
|
Shader shdrCubemap = LoadShader(TextFormat("resources/shaders/glsl%i/cubemap.vs", GLSL_VERSION),
|
||||||
|
|
@ -91,9 +92,11 @@ int main(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Image img = LoadImage("resources/skybox.png");
|
// TODO: WARNING: On PLATFORM_WEB it requires a big amount of memory to process input image
|
||||||
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT); // CUBEMAP_LAYOUT_PANORAMA
|
// and generate the required cubemap image to be passed to rlLoadTextureCubemap()
|
||||||
UnloadImage(img);
|
Image image = LoadImage("resources/skybox.png");
|
||||||
|
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
|
||||||
|
UnloadImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||||
|
|
@ -132,9 +135,9 @@ int main(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Image img = LoadImage(droppedFiles.paths[0]);
|
Image image = LoadImage(droppedFiles.paths[0]);
|
||||||
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT);
|
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
|
||||||
UnloadImage(img);
|
UnloadImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextCopy(skyboxFileName, droppedFiles.paths[0]);
|
TextCopy(skyboxFileName, droppedFiles.paths[0]);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
int main()
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
@ -85,9 +85,9 @@ int main()
|
||||||
|
|
||||||
// Calculate the cube position
|
// Calculate the cube position
|
||||||
Vector3 cubePos = {
|
Vector3 cubePos = {
|
||||||
(float)(x - numBlocks/2)*(scale*3.0f) + scatter,
|
(float)(x - (float)numBlocks/2)*(scale*3.0f) + scatter,
|
||||||
(float)(y - numBlocks/2)*(scale*2.0f) + scatter,
|
(float)(y - (float)numBlocks/2)*(scale*2.0f) + scatter,
|
||||||
(float)(z - numBlocks/2)*(scale*3.0f) + scatter
|
(float)(z - (float)numBlocks/2)*(scale*3.0f) + scatter
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pick a color with a hue depending on cube position for the rainbow color effect
|
// Pick a color with a hue depending on cube position for the rainbow color effect
|
||||||
|
|
|
||||||
BIN
examples/models/resources/skillbot.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#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
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ void UpdateDrawFrame(void); // Update and Draw one frame
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
int main()
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
5987
examples/shaders/raygui.h
Normal file
|
|
@ -11,3 +11,6 @@
|
||||||
| texel_checker.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [UV Checker Map Maker](http://uvchecker.byvalle.com/) |
|
| texel_checker.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [UV Checker Map Maker](http://uvchecker.byvalle.com/) |
|
||||||
| 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/) | - |
|
||||||
| spark_flame.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [EffectTextureMaker](https://mebiusbox.github.io/contents/EffectTextureMaker/) |
|
| spark_flame.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [EffectTextureMaker](https://mebiusbox.github.io/contents/EffectTextureMaker/) |
|
||||||
|
| parrots.png | [Kodak set](http://r0k.us/graphics/kodak/) | ❔ | Original name: `kodim23.png` |
|
||||||
|
| cat.png | ❔ | ❔ | - |
|
||||||
|
| mandrill.png | ❔ | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Mandrill (a.k.a. Baboon) |
|
||||||
BIN
examples/shaders/resources/cat.png
Normal file
|
After Width: | Height: | Size: 379 KiB |
BIN
examples/shaders/resources/game_of_life/acorn.png
Normal file
|
After Width: | Height: | Size: 218 B |
BIN
examples/shaders/resources/game_of_life/breeder.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/shaders/resources/game_of_life/glider.png
Normal file
|
After Width: | Height: | Size: 216 B |
BIN
examples/shaders/resources/game_of_life/glider_gun.png
Normal file
|
After Width: | Height: | Size: 291 B |
BIN
examples/shaders/resources/game_of_life/oscillators.png
Normal file
|
After Width: | Height: | Size: 463 B |
BIN
examples/shaders/resources/game_of_life/puffer_train.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/shaders/resources/game_of_life/r_pentomino.png
Normal file
|
After Width: | Height: | Size: 213 B |
BIN
examples/shaders/resources/game_of_life/spaceships.png
Normal file
|
After Width: | Height: | Size: 828 B |
BIN
examples/shaders/resources/game_of_life/still_lifes.png
Normal file
|
After Width: | Height: | Size: 615 B |
BIN
examples/shaders/resources/mandrill.png
Normal file
|
After Width: | Height: | Size: 193 KiB |
BIN
examples/shaders/resources/parrots.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
|
|
@ -0,0 +1,34 @@
|
||||||
|
#version 100
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
|
||||||
|
uniform float contrast;
|
||||||
|
uniform float saturation;
|
||||||
|
uniform float brightness;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Get texel color
|
||||||
|
vec4 texel = texture2D(texture0, fragTexCoord);
|
||||||
|
|
||||||
|
// Apply contrast
|
||||||
|
texel.rgb = (texel.rgb - 0.5)*(contrast/100.0 + 1.0) + 0.5;
|
||||||
|
|
||||||
|
// Apply brightness
|
||||||
|
texel.rgb = texel.rgb + brightness/100.0;
|
||||||
|
|
||||||
|
// Apply saturation
|
||||||
|
float intensity = dot(texel.rgb, vec3(0.299, 0.587, 0.114));
|
||||||
|
texel.rgb = (texel.rgb - intensity)*saturation/100.0 + texel.rgb;
|
||||||
|
|
||||||
|
// Output resulting color
|
||||||
|
gl_FragColor = texel;
|
||||||
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ void main()
|
||||||
vec3 ambient = albedo*vec3(0.1);
|
vec3 ambient = albedo*vec3(0.1);
|
||||||
vec3 viewDirection = normalize(viewPosition - fragPosition);
|
vec3 viewDirection = normalize(viewPosition - fragPosition);
|
||||||
|
|
||||||
for (int i = 0; i < NR_LIGHTS; ++i)
|
for (int i = 0; i < NR_LIGHTS; i++)
|
||||||
{
|
{
|
||||||
if (lights[i].enabled == 0) continue;
|
if (lights[i].enabled == 0) continue;
|
||||||
vec3 lightDirection = lights[i].position - fragPosition;
|
vec3 lightDirection = lights[i].position - fragPosition;
|
||||||
|
|
|
||||||
44
examples/shaders/resources/shaders/glsl100/game_of_life.fs
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
#version 100
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
|
||||||
|
// Input size in pixels of the textures
|
||||||
|
uniform vec2 resolution;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Size of one pixel in texture coordinates (from 0.0 to 1.0)
|
||||||
|
float x = 1.0/resolution.x;
|
||||||
|
float y = 1.0/resolution.y;
|
||||||
|
|
||||||
|
// Status of the current cell (1 = alive, 0 = dead)
|
||||||
|
int origValue = (texture2D(texture0, fragTexCoord).r < 0.1)? 1 : 0;
|
||||||
|
|
||||||
|
// Sum of alive neighbors
|
||||||
|
int sumValue = (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left
|
||||||
|
sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top
|
||||||
|
sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right
|
||||||
|
|
||||||
|
sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left
|
||||||
|
sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right
|
||||||
|
|
||||||
|
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left
|
||||||
|
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom
|
||||||
|
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right
|
||||||
|
|
||||||
|
// Game of life rules:
|
||||||
|
// Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise
|
||||||
|
// Current cell goes from dead to alive when exactly 3 neighbors are alive
|
||||||
|
if ((origValue == 1 && sumValue == 2) || sumValue == 3)
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black
|
||||||
|
else
|
||||||
|
gl_FragColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#version 100
|
#version 100
|
||||||
|
|
||||||
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
||||||
|
|
||||||
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
||||||
|
|
||||||
varying vec2 fragTexCoord;
|
varying vec2 fragTexCoord;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#extension GL_EXT_frag_depth : enable //Extension required for writing depth
|
#extension GL_EXT_frag_depth : enable //Extension required for writing depth
|
||||||
#extension GL_OES_standard_derivatives : enable //Extension used for fwidth()
|
#extension GL_OES_standard_derivatives : enable //Extension used for fwidth()
|
||||||
|
|
||||||
|
#define ZERO 0
|
||||||
|
|
||||||
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
|
|
@ -17,8 +20,6 @@ uniform vec3 camPos;
|
||||||
uniform vec3 camDir;
|
uniform vec3 camDir;
|
||||||
uniform vec2 screenCenter;
|
uniform vec2 screenCenter;
|
||||||
|
|
||||||
#define ZERO 0
|
|
||||||
|
|
||||||
// SRC: https://learnopengl.com/Advanced-OpenGL/Depth-testing
|
// SRC: https://learnopengl.com/Advanced-OpenGL/Depth-testing
|
||||||
float CalcDepth(in vec3 rd, in float Idist)
|
float CalcDepth(in vec3 rd, in float Idist)
|
||||||
{
|
{
|
||||||
|
|
@ -128,7 +129,7 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
|
||||||
|
|
||||||
float res = 1.0;
|
float res = 1.0;
|
||||||
float t = mint;
|
float t = mint;
|
||||||
for (int i=ZERO; i<24; i++)
|
for (int i = ZERO; i < 24; i++)
|
||||||
{
|
{
|
||||||
float h = map(ro + rd*t).x;
|
float h = map(ro + rd*t).x;
|
||||||
float s = clamp(8.0*h/t,0.0,1.0);
|
float s = clamp(8.0*h/t,0.0,1.0);
|
||||||
|
|
@ -156,7 +157,7 @@ float calcAO(in vec3 pos, in vec3 nor)
|
||||||
{
|
{
|
||||||
float occ = 0.0;
|
float occ = 0.0;
|
||||||
float sca = 1.0;
|
float sca = 1.0;
|
||||||
for (int i=ZERO; i<5; i++)
|
for (int i = ZERO; i < 5; i++)
|
||||||
{
|
{
|
||||||
float h = 0.01 + 0.12*float(i)/4.0;
|
float h = 0.01 + 0.12*float(i)/4.0;
|
||||||
float d = map(pos + h*nor).x;
|
float d = map(pos + h*nor).x;
|
||||||
|
|
@ -257,7 +258,8 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||||
return vec4(vec3(clamp(col,0.0,1.0)),t);
|
return vec4(vec3(clamp(col,0.0,1.0)),t);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 CalcRayDir(vec2 nCoord){
|
vec3 CalcRayDir(vec2 nCoord)
|
||||||
|
{
|
||||||
vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0)));
|
vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0)));
|
||||||
vec3 vertical = normalize(cross(horizontal,camDir));
|
vec3 vertical = normalize(cross(horizontal,camDir));
|
||||||
return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y);
|
return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y);
|
||||||
|
|
@ -287,6 +289,7 @@ void main()
|
||||||
color = res.xyz;
|
color = res.xyz;
|
||||||
depth = CalcDepth(rd,res.w);
|
depth = CalcDepth(rd,res.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = vec4(color , 1.0);
|
gl_FragColor = vec4(color , 1.0);
|
||||||
gl_FragDepthEXT = depth;
|
gl_FragDepthEXT = depth;
|
||||||
}
|
}
|
||||||
|
|
@ -34,7 +34,7 @@ void main()
|
||||||
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
|
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
|
||||||
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
|
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
|
||||||
|
|
||||||
for (int iter = 0; iter < maxIterationsLimit; ++iter)
|
for (int iter = 0; iter < maxIterationsLimit; iter++)
|
||||||
{
|
{
|
||||||
float aa = a*a;
|
float aa = a*a;
|
||||||
float bb = b*b;
|
float bb = b*b;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#version 100
|
#version 100
|
||||||
|
|
||||||
precision mediump float;
|
|
||||||
|
|
||||||
#extension GL_OES_standard_derivatives : enable
|
#extension GL_OES_standard_derivatives : enable
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
varying vec2 fragTexCoord;
|
varying vec2 fragTexCoord;
|
||||||
varying vec4 fragColor;
|
varying vec4 fragColor;
|
||||||
|
|
|
||||||