Merge branch 'master' into master

This commit is contained in:
Ray 2025-09-14 10:13:13 +02:00 committed by GitHub
commit c85129d909
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
670 changed files with 120415 additions and 62700 deletions

View File

@ -3,7 +3,7 @@
# #
# You may wish to alter this file to override the set of languages analyzed, # You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic. # or to provide custom queries or build logic.
name: "CodeQL" name: Analyze raylib with CodeQL
on: on:
workflow_dispatch: workflow_dispatch:
@ -26,7 +26,7 @@ jobs:
# - https://gh.io/supported-runners-and-hardware-resources # - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners # - https://gh.io/using-larger-runners
# Consider using larger runners for possible analysis time improvements. # Consider using larger runners for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }} runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions: permissions:
actions: read actions: read

View File

@ -1,4 +1,4 @@
name: Android name: Build raylib - Android
on: on:
workflow_dispatch: workflow_dispatch:

View File

@ -1,4 +1,4 @@
name: CMakeBuilds name: Build raylib CMake - Windows+Linux
on: on:
workflow_dispatch: workflow_dispatch:

View File

@ -1,4 +1,4 @@
name: Linux Examples name: Build raylib examples - Linux
on: on:
workflow_dispatch: workflow_dispatch:

View File

@ -1,4 +1,4 @@
name: Windows Examples name: Build raylib examples - Windows
on: on:
workflow_dispatch: workflow_dispatch:

View File

@ -1,4 +1,4 @@
name: Linux name: Build raylib - Linux
on: on:
workflow_dispatch: workflow_dispatch:
@ -22,22 +22,28 @@ jobs:
build: build:
permissions: permissions:
contents: write # for actions/upload-release-asset to upload release asset contents: write # for actions/upload-release-asset to upload release asset
runs-on: ubuntu-20.04
strategy: strategy:
fail-fast: false fail-fast: false
max-parallel: 1 max-parallel: 1
matrix: matrix:
bits: [32, 64]
include: include:
- bits: 32 - bits: 32
ARCH: "i386" ARCH: "i386"
ARCH_NAME: "i386" ARCH_NAME: "i386"
COMPILER_PATH: "/user/bin" COMPILER_PATH: "/usr/bin"
runner: "ubuntu-latest"
- bits: 64 - bits: 64
ARCH: "x86_64" ARCH: "x86_64"
ARCH_NAME: "amd64" ARCH_NAME: "amd64"
COMPILER_PATH: "/user/bin" COMPILER_PATH: "/usr/bin"
runner: "ubuntu-latest"
- bits: 64
ARCH: "aarch64"
ARCH_NAME: "arm64"
COMPILER_PATH: "/usr/bin"
runner: "ubuntu-24.04-arm"
runs-on: ${{ matrix.runner }}
env: env:
RELEASE_NAME: raylib-dev_linux_${{ matrix.ARCH_NAME }} RELEASE_NAME: raylib-dev_linux_${{ matrix.ARCH_NAME }}
@ -54,7 +60,6 @@ jobs:
- name: Setup Environment - name: Setup Environment
run: | run: |
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get install gcc-multilib
sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxext-dev libxfixes-dev libwayland-dev libxkbcommon-dev sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxext-dev libxfixes-dev libwayland-dev libxkbcommon-dev
mkdir build mkdir build
cd build cd build
@ -65,8 +70,13 @@ jobs:
cd ../../../raylib cd ../../../raylib
# ${{ matrix.ARCH }}-linux-gnu-gcc -v # ${{ matrix.ARCH }}-linux-gnu-gcc -v
- name: Setup Environment (x86)
run : |
sudo apt-get install gcc-multilib
if: matrix.bits == 32 && matrix.ARCH == 'i386'
# TODO: Support 32bit (i386) static/shared library building # TODO: Support 32bit (i386) static/shared library building
- name: Build Library - name: Build Library (32-bit)
run: | run: |
cd src cd src
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" CUSTOM_CFLAGS="-m32" -B make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" CUSTOM_CFLAGS="-m32" -B
@ -74,13 +84,21 @@ jobs:
cd .. cd ..
if: matrix.bits == 32 if: matrix.bits == 32
- name: Build Library - name: Build Library (64-bit x86)
run: | run: |
cd src cd src
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
cd .. cd ..
if: matrix.bits == 64 if: matrix.bits == 64 && matrix.ARCH == 'x86_64'
- name: Build Library (64-bit ARM)
run: |
cd src
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
cd ..
if: matrix.bits == 64 && matrix.ARCH == 'aarch64'
- name: Generate Artifacts - name: Generate Artifacts
run: | run: |

View File

@ -1,4 +1,4 @@
name: macOS name: Build raylib - macOS
on: on:
workflow_dispatch: workflow_dispatch:

View File

@ -1,4 +1,4 @@
name: WebAssembly name: Build raylib - WebAssembly
on: on:
workflow_dispatch: workflow_dispatch:

View File

@ -1,4 +1,4 @@
name: Windows name: Build raylib - Windows
on: on:
workflow_dispatch: workflow_dispatch:
@ -28,27 +28,34 @@ jobs:
max-parallel: 1 max-parallel: 1
matrix: matrix:
compiler: [mingw-w64, msvc16] compiler: [mingw-w64, msvc16]
bits: [32, 64] ziptarget: [ win32, win64, winarm64 ]
include: include:
- compiler: mingw-w64 - compiler: mingw-w64
bits: 32
ARCH: "i686" ARCH: "i686"
WINDRES_ARCH: pe-i386 WINDRES_ARCH: pe-i386
ziptarget: "win32"
- compiler: mingw-w64 - compiler: mingw-w64
bits: 64
ARCH: "x86_64" ARCH: "x86_64"
WINDRES_ARCH: pe-x86-64 WINDRES_ARCH: pe-x86-64
ziptarget: "win64"
- compiler: msvc16 - compiler: msvc16
bits: 32
ARCH: "x86" ARCH: "x86"
VSARCHPATH: "Win32" VSARCHPATH: "Win32"
ziptarget: "win32"
- compiler: msvc16 - compiler: msvc16
bits: 64
ARCH: "x64" ARCH: "x64"
VSARCHPATH: "x64" VSARCHPATH: "x64"
ziptarget: "win64"
- compiler: msvc16
ARCH: "ARM64"
VSARCHPATH: "ARM64"
ziptarget: "winarm64"
exclude:
- compiler: mingw-w64
ziptarget: winarm64 # We don't build arm64 with mingw-w64 yet
env: env:
RELEASE_NAME: raylib-dev_win${{ matrix.bits }}_${{ matrix.compiler }} RELEASE_NAME: raylib-dev_${{ matrix.ziptarget }}_${{ matrix.compiler }}
GNUTARGET: default GNUTARGET: default
steps: steps:
@ -57,7 +64,7 @@ jobs:
- name: Setup Release Version - name: Setup Release Version
run: | run: |
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_win${{ matrix.bits }}_${{ matrix.compiler }}" >> $GITHUB_ENV echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_${{ matrix.ziptarget }}_${{ matrix.compiler }}" >> $GITHUB_ENV
shell: bash shell: bash
if: github.event_name == 'release' && github.event.action == 'published' if: github.event_name == 'release' && github.event.action == 'published'
@ -90,7 +97,7 @@ jobs:
shell: cmd shell: cmd
if: | if: |
matrix.compiler == 'mingw-w64' && matrix.compiler == 'mingw-w64' &&
matrix.bits == 32 matrix.arch == 'i686'
- name: Build Library (MinGW-w64 64bit) - name: Build Library (MinGW-w64 64bit)
run: | run: |
@ -105,7 +112,7 @@ jobs:
shell: cmd shell: cmd
if: | if: |
matrix.compiler == 'mingw-w64' && matrix.compiler == 'mingw-w64' &&
matrix.bits == 64 matrix.arch == 'x86_64'
- name: Build Library (MSVC16) - name: Build Library (MSVC16)
run: | run: |

View File

@ -1,4 +1,4 @@
name: Parse raylib_api name: Parse raylib API
on: on:
workflow_dispatch: workflow_dispatch:
@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Update parse files - name: Update parse files
working-directory: parser working-directory: tools/parser
run: | run: |
make raylib_api make raylib_api
mv raylib_api.* output mv raylib_api.* output
@ -30,8 +30,8 @@ jobs:
if: steps.diff.outcome == 'failure' if: steps.diff.outcome == 'failure'
run: | run: |
set -x set -x
git config user.email "github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]" git config user.name "github-actions[bot]"
git add parser git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add tools/parser
git commit -m "Update raylib_api.* by CI" git commit -m "Update raylib_api.* by CI"
git push git push

72
.github/workflows/update_examples.yml vendored Normal file
View File

@ -0,0 +1,72 @@
name: Update examples collection
on:
workflow_dispatch:
push:
paths:
- 'examples/**'
pull_request:
paths:
- 'examples/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v14
with:
version: 'latest'
actions-cache-folder: 'emsdk-cache'
- name: Clone raylib.com repo to update files
run: |
git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/raysan5/raylib.com.git
shell: bash
- name: Build and run rexm tool (requires GNU Makefile)
# "rexm update" validates and updates all required examples in raylib and even raylib.com repos,
# note that it calls examples/Makefile.Web internally, so it requires [make] tool available
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
cd "${{ github.workspace }}/src"
make PLATFORM=PLATFORM_DESKTOP
sudo make install
make clean
make PLATFORM=PLATFORM_WEB
cd ../tools/rexm/
make
export REXM_EXAMPLES_BASE_PATH="${{ github.workspace }}/examples"
export REXM_EXAMPLES_WEB_PATH="${{ github.workspace }}/raylib.com/examples"
export REXM_EXAMPLES_TEMPLATE_FILE_PATH="${{ github.workspace }}/examples/examples_template.c"
export REXM_EXAMPLES_TEMPLATE_SCREENSHOT_PATH="${{ github.workspace }}/examples/examples_template.png"
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 EMSDK_PATH="${{ github.workspace }}/emsdk-cache/emsdk-main"
./rexm update
shell: bash
- name: Commit changes to raylib repo (DISABLED)
if: github.event_name == 'push' && false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -A
git commit -m "Update examples collection" || echo "git exited with code 1, nothing changed"
git push
shell: bash
- name: Push changes to raylib.com repo (DISABLED)
if: github.event_name == 'push' && false
run: |
cd raylib.com
git add -A
git commit -m "Update web examples" || echo "git exited with code 1, nothing changed"
git push origin
shell: bash

10
.gitignore vendored
View File

@ -111,5 +111,11 @@ build/
build-*/ build-*/
docgen_tmp/ docgen_tmp/
# Parser stuff # Tools stuff
parser/raylib_parser tools/parser/raylib_parser
tools/rexm/rexm.exe
tools/rexm/rexm
# CI
emsdk-cache/
raylib.com/

View File

@ -7,16 +7,19 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| Name | raylib Version | Language | License | | Name | raylib Version | Language | License |
| :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: | | :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: |
| [raylib](https://github.com/raysan5/raylib) | **5.5** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib | | [raylib](https://github.com/raysan5/raylib) | **5.5** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **5.5** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT | | [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT | | [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib55.c3l) | **5.5** | [C3](https://c3-lang.org) | MIT | | [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib55.c3l) | **5.5** | [C3](https://c3-lang.org) | MIT |
| [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib | | [raylib-cs](https://github.com/raylib-cs/raylib-cs) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | | [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | | [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.1-dev** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT | | [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
| [Raylib-cs.BleedingEdge](https://github.com/danilwhale/Raylib-cs.BleedingEdge) | **5.6-dev** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
| [cl-raylib](https://github.com/longlene/cl-raylib) | 4.0 | [Common Lisp](https://common-lisp.net) | MIT | | [cl-raylib](https://github.com/longlene/cl-raylib) | 4.0 | [Common Lisp](https://common-lisp.net) | MIT |
| [claylib/wrap](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib | | [claylib/wrap](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
| [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 |
| [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 |
| [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 |
@ -42,10 +45,15 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** | | [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** |
| [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib | | [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib |
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.0 | [Lua](http://www.lua.org) | ISC | | [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.0 | [Lua](http://www.lua.org) | ISC |
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | MIT | | [raylib-lua-bindings (WIP)](https://github.com/legendaryredfox/raylib-lua-bindings) | 5.5 | [Lua](http://www.lua.org) | ISC |
| [Raylib.nelua](https://github.com/AuzFox/Raylib.nelua) | **5.0** | [nelua](https://nelua.io) | Zlib | | [ReiLua](https://github.com/nullstare/ReiLua) | 5.5 | [Lua](http://www.lua.org) | MIT |
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib | | [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib |
| [naylib](https://github.com/planetis-m/naylib) | **5.1-dev** | [Nim](https://nim-lang.org) | MIT | | [raylib-luajit](https://github.com/homma/raylib-luajit) | 5.5 | [Lua](http://www.lua.org) | MIT |
| [raylib-luajit-generated](https://github.com/james2doyle/raylib-luajit-generated) | 5.5 | [Lua](http://www.lua.org) | MIT |
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | **???** |
| [Raylib.nelua](https://github.com/AuzFox/Raylib.nelua) | **5.5** | [nelua](https://nelua.io) | Zlib |
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib |
| [naylib](https://github.com/planetis-m/naylib) | **5.6-dev** | [Nim](https://nim-lang.org) | MIT |
| [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib | | [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib |
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | BSD-3Clause | | [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | BSD-3Clause |
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT | | [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
@ -64,16 +72,18 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylibr](https://github.com/jeroenjanssens/raylibr) | 4.0 | [R](https://www.r-project.org) | MIT | | [raylibr](https://github.com/jeroenjanssens/raylibr) | 4.0 | [R](https://www.r-project.org) | MIT |
| [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 5.5 | [Rust](https://www.rust-lang.org) | GPLv3 | | [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 5.5 | [Rust](https://www.rust-lang.org) | GPLv3 |
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib | | [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib |
| [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib |
| [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** | | [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** |
| [racket-raylib](https://github.com/eutro/racket-raylib) | 4.0 | [Racket](https://racket-lang.org) | MIT/Apache-2.0 | | [racket-raylib](https://github.com/eutro/racket-raylib) | **5.5** | [Racket](https://racket-lang.org) | MIT/Apache-2.0 |
| [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT | | [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT |
| [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT | | [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT |
| [raylib-SmallBASIC](https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib) | **5.5** | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 | | [raylib-SmallBASIC](https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib) | **5.5** | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 |
| [raylib-umka](https://github.com/robloach/raylib-umka) | 4.5 | [Umka](https://github.com/vtereshkov/umka-lang) | Zlib | | [raylib-umka](https://github.com/robloach/raylib-umka) | 4.5 | [Umka](https://github.com/vtereshkov/umka-lang) | Zlib |
| [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-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/Not-Nik/raylib-zig) | **5.5** | [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 |
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib | | [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib | | [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
@ -85,6 +95,8 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [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 |
| [raylib-apl](https://github.com/Brian-ED/raylib-apl) | **5.0** | [Dyalog APL](https://www.dyalog.com/) | MIT | | [raylib-apl](https://github.com/Brian-ED/raylib-apl) | **5.0** | [Dyalog APL](https://www.dyalog.com/) | MIT |
| [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **5.5** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT | | [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **5.5** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT |
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
| [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** |
### Utility Wrapers ### Utility Wrapers
@ -95,6 +107,7 @@ These are utility wrappers for specific languages, they are not required to use
| [claylib](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib | | [claylib](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
| [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT | | [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
| [DOOR](https://github.com/RealDoigt/DOOR) | 4.0 | [D](https://dlang.org) | MIT | | [DOOR](https://github.com/RealDoigt/DOOR) | 4.0 | [D](https://dlang.org) | MIT |
| [Iris](https://github.com/Marcos-cat/iris) | **5.5** | [Uiua](https://www.uiua.org/) | MIT |
### Older or Unmaintained Language Bindings ### Older or Unmaintained Language Bindings
@ -133,7 +146,6 @@ These are older raylib bindings that are more than 2 versions old or have not be
| [clj-raylib](https://github.com/lsevero/clj-raylib) | 3.0 | [Clojure](https://clojure.org) | | [clj-raylib](https://github.com/lsevero/clj-raylib) | 3.0 | [Clojure](https://clojure.org) |
| [QuickJS-raylib](https://github.com/sntg-p/QuickJS-raylib) | 3.0 | [QuickJS](https://bellard.org/quickjs) | | [QuickJS-raylib](https://github.com/sntg-p/QuickJS-raylib) | 3.0 | [QuickJS](https://bellard.org/quickjs) |
| [raylib-duktape](https://github.com/RobLoach/raylib-duktape) | 2.6 | [JavaScript (Duktape)](https://en.wikipedia.org/wiki/JavaScript) | | [raylib-duktape](https://github.com/RobLoach/raylib-duktape) | 2.6 | [JavaScript (Duktape)](https://en.wikipedia.org/wiki/JavaScript) |
| [raylib-v7](https://github.com/Rabios/raylib-v7) | 3.5 | [JavaScript (v7)](https://en.wikipedia.org/wiki/JavaScript) |
| [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) | 2.6 | [ChaiScript](http://chaiscript.com) | | [raylib-chaiscript](https://github.com/RobLoach/raylib-chaiscript) | 2.6 | [ChaiScript](http://chaiscript.com) |
| [raylib-squirrel](https://github.com/RobLoach/raylib-squirrel) | 2.5 | [Squirrel](http://www.squirrel-lang.org) | | [raylib-squirrel](https://github.com/RobLoach/raylib-squirrel) | 2.5 | [Squirrel](http://www.squirrel-lang.org) |
| [racket-raylib-2d](https://github.com/arvyy/racket-raylib-2d) | 2.5 | [Racket](https://racket-lang.org) | | [racket-raylib-2d](https://github.com/arvyy/racket-raylib-2d) | 2.5 | [Racket](https://racket-lang.org) |

View File

@ -1671,7 +1671,7 @@ Detailed changes:
[examples] ADDED: models_waving_cubes, by @codecat [examples] ADDED: models_waving_cubes, by @codecat
[examples] ADDED: models_solar_system, by @aldrinmartoq [examples] ADDED: models_solar_system, by @aldrinmartoq
[examples] ADDED: shaders_fog, by @chriscamacho [examples] ADDED: shaders_fog, by @chriscamacho
[examples] ADDED: shaders_texture_waves, by @Anata [examples] ADDED: shaders_texture_waves, by @anatagawa
[examples] ADDED: shaders_basic_lighting, by @chriscamacho [examples] ADDED: shaders_basic_lighting, by @chriscamacho
[examples] ADDED: shaders_simple_mask, by @chriscamacho [examples] ADDED: shaders_simple_mask, by @chriscamacho
[examples] ADDED: audio_multichannel_sound, by @chriscamacho [examples] ADDED: audio_multichannel_sound, by @chriscamacho

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.12) cmake_minimum_required(VERSION 3.25)
#this change avoid the warning that appear when we include raylib using Cmake fatch content
project(raylib) project(raylib)
# Avoid excessive expansion of variables in conditionals. In particular, if # Avoid excessive expansion of variables in conditionals. In particular, if
@ -22,21 +23,13 @@ cmake_policy(SET CMP0063 NEW)
# Anywhere you see include(...) you can check <root>/cmake for that file # Anywhere you see include(...) you can check <root>/cmake for that file
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# RAYLIB_IS_MAIN determines whether the project is being used from root
# or if it is added as a dependency (through add_subdirectory for example).
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
set(RAYLIB_IS_MAIN TRUE)
else()
set(RAYLIB_IS_MAIN FALSE)
endif()
# Sets compiler flags and language standard # Sets compiler flags and language standard
include(CompilerFlags) include(CompilerFlags)
# Registers build options that are exposed to cmake # Registers build options that are exposed to cmake
include(CMakeOptions.txt) include(CMakeOptions.txt)
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE AND NOT "${PLATFORM}" MATCHES "DRM" AND NOT "${PLATFORM}" MATCHES "Web")
if (NOT GLFW_BUILD_WAYLAND AND NOT GLFW_BUILD_X11) if (NOT GLFW_BUILD_WAYLAND AND NOT GLFW_BUILD_X11)
MESSAGE(FATAL_ERROR "Cannot disable both Wayland and X11") MESSAGE(FATAL_ERROR "Cannot disable both Wayland and X11")
endif() endif()
@ -45,8 +38,9 @@ endif()
# Main sources directory (the second parameter sets the output directory name to raylib) # Main sources directory (the second parameter sets the output directory name to raylib)
add_subdirectory(src raylib) add_subdirectory(src raylib)
# Uninstall target # Uninstall target, only create when building raylib by itself
if(NOT TARGET uninstall) # Avoid conflicting target names when using raylib with other libraries
if(NOT TARGET uninstall AND PROJECT_IS_TOP_LEVEL)
configure_file( configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Uninstall.cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Uninstall.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"

View File

@ -2,12 +2,16 @@
include(CMakeDependentOption) include(CMakeDependentOption)
include(EnumOption) include(EnumOption)
if(EMSCRIPTEN)
# 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.")
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" "Platform to build for.")
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0" "Force a specific OpenGL Version?") enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0" "Force a specific OpenGL Version?")
# Configuration options # Configuration options
option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN}) option(BUILD_EXAMPLES "Build the examples." ${PROJECT_IS_TOP_LEVEL})
option(CUSTOMIZE_BUILD "Show options for customizing your Raylib library build." OFF) option(CUSTOMIZE_BUILD "Show options for customizing your Raylib library build." OFF)
option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF) option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF) option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)

View File

@ -11,7 +11,7 @@ Local variables | lowerCase | `Vector2 playerPosition = { 0 };`
Global variables | lowerCase | `bool windowReady = false;` Global variables | lowerCase | `bool windowReady = false;`
Constants | lowerCase | `const int maxValue = 8;` Constants | lowerCase | `const int maxValue = 8;`
Pointers | MyType *pointer | `Texture2D *array = NULL;` Pointers | MyType *pointer | `Texture2D *array = NULL;`
float values | always x.xf | `float gravity = 10.0f` float values | always x.xf | `float gravity = 10.0f` (avoid `10.f`)
Operators | value1*value2 | `int product = value*6;` Operators | value1*value2 | `int product = value*6;`
Operators | value1/value2 | `int division = value/4;` Operators | value1/value2 | `int division = value/4;`
Operators | value1 + value2 | `int sum = value + 10;` Operators | value1 + value2 | `int sum = value + 10;`
@ -28,6 +28,10 @@ Some other conventions to follow:
- **ALWAYS** initialize all defined variables. - **ALWAYS** initialize all defined variables.
- **Do not use TABS**, use 4 spaces instead. - **Do not use TABS**, use 4 spaces instead.
- Avoid trailing spaces, please, avoid them - Avoid trailing spaces, please, avoid them
- Comments always start with space + capital letter and never end with a '.', place them **before** the line(s) they refer to
```c
// This is a comment in raylib or raylib examples
```
- Control flow statements always are followed **by a space**: - Control flow statements always are followed **by a space**:
```c ```c
if (condition) value = 0; if (condition) value = 0;

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) Copyright (c) 2013-2025 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.

View File

@ -24,21 +24,21 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
[![Youtube Subscribers](https://img.shields.io/youtube/channel/subscribers/UC8WIBkhYb5sBNqXO1mZ7WSQ?style=flat&label=Youtube&logo=youtube)](https://www.youtube.com/c/raylib) [![Youtube Subscribers](https://img.shields.io/youtube/channel/subscribers/UC8WIBkhYb5sBNqXO1mZ7WSQ?style=flat&label=Youtube&logo=youtube)](https://www.youtube.com/c/raylib)
[![Twitch Status](https://img.shields.io/twitch/status/raysan5?style=flat&label=Twitch&logo=twitch)](https://www.twitch.tv/raysan5) [![Twitch Status](https://img.shields.io/twitch/status/raysan5?style=flat&label=Twitch&logo=twitch)](https://www.twitch.tv/raysan5)
[![Windows](https://github.com/raysan5/raylib/workflows/Windows/badge.svg)](https://github.com/raysan5/raylib/actions?query=workflow%3AWindows) [![Build Windows](https://github.com/raysan5/raylib/actions/workflows/build_windows.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/build_windows.yml)
[![Linux](https://github.com/raysan5/raylib/workflows/Linux/badge.svg)](https://github.com/raysan5/raylib/actions?query=workflow%3ALinux) [![Build Linux](https://github.com/raysan5/raylib/actions/workflows/build_linux.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/build_linux.yml)
[![macOS](https://github.com/raysan5/raylib/workflows/macOS/badge.svg)](https://github.com/raysan5/raylib/actions?query=workflow%3AmacOS) [![Build macOS](https://github.com/raysan5/raylib/actions/workflows/build_macos.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/build_macos.yml)
[![WebAssembly](https://github.com/raysan5/raylib/workflows/WebAssembly/badge.svg)](https://github.com/raysan5/raylib/actions?query=workflow%3AWebAssembly) [![Build WebAssembly](https://github.com/raysan5/raylib/actions/workflows/build_webassembly.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/build_webassembly.yml)
[![CMakeBuilds](https://github.com/raysan5/raylib/workflows/CMakeBuilds/badge.svg)](https://github.com/raysan5/raylib/actions?query=workflow%3ACMakeBuilds) [![Build CMake](https://github.com/raysan5/raylib/actions/workflows/build_cmake.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/build_cmake.yml)
[![Windows Examples](https://github.com/raysan5/raylib/actions/workflows/windows_examples.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/windows_examples.yml) [![Build examples Windows](https://github.com/raysan5/raylib/actions/workflows/build_examples_windows.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/build_examples_windows.yml)
[![Linux Examples](https://github.com/raysan5/raylib/actions/workflows/linux_examples.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/linux_examples.yml) [![Build examples Linux](https://github.com/raysan5/raylib/actions/workflows/build_examples_linux.yml/badge.svg)](https://github.com/raysan5/raylib/actions/workflows/build_examples_linux.yml)
features features
-------- --------
- **NO external dependencies**, all required libraries are [bundled into raylib](https://github.com/raysan5/raylib/tree/master/src/external) - **NO external dependencies**, all required libraries are [included into raylib](https://github.com/raysan5/raylib/tree/master/src/external)
- Multiple platforms supported: **Windows, Linux, MacOS, RPI, Android, HTML5... and more!** - Multiple platforms supported: **Windows, Linux, MacOS, RPI, Android, HTML5... and more!**
- Written in plain C code (C99) using PascalCase/camelCase notation - Written in plain C code (C99) using PascalCase/camelCase notation
- Hardware accelerated with OpenGL (**1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**) - Hardware accelerated with OpenGL: **1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) - **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
- Multiple **Fonts** formats supported (TTF, OTF, FNT, BDF, sprite fonts) - Multiple **Fonts** formats supported (TTF, OTF, FNT, BDF, sprite fonts)
- Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC) - Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC)
@ -130,6 +130,7 @@ raylib is present in several networks and raylib community is growing everyday.
- Webpage: [https://www.raylib.com](https://www.raylib.com) - Webpage: [https://www.raylib.com](https://www.raylib.com)
- Discord: [https://discord.gg/raylib](https://discord.gg/raylib) - Discord: [https://discord.gg/raylib](https://discord.gg/raylib)
- Twitter: [https://www.twitter.com/raysan5](https://www.twitter.com/raysan5) - Twitter: [https://www.twitter.com/raysan5](https://www.twitter.com/raysan5)
- BlueSky: [https://bsky.app/profile/raysan5](https://bsky.app/profile/raysan5.bsky.social)
- Twitch: [https://www.twitch.tv/raysan5](https://www.twitch.tv/raysan5) - Twitch: [https://www.twitch.tv/raysan5](https://www.twitch.tv/raysan5)
- Reddit: [https://www.reddit.com/r/raylib](https://www.reddit.com/r/raylib) - Reddit: [https://www.reddit.com/r/raylib](https://www.reddit.com/r/raylib)
- Patreon: [https://www.patreon.com/raylib](https://www.patreon.com/raylib) - Patreon: [https://www.patreon.com/raylib](https://www.patreon.com/raylib)

View File

@ -3,16 +3,18 @@
Here is a wishlist with features and ideas to improve the library. Note that features listed here are usually long term improvements or just describe a route to follow for the library. There are also some additional places to look for raylib improvements and ideas: Here is a wishlist with features and ideas to improve the library. Note that features listed here are usually long term improvements or just describe a route to follow for the library. There are also some additional places to look for raylib improvements and ideas:
- [GitHub Issues](https://github.com/raysan5/raylib/issues) has several open issues for possible improvements or bugs to fix. - [GitHub Issues](https://github.com/raysan5/raylib/issues) has several open issues for possible improvements or bugs to fix.
- [GitHub PRs](https://github.com/raysan5/raylib/pulls) open with improvements to be reviewed.
- [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve. - [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve.
- raylib wishlists discussions are open to everyone to ask for improvements, feel free to check and comment: - raylib wishlists discussions are open to everyone to ask for improvements, feel free to check and comment:
- [raylib wishlist 2021](https://github.com/raysan5/raylib/discussions/1502) - [raylib 6.0 wishlist](https://github.com/raysan5/raylib/discussions/4660)
- [raylib wishlist 2022](https://github.com/raysan5/raylib/discussions/2272)
- [raylib 5.0 wishlist](https://github.com/raysan5/raylib/discussions/2952) - [raylib 5.0 wishlist](https://github.com/raysan5/raylib/discussions/2952)
- [raylib wishlist 2022](https://github.com/raysan5/raylib/discussions/2272)
- [raylib wishlist 2021](https://github.com/raysan5/raylib/discussions/1502)
_Current version of raylib is complete and functional but there is always room for improvements._ _Current version of raylib is complete and functional but there is always room for improvements._
**raylib 5.x** **raylib 5.x**
- [ ] `rcore`: Support additional platforms: iOS, Xbox Series S|X - [ ] `rcore`: Support additional platforms: iOS, consoles?
- [ ] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK - [ ] `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

560
build.zig
View File

@ -2,7 +2,10 @@ 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.13.0"; const min_ver = "0.15.1";
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
const emccOutputFile = "index.html";
comptime { comptime {
const order = std.SemanticVersion.order; const order = std.SemanticVersion.order;
@ -11,39 +14,82 @@ comptime {
@compileError("Raylib requires zig version " ++ min_ver); @compileError("Raylib requires zig version " ++ min_ver);
} }
pub const emsdk = struct {
const zemscripten = @import("zemscripten");
pub fn shell(b: *std.Build) std.Build.LazyPath {
return b.dependency("raylib", .{}).path("src/shell.html");
}
pub const FlagsOptions = struct {
optimize: std.builtin.OptimizeMode,
asyncify: bool = true,
};
pub fn emccDefaultFlags(allocator: std.mem.Allocator, options: FlagsOptions) zemscripten.EmccFlags {
var emcc_flags = zemscripten.emccDefaultFlags(allocator, .{
.optimize = options.optimize,
.fsanitize = true,
});
if (options.asyncify)
emcc_flags.put("-sASYNCIFY", {}) catch unreachable;
return emcc_flags;
}
pub const SettingsOptions = struct {
optimize: std.builtin.OptimizeMode,
es3: bool = true,
emsdk_allocator: zemscripten.EmsdkAllocator = .emmalloc,
};
pub fn emccDefaultSettings(allocator: std.mem.Allocator, options: SettingsOptions) zemscripten.EmccSettings {
var emcc_settings = zemscripten.emccDefaultSettings(allocator, .{
.optimize = options.optimize,
.emsdk_allocator = options.emsdk_allocator,
});
if (options.es3)
emcc_settings.put("FULL_ES3", "1") catch unreachable;
emcc_settings.put("USE_GLFW", "3") catch unreachable;
emcc_settings.put("EXPORTED_RUNTIME_METHODS", "['requestFullscreen']") catch unreachable;
return emcc_settings;
}
pub fn emccStep(b: *std.Build, raylib: *std.Build.Step.Compile, wasm: *std.Build.Step.Compile, options: zemscripten.StepOptions) *std.Build.Step {
const activate_emsdk_step = zemscripten.activateEmsdkStep(b);
const emsdk_dep = b.dependency("emsdk", .{});
raylib.root_module.addIncludePath(emsdk_dep.path("upstream/emscripten/cache/sysroot/include"));
wasm.root_module.addIncludePath(emsdk_dep.path("upstream/emscripten/cache/sysroot/include"));
const emcc_step = zemscripten.emccStep(b, wasm, options);
emcc_step.dependOn(activate_emsdk_step);
return emcc_step;
}
pub fn emrunStep(
b: *std.Build,
html_path: []const u8,
extra_args: []const []const u8,
) *std.Build.Step {
return zemscripten.emrunStep(b, html_path, extra_args);
}
};
fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend) void { fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend) void {
switch (platform) { switch (platform) {
.glfw => raylib.defineCMacro("PLATFORM_DESKTOP_GLFW", null), .glfw => raylib.root_module.addCMacro("PLATFORM_DESKTOP_GLFW", ""),
.rgfw => raylib.defineCMacro("PLATFORM_DESKTOP_RGFW", null), .rgfw => raylib.root_module.addCMacro("PLATFORM_DESKTOP_RGFW", ""),
.sdl => raylib.defineCMacro("PLATFORM_DESKTOP_SDL", null), .sdl => raylib.root_module.addCMacro("PLATFORM_DESKTOP_SDL", ""),
.android => raylib.root_module.addCMacro("PLATFORM_ANDROID", ""),
else => {}, else => {},
} }
} }
fn createEmsdkStep(b: *std.Build, emsdk: *std.Build.Dependency) *std.Build.Step.Run {
if (builtin.os.tag == .windows) {
return b.addSystemCommand(&.{emsdk.path("emsdk.bat").getPath(b)});
} else {
return b.addSystemCommand(&.{emsdk.path("emsdk").getPath(b)});
}
}
fn emSdkSetupStep(b: *std.Build, emsdk: *std.Build.Dependency) !?*std.Build.Step.Run {
const dot_emsc_path = emsdk.path(".emscripten").getPath(b);
const dot_emsc_exists = !std.meta.isError(std.fs.accessAbsolute(dot_emsc_path, .{}));
if (!dot_emsc_exists) {
const emsdk_install = createEmsdkStep(b, emsdk);
emsdk_install.addArgs(&.{ "install", "latest" });
const emsdk_activate = createEmsdkStep(b, emsdk);
emsdk_activate.addArgs(&.{ "activate", "latest" });
emsdk_activate.step.dependOn(&emsdk_install.step);
return emsdk_activate;
} else {
return null;
}
}
/// A list of all flags from `src/config.h` that one may override /// A list of all flags from `src/config.h` that one may override
const config_h_flags = outer: { const config_h_flags = outer: {
// Set this value higher if compile errors happen as `src/config.h` gets larger // Set this value higher if compile errors happen as `src/config.h` gets larger
@ -76,25 +122,41 @@ const config_h_flags = outer: {
}; };
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile { fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
var raylib_flags_arr = std.ArrayList([]const u8).init(b.allocator); var raylib_flags_arr: std.ArrayList([]const u8) = .empty;
defer raylib_flags_arr.deinit(); defer raylib_flags_arr.deinit(b.allocator);
try raylib_flags_arr.appendSlice(&[_][]const u8{ const raylib = b.addLibrary(.{
"-std=gnu99", .name = "raylib",
"-D_GNU_SOURCE", .linkage = options.linkage,
"-DGL_SILENCE_DEPRECATION=199309L", .root_module = b.createModule(.{
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674 .optimize = optimize,
.target = target,
.link_libc = true,
}),
}); });
if (options.shared) { try raylib_flags_arr.appendSlice(
try raylib_flags_arr.appendSlice(&[_][]const u8{ b.allocator,
"-fPIC", &[_][]const u8{
"-DBUILD_LIBTYPE_SHARED", "-std=gnu99",
}); "-D_GNU_SOURCE",
"-DGL_SILENCE_DEPRECATION=199309L",
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
},
);
if (options.linkage == .dynamic) {
try raylib_flags_arr.appendSlice(
b.allocator,
&[_][]const u8{
"-fPIC",
"-DBUILD_LIBTYPE_SHARED",
},
);
} }
// Sets a flag indiciating the use of a custom `config.h` // Sets a flag indiciating the use of a custom `config.h`
try raylib_flags_arr.append("-DEXTERNAL_CONFIG_FLAGS"); try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
if (options.config.len > 0) { if (options.config.len > 0) {
// Splits a space-separated list of config flags into multiple flags // Splits a space-separated list of config flags into multiple flags
// //
@ -104,7 +166,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
// Apply config flags supplied by the user // Apply config flags supplied by the user
while (config_iter.next()) |config_flag| while (config_iter.next()) |config_flag|
try raylib_flags_arr.append(config_flag); try raylib_flags_arr.append(b.allocator, config_flag);
// Apply all relevant configs from `src/config.h` *except* the user-specified ones // Apply all relevant configs from `src/config.h` *except* the user-specified ones
// //
@ -122,85 +184,142 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
} }
// Otherwise, append default value from config.h to compile flags // Otherwise, append default value from config.h to compile flags
try raylib_flags_arr.append(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 custome config got set
try raylib_flags_arr.appendSlice(&config_h_flags); try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
} }
const raylib = if (options.shared)
b.addSharedLibrary(.{
.name = "raylib",
.target = target,
.optimize = optimize,
})
else
b.addStaticLibrary(.{
.name = "raylib",
.target = target,
.optimize = optimize,
});
raylib.linkLibC();
// 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.addIncludePath(b.path("src/external/glfw/include"));
} }
var c_source_files = try std.ArrayList([]const u8).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", "src/utils.c" });
if (options.rshapes) { if (options.rshapes) {
try c_source_files.append("src/rshapes.c"); try c_source_files.append(b.allocator, "src/rshapes.c");
try raylib_flags_arr.append("-DSUPPORT_MODULE_RSHAPES"); try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RSHAPES");
} }
if (options.rtextures) { if (options.rtextures) {
try c_source_files.append("src/rtextures.c"); try c_source_files.append(b.allocator, "src/rtextures.c");
try raylib_flags_arr.append("-DSUPPORT_MODULE_RTEXTURES"); try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RTEXTURES");
} }
if (options.rtext) { if (options.rtext) {
try c_source_files.append("src/rtext.c"); try c_source_files.append(b.allocator, "src/rtext.c");
try raylib_flags_arr.append("-DSUPPORT_MODULE_RTEXT"); try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RTEXT");
} }
if (options.rmodels) { if (options.rmodels) {
try c_source_files.append("src/rmodels.c"); try c_source_files.append(b.allocator, "src/rmodels.c");
try raylib_flags_arr.append("-DSUPPORT_MODULE_RMODELS"); try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RMODELS");
} }
if (options.raudio) { if (options.raudio) {
try c_source_files.append("src/raudio.c"); try c_source_files.append(b.allocator, "src/raudio.c");
try raylib_flags_arr.append("-DSUPPORT_MODULE_RAUDIO"); try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RAUDIO");
} }
if (options.opengl_version != .auto) { if (options.opengl_version != .auto) {
raylib.defineCMacro(options.opengl_version.toCMacroStr(), null); raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), "");
} }
raylib.addIncludePath(b.path("src/platforms")); raylib.addIncludePath(b.path("src/platforms"));
switch (target.result.os.tag) { switch (target.result.os.tag) {
.windows => { .windows => {
try c_source_files.append("src/rglfw.c"); switch (options.platform) {
raylib.linkSystemLibrary("winmm"); .glfw => try c_source_files.append(b.allocator, "src/rglfw.c"),
raylib.linkSystemLibrary("gdi32"); .rgfw, .sdl, .drm, .android => {},
raylib.linkSystemLibrary("opengl32"); }
raylib.root_module.linkSystemLibrary("winmm", .{});
raylib.root_module.linkSystemLibrary("gdi32", .{});
raylib.root_module.linkSystemLibrary("opengl32", .{});
setDesktopPlatform(raylib, options.platform); setDesktopPlatform(raylib, options.platform);
}, },
.linux => { .linux => {
if (options.platform != .drm) { if (options.platform == .drm) {
try c_source_files.append("src/rglfw.c"); if (options.opengl_version == .auto) {
raylib.root_module.linkSystemLibrary("GLESv2", .{});
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
}
raylib.root_module.linkSystemLibrary("EGL", .{});
raylib.root_module.linkSystemLibrary("gbm", .{});
raylib.root_module.linkSystemLibrary("libdrm", .{ .use_pkg_config = .force });
raylib.root_module.addCMacro("PLATFORM_DRM", "");
raylib.root_module.addCMacro("EGL_NO_X11", "");
raylib.root_module.addCMacro("DEFAULT_BATCH_BUFFER_ELEMENT", "");
} else if (target.result.abi.isAndroid()) {
//these are the only tag options per https://developer.android.com/ndk/guides/other_build_systems
const hostTuple = switch (builtin.target.os.tag) {
.linux => "linux-x86_64",
.windows => "windows-x86_64",
.macos => "darwin-x86_64",
else => @panic("unsupported host OS"),
};
const androidTriple = switch (target.result.cpu.arch) {
.x86 => "i686-linux-android",
.x86_64 => "x86_64-linux-android",
.arm => "arm-linux-androideabi",
.aarch64 => "aarch64-linux-android",
.riscv64 => "riscv64-linux-android",
else => error.InvalidAndroidTarget,
} catch @panic("invalid android target!");
const androidNdkPathString: []const u8 = options.android_ndk;
if (androidNdkPathString.len < 1) @panic("no ndk path provided and ANDROID_NDK_HOME is not set");
const androidApiLevel: []const u8 = options.android_api_version;
const androidSysroot = try std.fs.path.join(b.allocator, &.{ androidNdkPathString, "/toolchains/llvm/prebuilt/", hostTuple, "/sysroot" });
const androidLibPath = try std.fs.path.join(b.allocator, &.{ androidSysroot, "/usr/lib/", androidTriple });
const androidApiSpecificPath = try std.fs.path.join(b.allocator, &.{ androidLibPath, androidApiLevel });
const androidIncludePath = try std.fs.path.join(b.allocator, &.{ androidSysroot, "/usr/include" });
const androidArchIncludePath = try std.fs.path.join(b.allocator, &.{ androidIncludePath, androidTriple });
const androidAsmPath = try std.fs.path.join(b.allocator, &.{ androidIncludePath, "/asm-generic" });
const androidGluePath = try std.fs.path.join(b.allocator, &.{ androidNdkPathString, "/sources/android/native_app_glue/" });
raylib.root_module.addLibraryPath(.{ .cwd_relative = androidLibPath });
raylib.root_module.addLibraryPath(.{ .cwd_relative = androidApiSpecificPath });
raylib.root_module.addSystemIncludePath(.{ .cwd_relative = androidIncludePath });
raylib.root_module.addSystemIncludePath(.{ .cwd_relative = androidArchIncludePath });
raylib.root_module.addSystemIncludePath(.{ .cwd_relative = androidAsmPath });
raylib.root_module.addSystemIncludePath(.{ .cwd_relative = androidGluePath });
var libcData: std.ArrayList(u8) = .empty;
var aw: std.Io.Writer.Allocating = .fromArrayList(b.allocator, &libcData);
try (std.zig.LibCInstallation{
.include_dir = androidIncludePath,
.sys_include_dir = androidIncludePath,
.crt_dir = androidApiSpecificPath,
}).render(&aw.writer);
const libcFile = b.addWriteFiles().add("android-libc.txt", try libcData.toOwnedSlice(b.allocator));
raylib.setLibCFile(libcFile);
if (options.opengl_version == .auto) {
raylib.root_module.linkSystemLibrary("GLESv2", .{});
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
}
raylib.root_module.linkSystemLibrary("EGL", .{});
setDesktopPlatform(raylib, .android);
} else {
try c_source_files.append(b.allocator, "src/rglfw.c");
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) { if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
raylib.defineCMacro("_GLFW_X11", null); raylib.root_module.addCMacro("_GLFW_X11", "");
raylib.linkSystemLibrary("GLX"); raylib.root_module.linkSystemLibrary("GLX", .{});
raylib.linkSystemLibrary("X11"); raylib.root_module.linkSystemLibrary("X11", .{});
raylib.linkSystemLibrary("Xcursor"); raylib.root_module.linkSystemLibrary("Xcursor", .{});
raylib.linkSystemLibrary("Xext"); raylib.root_module.linkSystemLibrary("Xext", .{});
raylib.linkSystemLibrary("Xfixes"); raylib.root_module.linkSystemLibrary("Xfixes", .{});
raylib.linkSystemLibrary("Xi"); raylib.root_module.linkSystemLibrary("Xi", .{});
raylib.linkSystemLibrary("Xinerama"); raylib.root_module.linkSystemLibrary("Xinerama", .{});
raylib.linkSystemLibrary("Xrandr"); raylib.root_module.linkSystemLibrary("Xrandr", .{});
raylib.linkSystemLibrary("Xrender"); raylib.root_module.linkSystemLibrary("Xrender", .{});
} }
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) { if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
@ -211,10 +330,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
, .{}); , .{});
@panic("`wayland-scanner` not found"); @panic("`wayland-scanner` not found");
}; };
raylib.defineCMacro("_GLFW_WAYLAND", null); raylib.root_module.addCMacro("_GLFW_WAYLAND", "");
raylib.linkSystemLibrary("EGL"); raylib.root_module.linkSystemLibrary("EGL", .{});
raylib.linkSystemLibrary("wayland-client"); raylib.root_module.linkSystemLibrary("wayland-client", .{});
raylib.linkSystemLibrary("xkbcommon"); raylib.root_module.linkSystemLibrary("xkbcommon", .{});
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol"); waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol"); waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol"); waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
@ -225,74 +344,51 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol"); waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol");
waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol"); waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol");
} }
setDesktopPlatform(raylib, options.platform); setDesktopPlatform(raylib, options.platform);
} else {
if (options.opengl_version == .auto) {
raylib.linkSystemLibrary("GLESv2");
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null);
}
raylib.linkSystemLibrary("EGL");
raylib.linkSystemLibrary("gbm");
raylib.linkSystemLibrary2("libdrm", .{ .use_pkg_config = .force });
raylib.defineCMacro("PLATFORM_DRM", null);
raylib.defineCMacro("EGL_NO_X11", null);
raylib.defineCMacro("DEFAULT_BATCH_BUFFER_ELEMENT", "2048");
} }
}, },
.freebsd, .openbsd, .netbsd, .dragonfly => { .freebsd, .openbsd, .netbsd, .dragonfly => {
try c_source_files.append("rglfw.c"); try c_source_files.append(b.allocator, "rglfw.c");
raylib.linkSystemLibrary("GL"); raylib.root_module.linkSystemLibrary("GL", .{});
raylib.linkSystemLibrary("rt"); raylib.root_module.linkSystemLibrary("rt", .{});
raylib.linkSystemLibrary("dl"); raylib.root_module.linkSystemLibrary("dl", .{});
raylib.linkSystemLibrary("m"); raylib.root_module.linkSystemLibrary("m", .{});
raylib.linkSystemLibrary("X11"); raylib.root_module.linkSystemLibrary("X11", .{});
raylib.linkSystemLibrary("Xrandr"); raylib.root_module.linkSystemLibrary("Xrandr", .{});
raylib.linkSystemLibrary("Xinerama"); raylib.root_module.linkSystemLibrary("Xinerama", .{});
raylib.linkSystemLibrary("Xi"); raylib.root_module.linkSystemLibrary("Xi", .{});
raylib.linkSystemLibrary("Xxf86vm"); raylib.root_module.linkSystemLibrary("Xxf86vm", .{});
raylib.linkSystemLibrary("Xcursor"); raylib.root_module.linkSystemLibrary("Xcursor", .{});
setDesktopPlatform(raylib, options.platform); setDesktopPlatform(raylib, options.platform);
}, },
.macos => { .macos => {
// Include xcode_frameworks for cross compilation // Include xcode_frameworks for cross compilation
if (b.lazyDependency("xcode_frameworks", .{})) |dep| { if (b.lazyDependency("xcode_frameworks", .{})) |dep| {
raylib.addSystemFrameworkPath(dep.path("Frameworks")); raylib.root_module.addSystemFrameworkPath(dep.path("Frameworks"));
raylib.addSystemIncludePath(dep.path("include")); raylib.root_module.addSystemIncludePath(dep.path("include"));
raylib.addLibraryPath(dep.path("lib")); raylib.root_module.addLibraryPath(dep.path("lib"));
} }
// On macos rglfw.c include Objective-C files. // On macos rglfw.c include Objective-C files.
try raylib_flags_arr.append("-ObjC"); try raylib_flags_arr.append(b.allocator, "-ObjC");
raylib.root_module.addCSourceFile(.{ raylib.root_module.addCSourceFile(.{
.file = b.path("src/rglfw.c"), .file = b.path("src/rglfw.c"),
.flags = raylib_flags_arr.items, .flags = raylib_flags_arr.items,
}); });
_ = raylib_flags_arr.pop(); _ = raylib_flags_arr.pop();
raylib.linkFramework("Foundation"); raylib.root_module.linkFramework("Foundation", .{});
raylib.linkFramework("CoreServices"); raylib.root_module.linkFramework("CoreServices", .{});
raylib.linkFramework("CoreGraphics"); raylib.root_module.linkFramework("CoreGraphics", .{});
raylib.linkFramework("AppKit"); raylib.root_module.linkFramework("AppKit", .{});
raylib.linkFramework("IOKit"); raylib.root_module.linkFramework("IOKit", .{});
setDesktopPlatform(raylib, options.platform); setDesktopPlatform(raylib, options.platform);
}, },
.emscripten => { .emscripten => {
// Include emscripten for cross compilation raylib.root_module.addCMacro("PLATFORM_WEB", "");
if (b.lazyDependency("emsdk", .{})) |dep| {
if (try emSdkSetupStep(b, dep)) |emSdkStep| {
raylib.step.dependOn(&emSdkStep.step);
}
raylib.addIncludePath(dep.path("upstream/emscripten/cache/sysroot/include"));
}
raylib.defineCMacro("PLATFORM_WEB", null);
if (options.opengl_version == .auto) { if (options.opengl_version == .auto) {
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null); raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES3", "");
} }
}, },
else => { else => {
@ -308,15 +404,15 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
return raylib; return raylib;
} }
pub fn addRaygui(b: *std.Build, raylib: *std.Build.Step.Compile, raygui_dep: *std.Build.Dependency) void { pub fn addRaygui(b: *std.Build, raylib: *std.Build.Step.Compile, raygui_dep: *std.Build.Dependency, options: Options) void {
const raylib_dep = b.dependencyFromBuildZig(@This(), .{}); const raylib_dep = b.dependencyFromBuildZig(@This(), options);
var gen_step = b.addWriteFiles(); var gen_step = b.addWriteFiles();
raylib.step.dependOn(&gen_step.step); raylib.step.dependOn(&gen_step.step);
const raygui_c_path = gen_step.add("raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n"); const raygui_c_path = gen_step.add("raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n");
raylib.addCSourceFile(.{ .file = raygui_c_path }); raylib.root_module.addCSourceFile(.{ .file = raygui_c_path });
raylib.addIncludePath(raygui_dep.path("src")); raylib.root_module.addIncludePath(raygui_dep.path("src"));
raylib.addIncludePath(raylib_dep.path("src")); raylib.root_module.addIncludePath(raylib_dep.path("src"));
raylib.installHeader(raygui_dep.path("src/raygui.h"), "raygui.h"); raylib.installHeader(raygui_dep.path("src/raygui.h"), "raygui.h");
} }
@ -328,9 +424,11 @@ pub const Options = struct {
rtext: bool = true, rtext: bool = true,
rtextures: bool = true, rtextures: bool = true,
platform: PlatformBackend = .glfw, platform: PlatformBackend = .glfw,
shared: bool = false, linkage: std.builtin.LinkMode = .static,
linux_display_backend: LinuxDisplayBackend = .Both, linux_display_backend: LinuxDisplayBackend = .X11,
opengl_version: OpenglVersion = .auto, opengl_version: OpenglVersion = .auto,
android_ndk: []const u8 = "",
android_api_version: []const u8 = "35",
/// config should be a list of space-separated cflags, eg, "-DSUPPORT_CUSTOM_FRAME_CONTROL" /// config should be a list of space-separated cflags, eg, "-DSUPPORT_CUSTOM_FRAME_CONTROL"
config: []const u8 = &.{}, config: []const u8 = &.{},
@ -344,10 +442,12 @@ pub const Options = struct {
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext, .rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
.rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures, .rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures,
.rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes, .rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes,
.shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared, .linkage = b.option(std.builtin.LinkMode, "linkage", "Compile as shared or static library") orelse defaults.linkage,
.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_api_version = b.option([]const u8, "android_api_version", "specify target android API level") orelse defaults.android_api_version,
}; };
} }
}; };
@ -385,26 +485,170 @@ pub const PlatformBackend = enum {
rgfw, rgfw,
sdl, sdl,
drm, drm,
android,
}; };
pub fn build(b: *std.Build) !void { pub fn build(b: *std.Build) !void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
// Standard optimization options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
// set a preferred release mode, allowing the user to decide how to optimize.
const optimize = b.standardOptimizeOption(.{}); const optimize = b.standardOptimizeOption(.{});
const lib = try compileRaylib(b, target, optimize, Options.getOptions(b)); const lib = try compileRaylib(b, target, optimize, Options.getOptions(b));
lib.installHeader(b.path("src/raylib.h"), "raylib.h"); lib.installHeader(b.path("src/raylib.h"), "raylib.h");
lib.installHeader(b.path("src/rcamera.h"), "rcamera.h");
lib.installHeader(b.path("src/raymath.h"), "raymath.h"); lib.installHeader(b.path("src/raymath.h"), "raymath.h");
lib.installHeader(b.path("src/rlgl.h"), "rlgl.h"); lib.installHeader(b.path("src/rlgl.h"), "rlgl.h");
b.installArtifact(lib); b.installArtifact(lib);
const examples = b.step("examples", "Build/Install all examples");
examples.dependOn(try addExamples("audio", b, target, optimize, lib));
examples.dependOn(try addExamples("core", b, target, optimize, lib));
examples.dependOn(try addExamples("models", b, target, optimize, lib));
examples.dependOn(try addExamples("others", b, target, optimize, lib));
examples.dependOn(try addExamples("shaders", b, target, optimize, lib));
examples.dependOn(try addExamples("shapes", b, target, optimize, lib));
examples.dependOn(try addExamples("text", b, target, optimize, lib));
examples.dependOn(try addExamples("textures", b, target, optimize, lib));
}
fn addExamples(
comptime module: []const u8,
b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
raylib: *std.Build.Step.Compile,
) !*std.Build.Step {
const all = b.step(module, "All " ++ module ++ " examples");
const module_subpath = b.pathJoin(&.{ "examples", module });
var dir = try std.fs.cwd().openDir(b.pathFromRoot(module_subpath), .{ .iterate = true });
defer dir.close();
var iter = dir.iterate();
while (try iter.next()) |entry| {
if (entry.kind != .file) continue;
const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue;
const name = entry.name[0..extension_idx];
const path = b.pathJoin(&.{ module_subpath, entry.name });
// 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;
const exe_mod = b.createModule(.{
.target = target,
.optimize = optimize,
});
exe_mod.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
exe_mod.linkLibrary(raylib);
const run_step = b.step(name, name);
if (target.result.os.tag == .emscripten) {
const wasm = b.addLibrary(.{
.name = name,
.linkage = .static,
.root_module = exe_mod,
});
if (std.mem.eql(u8, name, "rlgl_standalone")) {
//TODO: Make rlgl_standalone example work
continue;
}
if (std.mem.eql(u8, name, "raylib_opengl_interop")) {
//TODO: Make raylib_opengl_interop example work
continue;
}
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize });
const emcc_settings = emsdk.emccDefaultSettings(b.allocator, .{ .optimize = optimize });
const install_dir: std.Build.InstallDir = .{ .custom = "htmlout" };
const emcc_step = emsdk.emccStep(b, raylib, wasm, .{
.optimize = optimize,
.flags = emcc_flags,
.settings = emcc_settings,
.shell_file_path = b.path("src/shell.html"),
.embed_paths = &.{
.{
.src_path = b.pathJoin(&.{ module_subpath, "resources" }),
.virtual_path = "resources",
},
},
.install_dir = install_dir,
});
const html_filename = try std.fmt.allocPrint(b.allocator, "{s}.html", .{wasm.name});
const emrun_step = emsdk.emrunStep(
b,
b.getInstallPath(install_dir, html_filename),
&.{"--no_browser"},
);
emrun_step.dependOn(emcc_step);
run_step.dependOn(emrun_step);
all.dependOn(emcc_step);
} else {
// special examples that test using these external dependencies directly
// alongside raylib
if (std.mem.eql(u8, name, "rlgl_standalone")) {
exe_mod.addIncludePath(b.path("src"));
exe_mod.addIncludePath(b.path("src/external/glfw/include"));
if (!hasCSource(raylib.root_module, "rglfw.c")) {
exe_mod.addCSourceFile(.{ .file = b.path("src/rglfw.c"), .flags = &.{} });
}
}
if (std.mem.eql(u8, name, "raylib_opengl_interop")) {
exe_mod.addIncludePath(b.path("src/external"));
}
switch (target.result.os.tag) {
.windows => {
exe_mod.linkSystemLibrary("winmm", .{});
exe_mod.linkSystemLibrary("gdi32", .{});
exe_mod.linkSystemLibrary("opengl32", .{});
exe_mod.addCMacro("PLATFORM_DESKTOP", "");
},
.linux => {
exe_mod.linkSystemLibrary("GL", .{});
exe_mod.linkSystemLibrary("rt", .{});
exe_mod.linkSystemLibrary("dl", .{});
exe_mod.linkSystemLibrary("m", .{});
exe_mod.linkSystemLibrary("X11", .{});
exe_mod.addCMacro("PLATFORM_DESKTOP", "");
},
.macos => {
exe_mod.linkFramework("Foundation", .{});
exe_mod.linkFramework("Cocoa", .{});
exe_mod.linkFramework("OpenGL", .{});
exe_mod.linkFramework("CoreAudio", .{});
exe_mod.linkFramework("CoreVideo", .{});
exe_mod.linkFramework("IOKit", .{});
exe_mod.addCMacro("PLATFORM_DESKTOP", "");
},
else => {
@panic("Unsupported OS");
},
}
const exe = b.addExecutable(.{
.name = name,
.root_module = exe_mod,
});
const install_cmd = b.addInstallArtifact(exe, .{});
const run_cmd = b.addRunArtifact(exe);
run_cmd.cwd = b.path(module_subpath);
run_cmd.step.dependOn(&install_cmd.step);
run_step.dependOn(&run_cmd.step);
all.dependOn(&install_cmd.step);
}
}
return all;
} }
fn waylandGenerate( fn waylandGenerate(
@ -420,12 +664,24 @@ fn waylandGenerate(
const client_step = b.addSystemCommand(&.{ "wayland-scanner", "client-header" }); const client_step = b.addSystemCommand(&.{ "wayland-scanner", "client-header" });
client_step.addFileArg(b.path(protocolDir)); client_step.addFileArg(b.path(protocolDir));
raylib.addIncludePath(client_step.addOutputFileArg(clientHeader).dirname()); raylib.root_module.addIncludePath(client_step.addOutputFileArg(clientHeader).dirname());
const private_step = b.addSystemCommand(&.{ "wayland-scanner", "private-code" }); const private_step = b.addSystemCommand(&.{ "wayland-scanner", "private-code" });
private_step.addFileArg(b.path(protocolDir)); private_step.addFileArg(b.path(protocolDir));
raylib.addIncludePath(private_step.addOutputFileArg(privateCode).dirname()); raylib.root_module.addIncludePath(private_step.addOutputFileArg(privateCode).dirname());
raylib.step.dependOn(&client_step.step); raylib.step.dependOn(&client_step.step);
raylib.step.dependOn(&private_step.step); raylib.step.dependOn(&private_step.step);
} }
fn hasCSource(module: *std.Build.Module, name: []const u8) bool {
for (module.link_objects.items) |o| switch (o) {
.c_source_file => |c| if (switch (c.file) {
.src_path => |s| std.ascii.endsWithIgnoreCase(s.sub_path, name),
.generated, .cwd_relative, .dependency => false,
}) return true,
.c_source_files => |s| for (s.files) |c| if (std.ascii.endsWithIgnoreCase(c, name)) return true,
else => {},
};
return false;
}

View File

@ -1,18 +1,23 @@
.{ .{
.name = "raylib", .name = .raylib,
.version = "5.5.0", .version = "5.6.0-dev",
.minimum_zig_version = "0.13.0", .minimum_zig_version = "0.15.1",
.fingerprint = 0x13035e5cb8bc1ac2, // Changing this has security and trust implications.
.dependencies = .{ .dependencies = .{
.xcode_frameworks = .{ .xcode_frameworks = .{
.url = "git+https://github.com/hexops/xcode-frameworks#a6bf82e032d4d9923ad5c222d466710fcc05f249", .url = "git+https://github.com/hexops/xcode-frameworks#9a45f3ac977fd25dff77e58c6de1870b6808c4a7",
.hash = "12208da4dfcd9b53fb367375fb612ec73f38e53015f1ce6ae6d6e8437a637078e170", .hash = "N-V-__8AABHMqAWYuRdIlflwi8gksPnlUMQBiSxAqQAAZFms",
.lazy = true, .lazy = true,
}, },
.emsdk = .{ .emsdk = .{
.url = "git+https://github.com/emscripten-core/emsdk#3.1.50", .url = "git+https://github.com/emscripten-core/emsdk#4.0.9",
.hash = "1220e8fe9509f0843e5e22326300ca415c27afbfbba3992f3c3184d71613540b5564", .hash = "N-V-__8AAJl1DwBezhYo_VE6f53mPVm00R-Fk28NPW7P14EQ",
.lazy = true, },
.zemscripten = .{
.url = "git+https://github.com/zig-gamedev/zemscripten#3fa4b778852226c7346bdcc3c1486e875a9a6d02",
.hash = "zemscripten-0.2.0-dev-sRlDqApRAACspTbAZnuNKWIzfWzSYgYkb2nWAXZ-tqqt",
}, },
}, },
@ -20,5 +25,7 @@
"build.zig", "build.zig",
"build.zig.zon", "build.zig.zon",
"src", "src",
"examples",
"LICENSE",
}, },
} }

View File

@ -19,9 +19,18 @@ join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}") join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(../raylib.pc.in raylib.pc @ONLY) configure_file(../raylib.pc.in raylib.pc @ONLY)
configure_file(../cmake/raylib-config-version.cmake raylib-config-version.cmake @ONLY) configure_file(../cmake/raylib-config-version.cmake raylib-config-version.cmake @ONLY)
configure_file(../cmake/raylib-config.cmake raylib-config.cmake @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
install(FILES ${PROJECT_SOURCE_DIR}/../cmake/raylib-config.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib") install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/raylib-config.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/raylib
)
install(EXPORT raylib-targets
FILE raylib-targets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/raylib
)
# populates raylib_{FOUND, INCLUDE_DIRS, LIBRARIES, LDFLAGS, DEFINITIONS} # populates raylib_{FOUND, INCLUDE_DIRS, LIBRARIES, LDFLAGS, DEFINITIONS}
include(PopulateConfigVariablesLocally) include(PopulateConfigVariablesLocally)

View File

@ -7,6 +7,8 @@ if(POLICY CMP0072)
cmake_policy(SET CMP0072 NEW) cmake_policy(SET CMP0072 NEW)
endif() endif()
set(RAYLIB_DEPENDENCIES "include(CMakeFindDependencyMacro)")
if (${PLATFORM} MATCHES "Desktop") if (${PLATFORM} MATCHES "Desktop")
set(PLATFORM_CPP "PLATFORM_DESKTOP") set(PLATFORM_CPP "PLATFORM_DESKTOP")
@ -69,6 +71,14 @@ elseif (${PLATFORM} MATCHES "Android")
set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON)
list(APPEND raylib_sources ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) list(APPEND raylib_sources ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
include_directories(${ANDROID_NDK}/sources/android/native_app_glue) include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
# NOTE: We remove '-Wl,--no-undefined' (set by default) as it conflicts with '-Wl,-undefined,dynamic_lookup' needed
# for compiling with the missing 'void main(void)' declaration in `android_main()`.
# We also remove other unnecessary or problematic flags.
string(REPLACE "-Wl,--no-undefined -Qunused-arguments" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
string(REPLACE "-static-libstdc++" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup")
find_library(OPENGL_LIBRARY OpenGL) find_library(OPENGL_LIBRARY OpenGL)
@ -93,10 +103,39 @@ elseif ("${PLATFORM}" MATCHES "DRM")
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread m dl) set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread m dl)
elseif ("${PLATFORM}" MATCHES "SDL") elseif ("${PLATFORM}" MATCHES "SDL")
find_package(SDL2 REQUIRED) # First, check if SDL is included as a subdirectory
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL") if(TARGET SDL3::SDL3)
set(LIBS_PRIVATE SDL2::SDL2) message(STATUS "Using SDL3 from subdirectory")
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
set(LIBS_PRIVATE SDL3::SDL3)
add_compile_definitions(USING_SDL3_PROJECT)
elseif(TARGET SDL2::SDL2)
message(STATUS "Using SDL2 from subdirectory")
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
set(LIBS_PRIVATE SDL2::SDL2)
add_compile_definitions(USING_SDL2_PROJECT)
else()
# No SDL added via add_subdirectory(), try find_package()
message(STATUS "No SDL target from subdirectory, searching via find_package()...")
# First try SDL3
find_package(SDL3 QUIET)
if(SDL3_FOUND)
message(STATUS "Found SDL3 via find_package()")
set(LIBS_PUBLIC SDL3::SDL3)
set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL3 REQUIRED)")
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
add_compile_definitions(USING_SDL3_PACKAGE)
else()
# Fallback to SDL2
find_package(SDL2 REQUIRED)
message(STATUS "Found SDL2 via find_package()")
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
set(LIBS_PUBLIC SDL2::SDL2)
set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL3 REQUIRED)")
add_compile_definitions(USING_SDL2_PACKAGE)
endif()
endif()
endif () endif ()
if (NOT ${OPENGL_VERSION} MATCHES "OFF") if (NOT ${OPENGL_VERSION} MATCHES "OFF")

View File

@ -1,79 +1,4 @@
# - Try to find raylib @PACKAGE_INIT@
# Options: @RAYLIB_DEPENDENCIES@
# raylib_USE_STATIC_LIBS - OFF by default
# raylib_VERBOSE - OFF by default
# Once done, this defines a raylib target that can be passed to
# target_link_libraries as well as following variables:
#
# raylib_FOUND - System has raylib installed
# raylib_INCLUDE_DIRS - The include directories for the raylib header(s)
# raylib_LIBRARIES - The libraries needed to use raylib
# raylib_LDFLAGS - The linker flags needed with raylib
# raylib_DEFINITIONS - Compiler switches required for using raylib
if (NOT TARGET raylib) include("${CMAKE_CURRENT_LIST_DIR}/raylib-targets.cmake")
set(XPREFIX PC_RAYLIB)
find_package(PkgConfig QUIET)
pkg_check_modules(${XPREFIX} QUIET raylib)
if (raylib_USE_STATIC_LIBS)
set(XPREFIX ${XPREFIX}_STATIC)
endif()
set(raylib_DEFINITIONS ${${XPREFIX}_CFLAGS})
find_path(raylib_INCLUDE_DIR
NAMES raylib.h
HINTS ${${XPREFIX}_INCLUDE_DIRS}
)
set(RAYLIB_NAMES raylib)
if (raylib_USE_STATIC_LIBS)
set(RAYLIB_NAMES libraylib.a raylib.lib ${RAYLIB_NAMES})
endif()
find_library(raylib_LIBRARY
NAMES ${RAYLIB_NAMES}
HINTS ${${XPREFIX}_LIBRARY_DIRS}
)
set(raylib_LIBRARIES ${raylib_LIBRARY})
set(raylib_LIBRARY_DIRS ${${XPREFIX}_LIBRARY_DIRS})
set(raylib_LIBRARY_DIR ${raylib_LIBRARY_DIRS})
set(raylib_INCLUDE_DIRS ${raylib_INCLUDE_DIR})
set(raylib_LDFLAGS ${${XPREFIX}_LDFLAGS})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(raylib DEFAULT_MSG
raylib_LIBRARY
raylib_INCLUDE_DIR
)
mark_as_advanced(raylib_LIBRARY raylib_INCLUDE_DIR)
if (raylib_USE_STATIC_LIBS)
add_library(raylib STATIC IMPORTED GLOBAL)
else()
add_library(raylib SHARED IMPORTED GLOBAL)
endif()
string (REPLACE ";" " " raylib_LDFLAGS "${raylib_LDFLAGS}")
set_target_properties(raylib
PROPERTIES
IMPORTED_LOCATION "${raylib_LIBRARIES}"
IMPORTED_IMPLIB "${raylib_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${raylib_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${raylib_LDFLAGS}"
INTERFACE_COMPILE_OPTIONS "${raylib_DEFINITIONS}"
)
if (raylib_VERBOSE)
message(STATUS "raylib_FOUND: ${raylib_FOUND}")
message(STATUS "raylib_INCLUDE_DIRS: ${raylib_INCLUDE_DIRS}")
message(STATUS "raylib_LIBRARIES: ${raylib_LIBRARIES}")
message(STATUS "raylib_LDFLAGS: ${raylib_LDFLAGS}")
message(STATUS "raylib_DEFINITIONS: ${raylib_DEFINITIONS}")
endif()
endif()

View File

@ -90,23 +90,16 @@ if (${PLATFORM} MATCHES "Android")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_custom_uniform.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_custom_uniform.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_view_depth.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_postprocessing.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_postprocessing.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_raymarching.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_raymarching.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_palette_switch.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_palette_switch.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c)
elseif (${PLATFORM} MATCHES "Web") elseif (${PLATFORM} MATCHES "Web")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os") set(example_sources) # clear example_sources
# Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads list(APPEND example_sources others/web_basic_window.c)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1 -s ASYNCIFY -s ALLOW_MEMORY_GROWTH=1 --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html") list(APPEND example_sources core/core_input_gestures_testbed.c)
set(CMAKE_EXECUTABLE_SUFFIX ".html")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
# Remove the -rdynamic flag because otherwise emscripten
# does not generate HTML+JS+WASM files, only a non-working
# and fat HTML
string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}")
elseif ("${PLATFORM}" STREQUAL "DRM") elseif ("${PLATFORM}" STREQUAL "DRM")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
@ -124,7 +117,21 @@ endif ()
# The rlgl_standalone example only targets desktop, without shared libraries. # The rlgl_standalone example only targets desktop, without shared libraries.
if (BUILD_SHARED_LIBS OR NOT ${PLATFORM} MATCHES "Desktop") if (BUILD_SHARED_LIBS OR NOT ${PLATFORM} MATCHES "Desktop")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
endif()
# The audio examples fail to link if raylib is built without raudio
if (NOT SUPPORT_MODULE_RAUDIO)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_mixed_processor.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_module_playing.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_music_stream.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_raw_stream.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_sound_loading.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_sound_multi.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_stream_effects.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/embedded_files_loading.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_sprite_button.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_sprite_explosion.c)
endif() endif()
include_directories(BEFORE SYSTEM others/external/include) include_directories(BEFORE SYSTEM others/external/include)
@ -150,10 +157,34 @@ foreach (example_source ${example_sources})
string(REGEX MATCH ".*/.*/" resources_dir ${example_source}) string(REGEX MATCH ".*/.*/" resources_dir ${example_source})
string(APPEND resources_dir "resources") string(APPEND resources_dir "resources")
if (${PLATFORM} MATCHES "Web" AND EXISTS ${resources_dir}) if (${PLATFORM} MATCHES "Web")
# The local resources path needs to be mapped to /resources virtual path target_compile_options(${example_name} PRIVATE -Os)
string(APPEND resources_dir "@resources") target_link_options(${example_name} PRIVATE
set_target_properties(${example_name} PROPERTIES LINK_FLAGS "--preload-file ${resources_dir}") -sALLOW_MEMORY_GROWTH=1
-sEXPORTED_RUNTIME_METHODS=[requestFullscreen]
-sUSE_GLFW=3
--shell-file "${CMAKE_SOURCE_DIR}/src/shell.html"
)
set_target_properties(${example_name} PROPERTIES SUFFIX ".html")
if (EXISTS ${resources_dir})
# The local resources path needs to be mapped to /resources virtual path
string(APPEND resources_dir "@resources")
set_target_properties(${example_name} PROPERTIES LINK_FLAGS "--preload-file ${resources_dir}")
endif ()
if(${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES3")
target_link_options(${example_name} PUBLIC "-sMIN_WEBGL_VERSION=2")
target_link_options(${example_name} PUBLIC "-sMAX_WEBGL_VERSION=2")
endif()
# Checks if OSX and links appropriate frameworks (Only required on MacOS)
if (APPLE)
target_link_libraries(${example_name} "-framework IOKit")
target_link_libraries(${example_name} "-framework Cocoa")
target_link_libraries(${example_name} "-framework OpenGL")
endif()
endif () endif ()
endforeach () endforeach ()

View File

@ -20,6 +20,8 @@
# - Linux (X11 desktop mode) # - Linux (X11 desktop mode)
# - macOS/OSX (x64, arm64 (not tested)) # - macOS/OSX (x64, arm64 (not tested))
# - Others (not tested) # - Others (not tested)
# > PLATFORM_WEB_RGFW:
# - HTML5 (WebAssembly)
# > PLATFORM_WEB: # > PLATFORM_WEB:
# - HTML5 (WebAssembly) # - HTML5 (WebAssembly)
# > PLATFORM_DRM: # > PLATFORM_DRM:
@ -28,7 +30,7 @@
# > PLATFORM_ANDROID: # > PLATFORM_ANDROID:
# - Android (ARM, ARM64) # - Android (ARM, ARM64)
# #
# Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2025 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.
@ -51,13 +53,18 @@
# Define required environment variables # Define required environment variables
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
# Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB # Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB, PLATFORM_WEB_RGFW
PLATFORM ?= PLATFORM_DESKTOP PLATFORM ?= PLATFORM_DESKTOP
ifeq ($(PLATFORM), PLATFORM_DESKTOP) ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW))
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW TARGET_PLATFORM := $(PLATFORM)
override PLATFORM = PLATFORM_DESKTOP
else else
TARGET_PLATFORM = $(PLATFORM) ifeq ($(PLATFORM), PLATFORM_DESKTOP)
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW
else
TARGET_PLATFORM = $(PLATFORM)
endif
endif endif
# Define required raylib variables # Define required raylib variables
@ -89,7 +96,6 @@ SDL_INCLUDE_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/include
SDL_LIBRARY_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/lib SDL_LIBRARY_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/lib
SDL_LIBRARIES ?= -lSDL2 -lSDL2main SDL_LIBRARIES ?= -lSDL2 -lSDL2main
# Use Wayland display server protocol on Linux desktop (by default it uses X11 windowing system) # Use Wayland display server protocol on Linux desktop (by default it uses X11 windowing system)
# NOTE: This variable is only used for PLATFORM_OS: LINUX # NOTE: This variable is only used for PLATFORM_OS: LINUX
USE_WAYLAND_DISPLAY ?= FALSE USE_WAYLAND_DISPLAY ?= FALSE
@ -100,9 +106,12 @@ BUILD_WEB_SHELL ?= $(RAYLIB_PATH)/src/minshell.html
BUILD_WEB_HEAP_SIZE ?= 134217728 BUILD_WEB_HEAP_SIZE ?= 134217728
BUILD_WEB_RESOURCES ?= TRUE BUILD_WEB_RESOURCES ?= TRUE
BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources
# Use WebGL2 backend (OpenGL 3.0)
# WARNING: Requires raylib compiled with GRAPHICS_API_OPENGL_ES3
BUILD_WEB_WEBGL2 ?= FALSE
# Determine PLATFORM_OS when required # Determine PLATFORM_OS when required
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB)) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW PLATFORM_WEB PLATFORM_WEB_RGFW))
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! # No uname.exe on MinGW!, but OS=Windows_NT on Windows!
# ifeq ($(UNAME),Msys) -> Windows # ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
@ -153,7 +162,7 @@ endif
# Define raylib release directory for compiled library # Define raylib release directory for compiled library
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
# Emscripten required variables # Emscripten required variables
EMSDK_PATH ?= C:/raylib/emsdk EMSDK_PATH ?= C:/raylib/emsdk
@ -179,7 +188,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
CC = clang CC = clang
endif endif
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
# HTML5 emscripten compiler # HTML5 emscripten compiler
# WARNING: To compile to HTML5, code must be redesigned # WARNING: To compile to HTML5, code must be redesigned
# to use emscripten.h and emscripten_set_main_loop() # to use emscripten.h and emscripten_set_main_loop()
@ -198,7 +207,7 @@ endif
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
MAKE = mingw32-make MAKE = mingw32-make
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
MAKE = mingw32-make MAKE = mingw32-make
else else
@ -226,11 +235,8 @@ CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result
ifeq ($(BUILD_MODE),DEBUG) ifeq ($(BUILD_MODE),DEBUG)
CFLAGS += -g -D_DEBUG CFLAGS += -g -D_DEBUG
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
CFLAGS += -sASSERTIONS=1 --profiling
endif
else else
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(BUILD_WEB_ASYNCIFY),TRUE) ifeq ($(BUILD_WEB_ASYNCIFY),TRUE)
CFLAGS += -O3 CFLAGS += -O3
else else
@ -266,8 +272,8 @@ endif
# NOTE: Some external/extras libraries could be required (stb, easings...) # NOTE: Some external/extras libraries could be required (stb, easings...)
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external $(EXTRA_INCLUDE_PATHS) INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external $(EXTRA_INCLUDE_PATHS)
# Define additional directories containing required header files
# Define additional directories containing required header files
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW) ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
ifeq ($(PLATFORM_OS),BSD) ifeq ($(PLATFORM_OS),BSD)
INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) -I/usr/pkg/include -I/usr/X11R7/include INCLUDE_PATHS += -I$(RAYLIB_INCLUDE_PATH) -I/usr/pkg/include -I/usr/X11R7/include
@ -284,11 +290,6 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
INCLUDE_PATHS += -I/usr/include/libdrm INCLUDE_PATHS += -I/usr/include/libdrm
endif endif
# Include GLFW required for examples/others/rlgl_standalone.c
ifeq ($(USE_EXTERNAL_GLFW),FALSE)
all others: INCLUDE_PATHS += -I$(RAYLIB_PATH)/src/external/glfw/include
endif
# Define library paths containing required libs: LDFLAGS # Define library paths containing required libs: LDFLAGS
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
@ -320,29 +321,41 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
endif endif
LDFLAGS += -L$(SDL_LIBRARY_PATH) LDFLAGS += -L$(SDL_LIBRARY_PATH)
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
# -Os # size optimization # -Os # size optimization
# -O2 # optimization level 2, if used, also set --memory-init-file 0 # -O2 # optimization level 2, if used, also set --memory-init-file 0
# -sUSE_GLFW=3 # Use glfw3 library (context/input management) # -sUSE_GLFW=3 # Use glfw3 library (context/input management)
# -sALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL! # -sALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL!
# -sTOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) (67108864 = 64MB) # -sTOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) (67108864 = 64MB)
# -sUSE_PTHREADS=1 # multithreading support # -sUSE_PTHREADS=1 # multithreading support
# -sWASM=0 # disable Web Assembly, emitted by default # -sWASM=0 # disable Web Assembly, emitted by default
# -sASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS # -sASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS
# -sFORCE_FILESYSTEM=1 # force filesystem to load/save files data # -sFORCE_FILESYSTEM=1 # force filesystem to load/save files data
# -sASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off) # -sASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off)
# -sGL_ENABLE_GET_PROC_ADDRESS # enable using the *glGetProcAddress() family of functions, required for extensions loading # -sMINIFY_HTML=0 # minify generated html from shell.html
# --profiling # include information for code profiling # --profiling # include information for code profiling
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem) # --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
# --preload-file resources # specify a resources folder for data compilation # --preload-file resources # specify a resources folder for data compilation
# --source-map-base # allow debugging in browser with source map # --source-map-base # allow debugging in browser with source map
LDFLAGS += -sUSE_GLFW=3 -sTOTAL_MEMORY=$(BUILD_WEB_HEAP_SIZE) -sFORCE_FILESYSTEM=1 # --shell-file shell.html # define a custom shell .html and output extension
LDFLAGS += -sTOTAL_MEMORY=$(BUILD_WEB_HEAP_SIZE) -sFORCE_FILESYSTEM=1 -sEXPORTED_RUNTIME_METHODS=ccall -sMINIFY_HTML=0
# Using GLFW3 library (instead of RGFW)
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
LDFLAGS += -sUSE_GLFW=3
endif
# Build using asyncify # Build using asyncify
ifeq ($(BUILD_WEB_ASYNCIFY),TRUE) ifeq ($(BUILD_WEB_ASYNCIFY),TRUE)
LDFLAGS += -sASYNCIFY LDFLAGS += -sASYNCIFY
endif endif
# NOTE: Flags required for WebGL 2.0 (OpenGL ES 3.0)
# WARNING: Requires raylib compiled with GRAPHICS_API_OPENGL_ES3
ifeq ($(BUILD_WEB_WEBGL2),TRUE)
LDFLAGS += -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2
endif
# Add resources building if required # Add resources building if required
ifeq ($(BUILD_WEB_RESOURCES),TRUE) ifeq ($(BUILD_WEB_RESOURCES),TRUE)
LDFLAGS += --preload-file $(BUILD_WEB_RESOURCES_PATH) LDFLAGS += --preload-file $(BUILD_WEB_RESOURCES_PATH)
@ -467,7 +480,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
# NOTE: Required packages: libegl1-mesa-dev # NOTE: Required packages: libegl1-mesa-dev
LDFLAGS += -L../src LDFLAGS += -L../src
LDLIBS = -lraylib -lm LDLIBS = -lraylib -lm
LDLIBS += -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo LDLIBS += -framework Foundation -framework AppKit -framework IOKit -framework OpenGL -framework CoreVideo
endif endif
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM) ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
@ -475,19 +488,23 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
# 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 -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
# Libraries for web (HTML5) compiling # Libraries for web (HTML5) compiling
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.a LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.web.a
endif endif
CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
# Define source code object files required # Define source code object files required
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
#EXAMPLES_LIST_START
CORE = \ CORE = \
core/core_2d_camera \ core/core_2d_camera \
core/core_2d_camera_mouse_zoom \ core/core_2d_camera_mouse_zoom \
core/core_2d_camera_platformer \ core/core_2d_camera_platformer \
core/core_2d_camera_split_screen \ core/core_2d_camera_split_screen \
core/core_3d_camera_first_person \ core/core_3d_camera_first_person \
core/core_3d_camera_fps \
core/core_3d_camera_free \ core/core_3d_camera_free \
core/core_3d_camera_mode \ core/core_3d_camera_mode \
core/core_3d_camera_split_screen \ core/core_3d_camera_split_screen \
@ -495,25 +512,25 @@ CORE = \
core/core_automation_events \ core/core_automation_events \
core/core_basic_screen_manager \ core/core_basic_screen_manager \
core/core_basic_window \ core/core_basic_window \
core/core_basic_window_web \
core/core_custom_frame_control \ core/core_custom_frame_control \
core/core_custom_logging \ core/core_custom_logging \
core/core_drop_files \ core/core_drop_files \
core/core_high_dpi \
core/core_input_gamepad \ core/core_input_gamepad \
core/core_input_gamepad_info \
core/core_input_gestures \ core/core_input_gestures \
core/core_input_gestures_web \ core/core_input_gestures_testbed \
core/core_input_keys \ core/core_input_keys \
core/core_input_mouse \ core/core_input_mouse \
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_loading_thread \
core/core_random_sequence \ core/core_random_sequence \
core/core_random_values \ core/core_random_values \
core/core_render_texture \
core/core_scissor_test \ core/core_scissor_test \
core/core_smooth_pixelperfect \ core/core_smooth_pixelperfect \
core/core_storage_values \ core/core_storage_values \
core/core_undo_redo \
core/core_vr_simulator \ core/core_vr_simulator \
core/core_window_flags \ core/core_window_flags \
core/core_window_letterbox \ core/core_window_letterbox \
@ -523,28 +540,29 @@ CORE = \
SHAPES = \ SHAPES = \
shapes/shapes_basic_shapes \ shapes/shapes_basic_shapes \
shapes/shapes_bouncing_ball \ shapes/shapes_bouncing_ball \
shapes/shapes_circle_sector_drawing \
shapes/shapes_collision_area \ shapes/shapes_collision_area \
shapes/shapes_colors_palette \ shapes/shapes_colors_palette \
shapes/shapes_draw_circle_sector \ shapes/shapes_digital_clock \
shapes/shapes_draw_rectangle_rounded \ shapes/shapes_double_pendulum \
shapes/shapes_draw_ring \ shapes/shapes_easings_ball \
shapes/shapes_easings_ball_anim \ shapes/shapes_easings_box \
shapes/shapes_easings_box_anim \ shapes/shapes_easings_rectangles \
shapes/shapes_easings_rectangle_array \
shapes/shapes_following_eyes \ shapes/shapes_following_eyes \
shapes/shapes_lines_bezier \ shapes/shapes_lines_bezier \
shapes/shapes_logo_raylib \ shapes/shapes_logo_raylib \
shapes/shapes_logo_raylib_anim \ shapes/shapes_logo_raylib_anim \
shapes/shapes_rectangle_advanced \
shapes/shapes_rectangle_scaling \ shapes/shapes_rectangle_scaling \
shapes/shapes_ring_drawing \
shapes/shapes_rounded_rectangle_drawing \
shapes/shapes_splines_drawing \ shapes/shapes_splines_drawing \
shapes/shapes_top_down_lights \ shapes/shapes_top_down_lights
shapes/shapes_rectangle_advanced
TEXTURES = \ 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_draw_tiled \
textures/textures_fog_of_war \ textures/textures_fog_of_war \
textures/textures_gif_player \ textures/textures_gif_player \
textures/textures_image_channel \ textures/textures_image_channel \
@ -559,40 +577,43 @@ TEXTURES = \
textures/textures_mouse_painting \ textures/textures_mouse_painting \
textures/textures_npatch_drawing \ textures/textures_npatch_drawing \
textures/textures_particles_blending \ textures/textures_particles_blending \
textures/textures_polygon \ textures/textures_polygon_drawing \
textures/textures_raw_data \ textures/textures_raw_data \
textures/textures_sprite_anim \ textures/textures_sprite_animation \
textures/textures_sprite_button \ textures/textures_sprite_button \
textures/textures_sprite_explosion \ textures/textures_sprite_explosion \
textures/textures_srcrec_dstrec \ textures/textures_srcrec_dstrec \
textures/textures_textured_curve \ textures/textures_textured_curve \
textures/textures_tiled_drawing \
textures/textures_to_image textures/textures_to_image
TEXT = \ TEXT = \
text/text_3d_drawing \
text/text_codepoints_loading \ text/text_codepoints_loading \
text/text_draw_3d \
text/text_font_filters \ text/text_font_filters \
text/text_font_loading \ text/text_font_loading \
text/text_font_sdf \ text/text_font_sdf \
text/text_font_spritefont \ text/text_font_spritefont \
text/text_format_text \ text/text_format_text \
text/text_inline_styling \
text/text_input_box \ text/text_input_box \
text/text_raylib_fonts \
text/text_rectangle_bounds \ text/text_rectangle_bounds \
text/text_unicode \ text/text_sprite_fonts \
text/text_unicode_emojis \
text/text_unicode_ranges \
text/text_writing_anim text/text_writing_anim
MODELS = \ MODELS = \
models/models_animation \ models/models_animation_playing \
models/models_animation_blending \ models/models_animation_blending \
models/models_billboard \ models/models_billboard_rendering \
models/models_bone_socket \ models/models_bone_socket \
models/models_box_collisions \ models/models_box_collisions \
models/models_cubicmap \ models/models_cubicmap_rendering \
models/models_draw_cube_texture \
models/models_first_person_maze \ models/models_first_person_maze \
models/models_geometric_shapes \ models/models_geometric_shapes \
models/models_heightmap \ models/models_gpu_skinning \
models/models_heightmap_rendering \
models/models_loading \ models/models_loading \
models/models_loading_gltf \ models/models_loading_gltf \
models/models_loading_m3d \ models/models_loading_m3d \
@ -602,37 +623,41 @@ MODELS = \
models/models_orthographic_projection \ models/models_orthographic_projection \
models/models_point_rendering \ models/models_point_rendering \
models/models_rlgl_solar_system \ models/models_rlgl_solar_system \
models/models_skybox \ models/models_skybox_rendering \
models/models_tesseract_view \
models/models_textured_cube \
models/models_waving_cubes \ models/models_waving_cubes \
models/models_yaw_pitch_roll \ models/models_yaw_pitch_roll
models/models_gpu_skinning
SHADERS = \ SHADERS = \
shaders/shaders_basic_lighting \ shaders/shaders_basic_lighting \
shaders/shaders_basic_pbr \ shaders/shaders_basic_pbr \
shaders/shaders_custom_uniform \ shaders/shaders_custom_uniform \
shaders/shaders_deferred_render \ shaders/shaders_deferred_rendering \
shaders/shaders_eratosthenes \ shaders/shaders_depth_rendering \
shaders/shaders_fog \ shaders/shaders_depth_writing \
shaders/shaders_eratosthenes_sieve \
shaders/shaders_fog_rendering \
shaders/shaders_hot_reloading \ shaders/shaders_hot_reloading \
shaders/shaders_hybrid_render \ shaders/shaders_hybrid_rendering \
shaders/shaders_julia_set \ shaders/shaders_julia_set \
shaders/shaders_lightmap \ shaders/shaders_lightmap_rendering \
shaders/shaders_mesh_instancing \ shaders/shaders_mesh_instancing \
shaders/shaders_model_shader \ shaders/shaders_model_shader \
shaders/shaders_multi_sample2d \ shaders/shaders_multi_sample2d \
shaders/shaders_normalmap_rendering \
shaders/shaders_palette_switch \ shaders/shaders_palette_switch \
shaders/shaders_postprocessing \ shaders/shaders_postprocessing \
shaders/shaders_raymarching \ shaders/shaders_raymarching_rendering \
shaders/shaders_shadowmap \ shaders/shaders_rounded_rectangle \
shaders/shaders_shadowmap_rendering \
shaders/shaders_shapes_textures \ shaders/shaders_shapes_textures \
shaders/shaders_simple_mask \ shaders/shaders_simple_mask \
shaders/shaders_spotlight \ shaders/shaders_spotlight_rendering \
shaders/shaders_texture_drawing \
shaders/shaders_texture_outline \ shaders/shaders_texture_outline \
shaders/shaders_texture_rendering \
shaders/shaders_texture_tiling \ shaders/shaders_texture_tiling \
shaders/shaders_texture_waves \ shaders/shaders_texture_waves \
shaders/shaders_write_depth \
shaders/shaders_vertex_displacement shaders/shaders_vertex_displacement
AUDIO = \ AUDIO = \
@ -642,6 +667,7 @@ AUDIO = \
audio/audio_raw_stream \ audio/audio_raw_stream \
audio/audio_sound_loading \ audio/audio_sound_loading \
audio/audio_sound_multi \ audio/audio_sound_multi \
audio/audio_sound_positioning \
audio/audio_stream_effects audio/audio_stream_effects
OTHERS = \ OTHERS = \
@ -649,19 +675,14 @@ OTHERS = \
others/embedded_files_loading \ others/embedded_files_loading \
others/raylib_opengl_interop \ others/raylib_opengl_interop \
others/raymath_vector_angle \ others/raymath_vector_angle \
others/rlgl_compute_shader others/rlgl_compute_shader \
others/rlgl_standalone
ifeq ($(TARGET_PLATFORM), PLATFORM_DESKTOP_GFLW) #EXAMPLES_LIST_END
OTHERS += others/rlgl_standalone
endif
CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))
# Define processes to execute # Define processes to execute
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------
# Default target entry # Default target entry
all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO) $(OTHERS) all: $(CORE) $(SHAPES) $(TEXT) $(TEXTURES) $(MODELS) $(SHADERS) $(AUDIO)
core: $(CORE) core: $(CORE)
shapes: $(SHAPES) shapes: $(SHAPES)
@ -670,14 +691,13 @@ text: $(TEXT)
models: $(MODELS) models: $(MODELS)
shaders: $(SHADERS) shaders: $(SHADERS)
audio: $(AUDIO) audio: $(AUDIO)
others: $(OTHERS)
# Generic compilation pattern # Generic compilation pattern
# NOTE: Examples must be ready for Android compilation! # NOTE: Examples must be ready for Android compilation!
%: %.c %: %.c
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
$(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$< $(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$<
else ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) else ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
$(MAKE) -f Makefile.Web $@ $(MAKE) -f Makefile.Web $@
else else
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -D$(TARGET_PLATFORM) $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -D$(TARGET_PLATFORM)
@ -706,7 +726,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
find . -type f -executable -delete find . -type f -executable -delete
rm -fv *.o rm -fv *.o
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB) ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(PLATFORM_OS),WINDOWS) ifeq ($(PLATFORM_OS),WINDOWS)
del *.wasm *.html *.js *.data del *.wasm *.html *.js *.data
else else

View File

@ -2,7 +2,7 @@
# #
# raylib makefile for Android project (APK building) # raylib makefile for Android project (APK building)
# #
# Copyright (c) 2017-2024 Ramon Santamaria (@raysan5) # Copyright (c) 2017-2025 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.

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@ The examples assume you have already built the `raylib` library in `../src`.
- `make` builds all examples - `make` builds all examples
- `make [module]` builds all examples for a particular module (e.g `make core`) - `make [module]` builds all examples for a particular module (e.g `make core`)
- `make [module]/[name]` builds one examples for a particular module (e.g `make core/core_basic_window`)
### With Zig ### With Zig
@ -16,195 +17,226 @@ 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 LIST ## EXAMPLES COLLECTION [TOTAL: 163]
### category: core ### category: core [37]
Examples using raylib core platform functionality like window creation, inputs, drawing modes and system functionality. Examples using raylib[core](../src/rcore.c) platform functionality like 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 |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
| 01 | [core_basic_window](core/core_basic_window.c) | <img src="core/core_basic_window.png" alt="core_basic_window" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | [core_basic_window](core/core_basic_window.c) | <img src="core/core_basic_window.png" alt="core_basic_window" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 02 | [core_input_keys](core/core_input_keys.c) | <img src="core/core_input_keys.png" alt="core_input_keys" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | [core_input_keys](core/core_input_keys.c) | <img src="core/core_input_keys.png" alt="core_input_keys" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 03 | [core_input_mouse](core/core_input_mouse.c) | <img src="core/core_input_mouse.png" alt="core_input_mouse" width="80"> | ⭐️☆☆☆ | 1.0 | **4.0** | [Ray](https://github.com/raysan5) | | [core_input_mouse](core/core_input_mouse.c) | <img src="core/core_input_mouse.png" alt="core_input_mouse" width="80"> | ⭐☆☆☆ | 1.0 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 04 | [core_input_mouse_wheel](core/core_input_mouse_wheel.c) | <img src="core/core_input_mouse_wheel.png" alt="core_input_mouse_wheel" width="80"> | ⭐️☆☆☆ | 1.1 | 1.3 | [Ray](https://github.com/raysan5) | | [core_input_mouse_wheel](core/core_input_mouse_wheel.c) | <img src="core/core_input_mouse_wheel.png" alt="core_input_mouse_wheel" width="80"> | ⭐☆☆☆ | 1.1 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
| 05 | [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐️☆☆☆ | 1.1 | **4.2** | [Ray](https://github.com/raysan5) | | [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐☆☆☆ | 1.1 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 06 | [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐️☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) | | [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) |
| 07 | [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) | | [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐⭐☆☆ | 1.4 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 08 | [core_input_virtual_controls](core/core_input_virtual_controls.c) | <img src="core/core_input_virtual_controls.png" alt="core_input_virtual_controls" width="80"> | ⭐️⭐️☆☆ | **5.0** | **5.0** | [oblerion](https://github.com/oblerion) | | [core_input_gestures_testbed](core/core_input_gestures_testbed.c) | <img src="core/core_input_gestures_testbed.png" alt="core_input_gestures_testbed" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.6-dev | [ubkp](https://github.com/ubkp) |
| 09 | [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐️⭐️☆☆ | 1.5 | 3.0 | [Ray](https://github.com/raysan5) | | [core_input_virtual_controls](core/core_input_virtual_controls.c) | <img src="core/core_input_virtual_controls.png" alt="core_input_virtual_controls" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [GreenSnakeLinux](https://github.com/GreenSnakeLinux) |
| 10 | [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) | | [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐⭐☆☆ | 1.5 | 3.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 11 | [core_2d_camera_platformer](core/core_2d_camera_platformer.c) | <img src="core/core_2d_camera_platformer.png" alt="core_2d_camera_platformer" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [avyy](https://github.com/avyy) | | [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐⭐☆☆ | 4.2 | 4.2 | [Jeffery Myers](https://github.com/JeffM2501) |
| 12 | [core_2d_camera_split_screen](core/core_2d_camera_split_screen.c) | <img src="core/core_2d_camera_split_screen.png" alt="core_2d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Gabriel dos Santos Sanches](https://github.com/gabrielssanches) | | [core_2d_camera_platformer](core/core_2d_camera_platformer.c) | <img src="core/core_2d_camera_platformer.png" alt="core_2d_camera_platformer" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.0 | [arvyy](https://github.com/arvyy) |
| 13 | [core_3d_camera_mode](core/core_3d_camera_mode.c) | <img src="core/core_3d_camera_mode.png" alt="core_3d_camera_mode" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | [core_2d_camera_split_screen](core/core_2d_camera_split_screen.c) | <img src="core/core_2d_camera_split_screen.png" alt="core_2d_camera_split_screen" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [Gabriel dos Santos Sanches](https://github.com/gabrielssanches) |
| 14 | [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 | [Ray](https://github.com/raysan5) | | [core_3d_camera_mode](core/core_3d_camera_mode.c) | <img src="core/core_3d_camera_mode.png" alt="core_3d_camera_mode" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 15 | [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 | [Ray](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) |
| 16 | [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_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) |
| 17 | [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** | [Ray](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) |
| 18 | [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 | [Ray](https://github.com/raysan5) | | [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) |
| 19 | [core_custom_logging](core/core_custom_logging.c) | <img src="core/core_custom_logging.png" alt="core_custom_logging" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) | | [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) |
| 20 | [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 | [Ray](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) |
| 21 | [core_window_letterbox](core/core_window_letterbox.c) | <img src="core/core_window_letterbox.png" alt="core_window_letterbox" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Anata](https://github.com/anatagawa) | | [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) |
| 22 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | [core_window_letterbox](core/core_window_letterbox.c) | <img src="core/core_window_letterbox.png" alt="core_window_letterbox" width="80"> | ⭐⭐☆☆ | 2.5 | 4.0 | [Anata](https://github.com/anatagawa) |
| 23 | [core_drop_files](core/core_drop_files.c) | <img src="core/core_drop_files.png" alt="core_drop_files" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐☆☆☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 24 | [core_random_values](core/core_random_values.c) | <img src="core/core_random_values.png" alt="core_random_values" width="80"> | ⭐️☆☆☆ | 1.1 | 1.1 | [Ray](https://github.com/raysan5) | | [core_custom_logging](core/core_custom_logging.c) | <img src="core/core_custom_logging.png" alt="core_custom_logging" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) |
| 25 | [core_storage_values](core/core_storage_values.c) | <img src="core/core_storage_values.png" alt="core_storage_values" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) | | [core_drop_files](core/core_drop_files.c) | <img src="core/core_drop_files.png" alt="core_drop_files" width="80"> | ⭐⭐☆☆ | 1.3 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 26 | [core_vr_simulator](core/core_vr_simulator.c) | <img src="core/core_vr_simulator.png" alt="core_vr_simulator" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | | [core_random_values](core/core_random_values.c) | <img src="core/core_random_values.png" alt="core_random_values" width="80"> | ⭐☆☆☆ | 1.1 | 1.1 | [Ramon Santamaria](https://github.com/raysan5) |
| 27 | [core_loading_thread](core/core_loading_thread.c) | <img src="core/core_loading_thread.png" alt="core_loading_thread" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Ray](https://github.com/raysan5) | | [core_storage_values](core/core_storage_values.c) | <img src="core/core_storage_values.png" alt="core_storage_values" width="80"> | ⭐⭐☆☆ | 1.4 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 28 | [core_scissor_test](core/core_scissor_test.c) | <img src="core/core_scissor_test.png" alt="core_scissor_test" width="80"> | ⭐️☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) | | [core_vr_simulator](core/core_vr_simulator.c) | <img src="core/core_vr_simulator.png" alt="core_vr_simulator" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 29 | [core_basic_screen_manager](core/core_basic_screen_manager.c) | <img src="core/core_basic_screen_manager.png" alt="core_basic_screen_manager" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) | | [core_scissor_test](core/core_scissor_test.c) | <img src="core/core_scissor_test.png" alt="core_scissor_test" width="80"> | ⭐☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
| 30 | [core_custom_frame_control](core/core_custom_frame_control.c) | <img src="core/core_custom_frame_control.png" alt="core_custom_frame_control" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) | | [core_basic_screen_manager](core/core_basic_screen_manager.c) | <img src="core/core_basic_screen_manager.png" alt="core_basic_screen_manager" width="80"> | ⭐☆☆☆ | 4.0 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 31 | [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_custom_frame_control](core/core_custom_frame_control.c) | <img src="core/core_custom_frame_control.png" alt="core_custom_frame_control" width="80"> | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 32 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | [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) |
| 33 | [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** | [REDl3east](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_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_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) |
### category: shapes ### category: shapes [20]
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/shapes.c) module. Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
| 34 | [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | **4.0** | [Ray](https://github.com/raysan5) | | [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐☆☆☆ | 1.0 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 35 | [shapes_bouncing_ball](shapes/shapes_bouncing_ball.c) | <img src="shapes/shapes_bouncing_ball.png" alt="shapes_bouncing_ball" width="80"> | ⭐️☆☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | [shapes_bouncing_ball](shapes/shapes_bouncing_ball.c) | <img src="shapes/shapes_bouncing_ball.png" alt="shapes_bouncing_ball" width="80"> | ⭐☆☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 36 | [shapes_colors_palette](shapes/shapes_colors_palette.c) | <img src="shapes/shapes_colors_palette.png" alt="shapes_colors_palette" width="80"> | ⭐️⭐️☆☆ | 1.0 | 2.5 | [Ray](https://github.com/raysan5) | | [shapes_colors_palette](shapes/shapes_colors_palette.c) | <img src="shapes/shapes_colors_palette.png" alt="shapes_colors_palette" width="80"> | ⭐⭐☆☆ | 1.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 37 | [shapes_logo_raylib](shapes/shapes_logo_raylib.c) | <img src="shapes/shapes_logo_raylib.png" alt="shapes_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | [shapes_logo_raylib](shapes/shapes_logo_raylib.c) | <img src="shapes/shapes_logo_raylib.png" alt="shapes_logo_raylib" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 38 | [shapes_logo_raylib_anim](shapes/shapes_logo_raylib_anim.c) | <img src="shapes/shapes_logo_raylib_anim.png" alt="shapes_logo_raylib_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | | [shapes_logo_raylib_anim](shapes/shapes_logo_raylib_anim.c) | <img src="shapes/shapes_logo_raylib_anim.png" alt="shapes_logo_raylib_anim" width="80"> | ⭐⭐☆☆ | 2.5 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 39 | [shapes_rectangle_scaling](shapes/shapes_rectangle_scaling.c) | <img src="shapes/shapes_rectangle_scaling.png" alt="shapes_rectangle_scaling" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) | | [shapes_rectangle_scaling](shapes/shapes_rectangle_scaling.c) | <img src="shapes/shapes_rectangle_scaling.png" alt="shapes_rectangle_scaling" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| 40 | [shapes_lines_bezier](shapes/shapes_lines_bezier.c) | <img src="shapes/shapes_lines_bezier.png" alt="shapes_lines_bezier" width="80"> | ⭐️☆☆☆ | 1.7 | 1.7 | [Ray](https://github.com/raysan5) | | [shapes_lines_bezier](shapes/shapes_lines_bezier.c) | <img src="shapes/shapes_lines_bezier.png" alt="shapes_lines_bezier" width="80"> | ⭐☆☆☆ | 1.7 | 1.7 | [Ramon Santamaria](https://github.com/raysan5) |
| 41 | [shapes_collision_area](shapes/shapes_collision_area.c) | <img src="shapes/shapes_collision_area.png" alt="shapes_collision_area" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | [shapes_collision_area](shapes/shapes_collision_area.c) | <img src="shapes/shapes_collision_area.png" alt="shapes_collision_area" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 42 | [shapes_following_eyes](shapes/shapes_following_eyes.c) | <img src="shapes/shapes_following_eyes.png" alt="shapes_following_eyes" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | [shapes_following_eyes](shapes/shapes_following_eyes.c) | <img src="shapes/shapes_following_eyes.png" alt="shapes_following_eyes" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 43 | [shapes_easings_ball_anim](shapes/shapes_easings_ball_anim.c) | <img src="shapes/shapes_easings_ball_anim.png" alt="shapes_easings_ball_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | [shapes_easings_ball](shapes/shapes_easings_ball.c) | <img src="shapes/shapes_easings_ball.png" alt="shapes_easings_ball" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 44 | [shapes_easings_box_anim](shapes/shapes_easings_box_anim.c) | <img src="shapes/shapes_easings_box_anim.png" alt="shapes_easings_box_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | [shapes_easings_box](shapes/shapes_easings_box.c) | <img src="shapes/shapes_easings_box.png" alt="shapes_easings_box" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 45 | [shapes_easings_rectangle_array](shapes/shapes_easings_rectangle_array.c) | <img src="shapes/shapes_easings_rectangle_array.png" alt="shapes_easings_rectangle_array" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | [shapes_easings_rectangles](shapes/shapes_easings_rectangles.c) | <img src="shapes/shapes_easings_rectangles.png" alt="shapes_easings_rectangles" width="80"> | ⭐⭐⭐☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 46 | [shapes_draw_ring](shapes/shapes_draw_ring.c) | <img src="shapes/shapes_draw_ring.png" alt="shapes_draw_ring" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) | | [shapes_ring_drawing](shapes/shapes_ring_drawing.c) | <img src="shapes/shapes_ring_drawing.png" alt="shapes_ring_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| 47 | [shapes_draw_circle_sector](shapes/shapes_draw_circle_sector.c) | <img src="shapes/shapes_draw_circle_sector.png" alt="shapes_draw_circle_sector" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) | | [shapes_circle_sector_drawing](shapes/shapes_circle_sector_drawing.c) | <img src="shapes/shapes_circle_sector_drawing.png" alt="shapes_circle_sector_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| 48 | [shapes_draw_rectangle_rounded](shapes/shapes_draw_rectangle_rounded.c) | <img src="shapes/shapes_draw_rectangle_rounded.png" alt="shapes_draw_rectangle_rounded" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) | | [shapes_rounded_rectangle_drawing](shapes/shapes_rounded_rectangle_drawing.c) | <img src="shapes/shapes_rounded_rectangle_drawing.png" alt="shapes_rounded_rectangle_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| 49 | [shapes_top_down_lights](shapes/shapes_top_down_lights.c) | <img src="shapes/shapes_top_down_lights.png" alt="shapes_top_down_lights" width="80"> | ⭐️⭐️⭐️⭐️ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) | | [shapes_top_down_lights](shapes/shapes_top_down_lights.c) | <img src="shapes/shapes_top_down_lights.png" alt="shapes_top_down_lights" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [Jeffery Myers](https://github.com/JeffM2501) |
| 50 | [shapes_rectangle_advanced](shapes/shapes_rectangle_advanced.c) | <img src="shapes/shapes_rectangle_advanced.png" alt="shapes_rectangle_advanced" width="80"> | ⭐️⭐️⭐️⭐️⭐️| **5.0** | **5.0** | [ExCyber](https://github.com/evertonse) | | [shapes_rectangle_advanced](shapes/shapes_rectangle_advanced.c) | <img src="shapes/shapes_rectangle_advanced.png" alt="shapes_rectangle_advanced" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.5 | [Everton Jr.](https://github.com/evertonse) |
| [shapes_splines_drawing](shapes/shapes_splines_drawing.c) | <img src="shapes/shapes_splines_drawing.png" alt="shapes_splines_drawing" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [shapes_digital_clock](shapes/shapes_digital_clock.c) | <img src="shapes/shapes_digital_clock.png" alt="shapes_digital_clock" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
| [shapes_double_pendulum](shapes/shapes_double_pendulum.c) | <img src="shapes/shapes_double_pendulum.png" alt="shapes_double_pendulum" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) |
### category: textures ### category: textures [26]
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/textures.c) module. Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
| 51 | [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 52 | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐⭐⭐☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
| 53 | [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) | | [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐⭐☆☆ | 1.4 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
| 54 | [textures_image_generation](textures/textures_image_generation.c) | <img src="textures/textures_image_generation.png" alt="textures_image_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | 1.8 | [Ray](https://github.com/raysan5) | | [textures_image_generation](textures/textures_image_generation.c) | <img src="textures/textures_image_generation.png" alt="textures_image_generation" width="80"> | ⭐⭐☆☆ | 1.8 | 1.8 | [Wilhem Barbier](https://github.com/nounoursheureux) |
| 55 | [textures_image_loading](textures/textures_image_loading.c) | <img src="textures/textures_image_loading.png" alt="textures_image_loading" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | | [textures_image_loading](textures/textures_image_loading.c) | <img src="textures/textures_image_loading.png" alt="textures_image_loading" width="80"> | ⭐☆☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
| 56 | [textures_image_processing](textures/textures_image_processing.c) | <img src="textures/textures_image_processing.png" alt="textures_image_processing" width="80"> | ⭐️⭐️⭐️☆ | 1.4 | 3.5 | [Ray](https://github.com/raysan5) | | [textures_image_processing](textures/textures_image_processing.c) | <img src="textures/textures_image_processing.png" alt="textures_image_processing" width="80"> | ⭐⭐⭐☆ | 1.4 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 57 | [textures_image_text](textures/textures_image_text.c) | <img src="textures/textures_image_text.png" alt="textures_image_text" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) | | [textures_image_text](textures/textures_image_text.c) | <img src="textures/textures_image_text.png" alt="textures_image_text" width="80"> | ⭐⭐☆☆ | 1.8 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 58 | [textures_to_image](textures/textures_to_image.c) | <img src="textures/textures_to_image.png" alt="textures_to_image" width="80"> | ⭐️☆☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | [textures_to_image](textures/textures_to_image.c) | <img src="textures/textures_to_image.png" alt="textures_to_image" width="80"> | ⭐☆☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 59 | [textures_raw_data](textures/textures_raw_data.c) | <img src="textures/textures_raw_data.png" alt="textures_raw_data" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) | | [textures_raw_data](textures/textures_raw_data.c) | <img src="textures/textures_raw_data.png" alt="textures_raw_data" width="80"> | ⭐⭐⭐☆ | 1.3 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 60 | [textures_particles_blending](textures/textures_particles_blending.c) | <img src="textures/textures_particles_blending.png" alt="textures_particles_blending" width="80"> | ⭐️☆☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) | | [textures_particles_blending](textures/textures_particles_blending.c) | <img src="textures/textures_particles_blending.png" alt="textures_particles_blending" width="80"> | ⭐☆☆☆ | 1.7 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 61 | [textures_npatch_drawing](textures/textures_npatch_drawing.c) | <img src="textures/textures_npatch_drawing.png" alt="textures_npatch_drawing" width="80"> | ⭐️⭐️⭐️☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) | | [textures_npatch_drawing](textures/textures_npatch_drawing.c) | <img src="textures/textures_npatch_drawing.png" alt="textures_npatch_drawing" width="80"> | ⭐⭐⭐☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) |
| 62 | [textures_background_scrolling](textures/textures_background_scrolling.c) | <img src="textures/textures_background_scrolling.png" alt="textures_background_scrolling" width="80"> | ⭐️☆☆☆ | 2.0 | 2.5 | [Ray](https://github.com/raysan5) | | [textures_background_scrolling](textures/textures_background_scrolling.c) | <img src="textures/textures_background_scrolling.png" alt="textures_background_scrolling" width="80"> | ⭐☆☆☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 63 | [textures_sprite_anim](textures/textures_sprite_anim.c) | <img src="textures/textures_sprite_anim.png" alt="textures_sprite_anim" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | | [textures_sprite_animation](textures/textures_sprite_animation.c) | <img src="textures/textures_sprite_animation.png" alt="textures_sprite_animation" width="80"> | ⭐⭐☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
| 64 | [textures_sprite_button](textures/textures_sprite_button.c) | <img src="textures/textures_sprite_button.png" alt="textures_sprite_button" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | [textures_sprite_button](textures/textures_sprite_button.c) | <img src="textures/textures_sprite_button.png" alt="textures_sprite_button" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 65 | [textures_sprite_explosion](textures/textures_sprite_explosion.c) | <img src="textures/textures_sprite_explosion.png" alt="textures_sprite_explosion" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) | | [textures_sprite_explosion](textures/textures_sprite_explosion.c) | <img src="textures/textures_sprite_explosion.png" alt="textures_sprite_explosion" width="80"> | ⭐⭐☆☆ | 2.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 66 | [textures_bunnymark](textures/textures_bunnymark.c) | <img src="textures/textures_bunnymark.png" alt="textures_bunnymark" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | 2.5 | [Ray](https://github.com/raysan5) | | [textures_bunnymark](textures/textures_bunnymark.c) | <img src="textures/textures_bunnymark.png" alt="textures_bunnymark" width="80"> | ⭐⭐⭐☆ | 1.6 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 67 | [textures_mouse_painting](textures/textures_mouse_painting.c) | <img src="textures/textures_mouse_painting.png" alt="textures_mouse_painting" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) | | [textures_mouse_painting](textures/textures_mouse_painting.c) | <img src="textures/textures_mouse_painting.png" alt="textures_mouse_painting" width="80"> | ⭐⭐⭐☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
| 68 | [textures_blend_modes](textures/textures_blend_modes.c) | <img src="textures/textures_blend_modes.png" alt="textures_blend_modes" width="80"> | ⭐️☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) | | [textures_blend_modes](textures/textures_blend_modes.c) | <img src="textures/textures_blend_modes.png" alt="textures_blend_modes" width="80"> | ⭐☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) |
| 69 | [textures_draw_tiled](textures/textures_draw_tiled.c) | <img src="textures/textures_draw_tiled.png" alt="textures_draw_tiled" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | **4.2** | [Vlad Adrian](https://github.com/demizdor) | | [textures_tiled_drawing](textures/textures_tiled_drawing.c) | <img src="textures/textures_tiled_drawing.png" alt="textures_tiled_drawing" width="80"> | ⭐⭐⭐☆ | 3.0 | 4.2 | [Vlad Adrian](https://github.com/demizdor) |
| 70 | [textures_polygon](textures/textures_polygon.c) | <img src="textures/textures_polygon.png" alt="textures_polygon" width="80"> | ⭐️☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/codifies) | | [textures_polygon_drawing](textures/textures_polygon_drawing.c) | <img src="textures/textures_polygon_drawing.png" alt="textures_polygon_drawing" width="80"> | ⭐☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
| 71 | [textures_fog_of_war](textures/textures_fog_of_war.c) | <img src="textures/textures_fog_of_war.png" alt="textures_fog_of_war" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | [textures_fog_of_war](textures/textures_fog_of_war.c) | <img src="textures/textures_fog_of_war.png" alt="textures_fog_of_war" width="80"> | ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 72 | [textures_gif_player](textures/textures_gif_player.c) | <img src="textures/textures_gif_player.png" alt="textures_gif_player" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | [textures_gif_player](textures/textures_gif_player.c) | <img src="textures/textures_gif_player.png" alt="textures_gif_player" width="80"> | ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| [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_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_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) |
### category: text ### category: text [14]
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/text.c) module. Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
| 73 | [text_raylib_fonts](text/text_raylib_fonts.c) | <img src="text/text_raylib_fonts.png" alt="text_raylib_fonts" width="80"> | ⭐️☆☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) | | [text_sprite_fonts](text/text_sprite_fonts.c) | <img src="text/text_sprite_fonts.png" alt="text_sprite_fonts" width="80"> | ⭐☆☆☆ | 1.7 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
| 74 | [text_font_spritefont](text/text_font_spritefont.c) | <img src="text/text_font_spritefont.png" alt="text_font_spritefont" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | [text_font_spritefont](text/text_font_spritefont.c) | <img src="text/text_font_spritefont.png" alt="text_font_spritefont" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 75 | [text_font_filters](text/text_font_filters.c) | <img src="text/text_font_filters.png" alt="text_font_filters" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | | [text_font_filters](text/text_font_filters.c) | <img src="text/text_font_filters.png" alt="text_font_filters" width="80"> | ⭐⭐☆☆ | 1.3 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 76 | [text_font_loading](text/text_font_loading.c) | <img src="text/text_font_loading.png" alt="text_font_loading" width="80"> | ⭐️☆☆☆ | 1.4 | 3.0 | [Ray](https://github.com/raysan5) | | [text_font_loading](text/text_font_loading.c) | <img src="text/text_font_loading.png" alt="text_font_loading" width="80"> | ⭐☆☆☆ | 1.4 | 3.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 77 | [text_font_sdf](text/text_font_sdf.c) | <img src="text/text_font_sdf.png" alt="text_font_sdf" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | [text_font_sdf](text/text_font_sdf.c) | <img src="text/text_font_sdf.png" alt="text_font_sdf" width="80"> | ⭐⭐⭐☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 78 | [text_format_text](text/text_format_text.c) | <img src="text/text_format_text.png" alt="text_format_text" width="80"> | ⭐️☆☆☆ | 1.1 | 3.0 | [Ray](https://github.com/raysan5) | | [text_format_text](text/text_format_text.c) | <img src="text/text_format_text.png" alt="text_format_text" width="80"> | ⭐☆☆☆ | 1.1 | 3.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 79 | [text_input_box](text/text_input_box.c) | <img src="text/text_input_box.png" alt="text_input_box" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) | | [text_input_box](text/text_input_box.c) | <img src="text/text_input_box.png" alt="text_input_box" width="80"> | ⭐⭐☆☆ | 1.7 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 80 | [text_writing_anim](text/text_writing_anim.c) | <img src="text/text_writing_anim.png" alt="text_writing_anim" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) | | [text_writing_anim](text/text_writing_anim.c) | <img src="text/text_writing_anim.png" alt="text_writing_anim" width="80"> | ⭐⭐☆☆ | 1.4 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
| 81 | [text_rectangle_bounds](text/text_rectangle_bounds.c) | <img src="text/text_rectangle_bounds.png" alt="text_rectangle_bounds" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) | | [text_rectangle_bounds](text/text_rectangle_bounds.c) | <img src="text/text_rectangle_bounds.png" alt="text_rectangle_bounds" width="80"> | ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
| 82 | [text_unicode](text/text_unicode.c) | <img src="text/text_unicode.png" alt="text_unicode" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) | | [text_unicode_emojis](text/text_unicode_emojis.c) | <img src="text/text_unicode_emojis.png" alt="text_unicode_emojis" width="80"> | ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
| 83 | [text_draw_3d](text/text_draw_3d.c) | <img src="text/text_draw_3d.png" alt="text_draw_3d" width="80"> | ⭐️⭐️⭐️⭐️ | 3.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) | | [text_unicode_ranges](text/text_unicode_ranges.c) | <img src="text/text_unicode_ranges.png" alt="text_unicode_ranges" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Vlad Adrian](https://github.com/demizdor) |
| 84 | [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** | [Ray](https://github.com/raysan5) | | [text_3d_drawing](text/text_3d_drawing.c) | <img src="text/text_3d_drawing.png" alt="text_3d_drawing" width="80"> | ⭐⭐⭐⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
| [text_codepoints_loading](text/text_codepoints_loading.c) | <img src="text/text_codepoints_loading.png" alt="text_codepoints_loading" width="80"> | ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| [text_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) |
### category: models ### category: models [23]
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/models.c) module. Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
| 85 | [models_animation](models/models_animation.c) | <img src="models/models_animation.png" alt="models_animation" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [culacant](https://github.com/culacant) | | [models_animation_playing](models/models_animation_playing.c) | <img src="models/models_animation_playing.png" alt="models_animation_playing" width="80"> | ⭐⭐☆☆ | 2.5 | 3.5 | [Culacant](https://github.com/culacant) |
| 86 | [models_animation_blending](models/models_animation_blending.c) | <img src="models/models_animation_blending.png" alt="models_animation_blending" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Kirandeep-Singh-Khehra](https://github.com/Kirandeep-Singh-Khehra) | | [models_billboard_rendering](models/models_billboard_rendering.c) | <img src="models/models_billboard_rendering.png" alt="models_billboard_rendering" width="80"> | ⭐⭐⭐☆ | 1.3 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 87 | [models_billboard](models/models_billboard.c) | <img src="models/models_billboard.png" alt="models_billboard" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) | | [models_box_collisions](models/models_box_collisions.c) | <img src="models/models_box_collisions.png" alt="models_box_collisions" width="80"> | ⭐☆☆☆ | 1.3 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 88 | [models_box_collisions](models/models_box_collisions.c) | <img src="models/models_box_collisions.png" alt="models_box_collisions" width="80"> | ⭐️☆☆☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) | | [models_cubicmap_rendering](models/models_cubicmap_rendering.c) | <img src="models/models_cubicmap_rendering.png" alt="models_cubicmap_rendering" width="80"> | ⭐⭐☆☆ | 1.8 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 89 | [models_cubicmap](models/models_cubicmap.c) | <img src="models/models_cubicmap.png" alt="models_cubicmap" width="80"> | ⭐️⭐️☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) | | [models_first_person_maze](models/models_first_person_maze.c) | <img src="models/models_first_person_maze.png" alt="models_first_person_maze" width="80"> | ⭐⭐☆☆ | 2.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 90 | [models_first_person_maze](models/models_first_person_maze.c) | <img src="models/models_first_person_maze.png" alt="models_first_person_maze" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) | | [models_geometric_shapes](models/models_geometric_shapes.c) | <img src="models/models_geometric_shapes.png" alt="models_geometric_shapes" width="80"> | ⭐☆☆☆ | 1.0 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 91 | [models_geometric_shapes](models/models_geometric_shapes.c) | <img src="models/models_geometric_shapes.png" alt="models_geometric_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | 3.5 | [Ray](https://github.com/raysan5) | | [models_mesh_generation](models/models_mesh_generation.c) | <img src="models/models_mesh_generation.png" alt="models_mesh_generation" width="80"> | ⭐⭐☆☆ | 1.8 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 92 | [models_mesh_generation](models/models_mesh_generation.c) | <img src="models/models_mesh_generation.png" alt="models_mesh_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) | | [models_mesh_picking](models/models_mesh_picking.c) | <img src="models/models_mesh_picking.png" alt="models_mesh_picking" width="80"> | ⭐⭐⭐☆ | 1.7 | 4.0 | [Joel Davis](https://github.com/joeld42) |
| 93 | [models_mesh_picking](models/models_mesh_picking.c) | <img src="models/models_mesh_picking.png" alt="models_mesh_picking" width="80"> | ⭐️⭐️⭐️☆ | 1.7 | **4.0** | [Joel Davis](https://github.com/joeld42) | | [models_loading](models/models_loading.c) | <img src="models/models_loading.png" alt="models_loading" width="80"> | ⭐☆☆☆ | 2.0 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 94 | [models_loading](models/models_loading.c) | <img src="models/models_loading.png" alt="models_loading" width="80"> | ⭐️☆☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | | [models_loading_gltf](models/models_loading_gltf.c) | <img src="models/models_loading_gltf.png" alt="models_loading_gltf" width="80"> | ⭐☆☆☆ | 3.7 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 95 | [models_loading_gltf](models/models_loading_gltf.c) | <img src="models/models_loading_gltf.png" alt="models_loading_gltf" width="80"> | ⭐️☆☆☆ | 3.7 | **4.2** | [Ray](https://github.com/raysan5) | | [models_loading_vox](models/models_loading_vox.c) | <img src="models/models_loading_vox.png" alt="models_loading_vox" width="80"> | ⭐☆☆☆ | 4.0 | 4.0 | [Johann Nadalutti](https://github.com/procfxgen) |
| 96 | [models_loading_vox](models/models_loading_vox.c) | <img src="models/models_loading_vox.png" alt="models_loading_vox" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Johann Nadalutti](https://github.com/procfxgen) | | [models_loading_m3d](models/models_loading_m3d.c) | <img src="models/models_loading_m3d.png" alt="models_loading_m3d" width="80"> | ⭐⭐☆☆ | 4.5 | 4.5 | [bzt](https://github.com/bztsrc) |
| 97 | [models_loading_m3d](models/models_loading_m3d.c) | <img src="models/models_loading_m3d.png" alt="models_loading_m3d" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [bzt](https://bztsrc.gitlab.io/model3d) | | [models_orthographic_projection](models/models_orthographic_projection.c) | <img src="models/models_orthographic_projection.png" alt="models_orthographic_projection" width="80"> | ⭐☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) |
| 98 | [models_orthographic_projection](models/models_orthographic_projection.c) | <img src="models/models_orthographic_projection.png" alt="models_orthographic_projection" width="80"> | ⭐️☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) | | [models_point_rendering](models/models_point_rendering.c) | <img src="models/models_point_rendering.png" alt="models_point_rendering" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Reese Gallagher](https://github.com/satchelfrost) |
| 99 | [models_point_rendering](models/models_point_rendering.c) | <img src="models/models_point_rendering.png" alt="models_point_rendering" width="80"> | ⭐️⭐️☆☆ | 5.0 | 5.0 | [Reese Gallagher](https://github.com/satchelfrost) | | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) | <img src="models/models_rlgl_solar_system.png" alt="models_rlgl_solar_system" width="80"> | ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 100 | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) | <img src="models/models_rlgl_solar_system.png" alt="models_rlgl_solar_system" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) | <img src="models/models_yaw_pitch_roll.png" alt="models_yaw_pitch_roll" width="80"> | ⭐⭐☆☆ | 1.8 | 4.0 | [Berni](https://github.com/Berni8k) |
| 101 | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) | <img src="models/models_yaw_pitch_roll.png" alt="models_yaw_pitch_roll" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Berni](https://github.com/Berni8k) | | [models_waving_cubes](models/models_waving_cubes.c) | <img src="models/models_waving_cubes.png" alt="models_waving_cubes" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.7 | [Codecat](https://github.com/codecat) |
| 102 | [models_waving_cubes](models/models_waving_cubes.c) | <img src="models/models_waving_cubes.png" alt="models_waving_cubes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [codecat](https://github.com/codecat) | | [models_heightmap_rendering](models/models_heightmap_rendering.c) | <img src="models/models_heightmap_rendering.png" alt="models_heightmap_rendering" width="80"> | ⭐☆☆☆ | 1.8 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 103 | [models_heightmap](models/models_heightmap.c) | <img src="models/models_heightmap.png" alt="models_heightmap" width="80"> | ⭐️☆☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) | | [models_skybox_rendering](models/models_skybox_rendering.c) | <img src="models/models_skybox_rendering.png" alt="models_skybox_rendering" width="80"> | ⭐⭐☆☆ | 1.8 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 104 | [models_skybox](models/models_skybox.c) | <img src="models/models_skybox.png" alt="models_skybox" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) | | [models_textured_cube](models/models_textured_cube.c) | <img src="models/models_textured_cube.png" alt="models_textured_cube" width="80"> | ⭐⭐☆☆ | 4.5 | 4.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [models_gpu_skinning](models/models_gpu_skinning.c) | <img src="models/models_gpu_skinning.png" alt="models_gpu_skinning" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Daniel Holden](https://github.com/orangeduck) |
| [models_bone_socket](models/models_bone_socket.c) | <img src="models/models_bone_socket.png" alt="models_bone_socket" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
| [models_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) |
### category: shaders ### category: shaders [29]
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.
| ## | 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 |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
| 105 | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐️⭐️⭐️⭐️ | 3.0 | **4.2** | [Chris Camacho](https://github.com/codifies) | | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐⭐⭐⭐️ | 3.0 | 4.2 | [Chris Camacho](https://github.com/chriscamacho) |
| 106 | [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐️⭐️☆☆ | 1.3 | 3.7 | [Ray](https://github.com/raysan5) | | [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐⭐☆☆ | 1.3 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
| 107 | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) | | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐⭐☆☆ | 1.7 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
| 108 | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) | <img src="shaders/shaders_custom_uniform.png" alt="shaders_custom_uniform" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) | <img src="shaders/shaders_custom_uniform.png" alt="shaders_custom_uniform" width="80"> | ⭐⭐☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 109 | [shaders_postprocessing](shaders/shaders_postprocessing.c) | <img src="shaders/shaders_postprocessing.png" alt="shaders_postprocessing" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | [shaders_postprocessing](shaders/shaders_postprocessing.c) | <img src="shaders/shaders_postprocessing.png" alt="shaders_postprocessing" width="80"> | ⭐⭐⭐☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 110 | [shaders_palette_switch](shaders/shaders_palette_switch.c) | <img src="shaders/shaders_palette_switch.png" alt="shaders_palette_switch" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) | | [shaders_palette_switch](shaders/shaders_palette_switch.c) | <img src="shaders/shaders_palette_switch.png" alt="shaders_palette_switch" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) |
| 111 | [shaders_raymarching](shaders/shaders_raymarching.c) | <img src="shaders/shaders_raymarching.png" alt="shaders_raymarching" width="80"> | ⭐️⭐️⭐️⭐️ | 2.0 | **4.2** | [Ray](https://github.com/raysan5) | | [shaders_raymarching_rendering](shaders/shaders_raymarching_rendering.c) | <img src="shaders/shaders_raymarching_rendering.png" alt="shaders_raymarching_rendering" width="80"> | ⭐⭐⭐⭐️ | 2.0 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 112 | [shaders_texture_drawing](shaders/shaders_texture_drawing.c) | <img src="shaders/shaders_texture_drawing.png" alt="shaders_texture_drawing" width="80"> | ⭐️⭐️☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/) | | [shaders_texture_rendering](shaders/shaders_texture_rendering.c) | <img src="shaders/shaders_texture_rendering.png" alt="shaders_texture_rendering" width="80"> | ⭐⭐☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/ciessielski) |
| 113 | [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** | [Samuel 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) |
| 114 | [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) |
| 115 | [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** | [eggmund](https://github.com/eggmund) | | [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) |
| 116 | [shaders_eratosthenes](shaders/shaders_eratosthenes.c) | <img src="shaders/shaders_eratosthenes.png" alt="shaders_eratosthenes" 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) |
| 117 | [shaders_fog](shaders/shaders_fog.c) | <img src="shaders/shaders_fog.png" alt="shaders_fog" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) | | [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) |
| 118 | [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/codifies) | | [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) |
| 119 | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.5 | [Ray](https://github.com/raysan5) | | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐⭐⭐☆ | 3.0 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 120 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.2** | [seanpringle](https://github.com/seanpringle) | | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐⭐⭐⭐️ | 3.7 | 4.2 | [seanpringle](https://github.com/seanpringle) |
| 121 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) | | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐⭐☆☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 122 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) | | [shaders_normalmap_rendering](shaders/shaders_normalmap_rendering.c) | <img src="shaders/shaders_normalmap_rendering.png" alt="shaders_normalmap_rendering" width="80"> | ⭐⭐⭐⭐️ | 5.6 | 5.6 | [Jeremy Montgomery](https://github.com/Sir_Irk) |
| 123 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) | | [shaders_spotlight_rendering](shaders/shaders_spotlight_rendering.c) | <img src="shaders/shaders_spotlight_rendering.png" alt="shaders_spotlight_rendering" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
| [shaders_deferred_rendering](shaders/shaders_deferred_rendering.c) | <img src="shaders/shaders_deferred_rendering.png" alt="shaders_deferred_rendering" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
| [shaders_hybrid_rendering](shaders/shaders_hybrid_rendering.c) | <img src="shaders/shaders_hybrid_rendering.png" alt="shaders_hybrid_rendering" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
| [shaders_texture_tiling](shaders/shaders_texture_tiling.c) | <img src="shaders/shaders_texture_tiling.png" alt="shaders_texture_tiling" width="80"> | ⭐⭐☆☆ | 4.5 | 4.5 | [Luis Almeida](https://github.com/luis605) |
| [shaders_shadowmap_rendering](shaders/shaders_shadowmap_rendering.c) | <img src="shaders/shaders_shadowmap_rendering.png" alt="shaders_shadowmap_rendering" width="80"> | ⭐⭐⭐⭐️ | 5.0 | 5.0 | [TheManTheMythTheGameDev](https://github.com/TheManTheMythTheGameDev) |
| [shaders_vertex_displacement](shaders/shaders_vertex_displacement.c) | <img src="shaders/shaders_vertex_displacement.png" alt="shaders_vertex_displacement" width="80"> | ⭐⭐⭐☆ | 5.0 | 4.5 | [Alex ZH](https://github.com/ZzzhHe) |
| [shaders_depth_writing](shaders/shaders_depth_writing.c) | <img src="shaders/shaders_depth_writing.png" alt="shaders_depth_writing" width="80"> | ⭐⭐☆☆ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
| [shaders_basic_pbr](shaders/shaders_basic_pbr.c) | <img src="shaders/shaders_basic_pbr.png" alt="shaders_basic_pbr" width="80"> | ⭐⭐⭐⭐️ | 5.0 | 5.5 | [Afan OLOVCIC](https://github.com/_DevDad) |
| [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) | <img src="shaders/shaders_lightmap_rendering.png" alt="shaders_lightmap_rendering" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
| [shaders_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) |
### category: audio ### category: audio [8]
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, check [raudio_standalone](others/raudio_standalone.c) example. 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.
| ## | 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 |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
| 124 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) | | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐☆☆☆ | 1.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| 125 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐☆☆☆ | 1.3 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 126 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) | | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐⭐⭐☆ | 1.6 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| 127 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) | | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐☆☆☆ | 1.1 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [audio_mixed_processor](audio/audio_mixed_processor.c) | <img src="audio/audio_mixed_processor.png" alt="audio_mixed_processor" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [hkc](https://github.com/hatkidchan) |
| [audio_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_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) |
### category: others ### category: others [6]
Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries. Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries.
| ## | 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 |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
| 128 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) | | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐⭐⭐⭐️ | 1.6 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| 129 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) | | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
| 130 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) | | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
| 131 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) | | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐⭐⭐⭐️ | 3.8 | 4.0 | [Stephan Soller](https://github.com/arkanis) |
| 132 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) | | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐⭐☆☆ | 3.0 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
| [raymath_vector_angle](others/raymath_vector_angle.c) | <img src="others/raymath_vector_angle.png" alt="raymath_vector_angle" width="80"> | ⭐⭐☆☆ | 1.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
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!

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [audio] example - Mixed audio processing * raylib [audio] example - mixed processor
*
* Example complexity rating: [] 4/4
* *
* Example originally created with raylib 4.2, last time updated with raylib 4.2 * Example originally created with raylib 4.2, last time updated with raylib 4.2
* *
@ -9,7 +11,7 @@
* 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) 2023 hkc (@hatkidchan) * Copyright (c) 2023-2025 hkc (@hatkidchan)
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
@ -28,13 +30,13 @@ void ProcessAudio(void *buffer, unsigned int frames)
for (unsigned int frame = 0; frame < frames; frame++) for (unsigned int frame = 0; frame < frames; frame++)
{ {
float *left = &samples[frame * 2 + 0], *right = &samples[frame * 2 + 1]; float *left = &samples[frame*2 + 0], *right = &samples[frame*2 + 1];
*left = powf(fabsf(*left), exponent) * ( (*left < 0.0f)? -1.0f : 1.0f ); *left = powf(fabsf(*left), exponent)*( (*left < 0.0f)? -1.0f : 1.0f );
*right = powf(fabsf(*right), exponent) * ( (*right < 0.0f)? -1.0f : 1.0f ); *right = powf(fabsf(*right), exponent)*( (*right < 0.0f)? -1.0f : 1.0f );
average += fabsf(*left) / frames; // accumulating average volume average += fabsf(*left)/frames; // accumulating average volume
average += fabsf(*right) / frames; average += fabsf(*right)/frames;
} }
// Moving history to the left // Moving history to the left
@ -53,7 +55,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - processing mixed output"); InitWindow(screenWidth, screenHeight, "raylib [audio] example - mixed processor");
InitAudioDevice(); // Initialize audio device InitAudioDevice(); // Initialize audio device
@ -97,7 +99,7 @@ int main(void)
DrawRectangle(199, 199, 402, 34, LIGHTGRAY); DrawRectangle(199, 199, 402, 34, LIGHTGRAY);
for (int i = 0; i < 400; i++) for (int i = 0; i < 400; i++)
{ {
DrawLine(201 + i, 232 - (int)(averageVolume[i] * 32), 201 + i, 232, MAROON); DrawLine(201 + i, 232 - (int)(averageVolume[i]*32), 201 + i, 232, MAROON);
} }
DrawRectangleLines(199, 199, 402, 34, GRAY); DrawRectangleLines(199, 199, 402, 34, GRAY);

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [audio] example - Module playing (streaming) * raylib [audio] example - module playing
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 1.5, last time updated with raylib 3.5 * Example originally created with raylib 1.5, last time updated with raylib 3.5
* *
* 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) 2016-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2016-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -35,7 +37,7 @@ int main(void)
SetConfigFlags(FLAG_MSAA_4X_HINT); // NOTE: Try to enable MSAA 4X SetConfigFlags(FLAG_MSAA_4X_HINT); // NOTE: Try to enable MSAA 4X
InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)"); InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing");
InitAudioDevice(); // Initialize audio device InitAudioDevice(); // Initialize audio device

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [audio] example - Music playing (streaming) * raylib [audio] example - music stream
* *
* Example originally created with raylib 1.3, last time updated with raylib 4.0 * Example complexity rating: [] 1/4
*
* Example originally created with raylib 1.3, last time updated with raylib 4.2
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -23,7 +25,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - music playing (streaming)"); InitWindow(screenWidth, screenHeight, "raylib [audio] example - music stream");
InitAudioDevice(); // Initialize audio device InitAudioDevice(); // Initialize audio device

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [audio] example - Raw audio streaming * raylib [audio] example - raw stream
*
* Example complexity rating: [] 3/4
* *
* Example originally created with raylib 1.6, last time updated with raylib 4.2 * Example originally created with raylib 1.6, last time updated with raylib 4.2
* *
@ -9,7 +11,7 @@
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
* *
********************************************************************************************/ ********************************************************************************************/
@ -60,7 +62,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw audio streaming"); InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream");
InitAudioDevice(); // Initialize audio device InitAudioDevice(); // Initialize audio device
@ -106,8 +108,6 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Sample mouse input.
mousePosition = GetMousePosition(); mousePosition = GetMousePosition();
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
@ -115,7 +115,7 @@ int main(void)
float fp = (float)(mousePosition.y); float fp = (float)(mousePosition.y);
frequency = 40.0f + (float)(fp); frequency = 40.0f + (float)(fp);
float pan = (float)(mousePosition.x) / (float)screenWidth; float pan = (float)(mousePosition.x)/(float)screenWidth;
SetAudioStreamPan(stream, pan); SetAudioStreamPan(stream, pan);
} }
@ -123,7 +123,7 @@ int main(void)
// Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc. // Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc.
if (frequency != oldFrequency) if (frequency != oldFrequency)
{ {
// Compute wavelength. Limit size in both directions. // Compute wavelength. Limit size in both directions
//int oldWavelength = waveLength; //int oldWavelength = waveLength;
waveLength = (int)(22050/frequency); waveLength = (int)(22050/frequency);
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2; if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
@ -141,7 +141,7 @@ int main(void)
} }
// Scale read cursor's position to minimize transition artifacts // Scale read cursor's position to minimize transition artifacts
//readCursor = (int)(readCursor * ((float)waveLength / (float)oldWavelength)); //readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
oldFrequency = frequency; oldFrequency = frequency;
} }

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [audio] example - Sound loading and playing * raylib [audio] example - sound loading
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 1.1, last time updated with raylib 3.5 * Example originally created with raylib 1.1, last time updated with raylib 3.5
* *
* 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) 2014-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -23,7 +25,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound loading and playing"); InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound loading");
InitAudioDevice(); // Initialize audio device InitAudioDevice(); // Initialize audio device

View File

@ -1,13 +1,17 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [audio] example - Playing sound multiple times * raylib [audio] example - sound multi
* *
* Example originally created with raylib 4.6 * Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.0, last time updated with raylib 5.0
*
* Example contributed by Jeffery Myers (@JeffM2501) 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) 2023 Jeffery Myers (@JeffM2501) * Copyright (c) 2023-2025 Jeffery Myers (@JeffM2501)
* *
********************************************************************************************/ ********************************************************************************************/
@ -27,18 +31,18 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - playing sound multiple times"); InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound multi");
InitAudioDevice(); // Initialize audio device InitAudioDevice(); // Initialize audio device
// load the sound list // Load audio file into the first slot as the 'source' sound,
soundArray[0] = LoadSound("resources/sound.wav"); // Load WAV audio file into the first slot as the 'source' sound // this sound owns the sample data
// this sound owns the sample data soundArray[0] = LoadSound("resources/sound.wav");
for (int i = 1; i < MAX_SOUNDS; i++)
{ // Load an alias of the sound into slots 1-9. These do not own the sound data, but can be played
soundArray[i] = LoadSoundAlias(soundArray[0]); // Load an alias of the sound into slots 1-9. These do not own the sound data, but can be played for (int i = 1; i < MAX_SOUNDS; i++) soundArray[i] = LoadSoundAlias(soundArray[0]);
}
currentSound = 0; // set the sound list to the start currentSound = 0; // Set the sound list to the start
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -50,14 +54,15 @@ int main(void)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_SPACE)) if (IsKeyPressed(KEY_SPACE))
{ {
PlaySound(soundArray[currentSound]); // play the next open sound slot PlaySound(soundArray[currentSound]); // Play the next open sound slot
currentSound++; // increment the sound slot currentSound++; // Increment the sound slot
if (currentSound >= MAX_SOUNDS) // if the sound slot is out of bounds, go back to 0
currentSound = 0;
// Note: a better way would be to look at the list for the first sound that is not playing and use that slot // If the sound slot is out of bounds, go back to 0
if (currentSound >= MAX_SOUNDS) currentSound = 0;
// NOTE: Another approach would be to look at the list for the first sound
// that is not playing and use that slot
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -74,9 +79,8 @@ int main(void)
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
for (int i = 1; i < MAX_SOUNDS; i++) for (int i = 1; i < MAX_SOUNDS; i++) UnloadSoundAlias(soundArray[i]); // Unload sound aliases
UnloadSoundAlias(soundArray[i]); // Unload sound aliases UnloadSound(soundArray[0]); // Unload source sound data
UnloadSound(soundArray[0]); // Unload source sound data
CloseAudioDevice(); // Close audio device CloseAudioDevice(); // Close audio device

View File

@ -0,0 +1,128 @@
/*******************************************************************************************
*
* raylib [audio] example - sound positioning
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.5
*
* Example contributed by Le Juez Victor (@Bigfoot71) 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 Le Juez Victor (@Bigfoot71)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static void SetSoundPosition(Camera listener, Sound sound, Vector3 position, float maxDist);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound positioning");
InitAudioDevice();
Sound sound = LoadSound("resources/coin.wav");
Camera camera = {
.position = (Vector3) { 0, 5, 5 },
.target = (Vector3) { 0, 0, 0 },
.up = (Vector3) { 0, 1, 0 },
.fovy = 60,
.projection = CAMERA_PERSPECTIVE
};
DisableCursor();
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera, CAMERA_FREE);
float th = GetTime();
Vector3 spherePos = {
.x = 5.0f*cosf(th),
.y = 0.0f,
.z = 5.0f*sinf(th)
};
SetSoundPosition(camera, sound, spherePos, 20.0f);
if (!IsSoundPlaying(sound)) PlaySound(sound);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawGrid(10, 2);
DrawSphere(spherePos, 0.5f, RED);
EndMode3D();
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadSound(sound);
CloseAudioDevice(); // Close audio device
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
// Set sound 3d position
static void SetSoundPosition(Camera listener, Sound sound, Vector3 position, float maxDist)
{
// Calculate direction vector and distance between listener and sound source
Vector3 direction = Vector3Subtract(position, listener.position);
float distance = Vector3Length(direction);
// Apply logarithmic distance attenuation and clamp between 0-1
float attenuation = 1.0f/(1.0f + (distance/maxDist));
attenuation = Clamp(attenuation, 0.0f, 1.0f);
// Calculate normalized vectors for spatial positioning
Vector3 normalizedDirection = Vector3Normalize(direction);
Vector3 forward = Vector3Normalize(Vector3Subtract(listener.target, listener.position));
Vector3 right = Vector3Normalize(Vector3CrossProduct(listener.up, forward));
// Reduce volume for sounds behind the listener
float dotProduct = Vector3DotProduct(forward, normalizedDirection);
if (dotProduct < 0.0f) attenuation *= (1.0f + dotProduct*0.5f);
// Set stereo panning based on sound position relative to listener
float pan = 0.5f + 0.5f*Vector3DotProduct(normalizedDirection, right);
// Apply final sound properties
SetSoundVolume(sound, attenuation);
SetSoundPan(sound, pan);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [audio] example - Music stream processing effects * raylib [audio] example - stream effects
*
* Example complexity rating: [] 4/4
* *
* Example originally created with raylib 4.2, last time updated with raylib 5.0 * Example originally created with raylib 4.2, last time updated with raylib 5.0
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2022-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2022-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -15,7 +17,9 @@
#include <stdlib.h> // Required for: NULL #include <stdlib.h> // Required for: NULL
// Required delay effect variables //----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static float *delayBuffer = NULL; static float *delayBuffer = NULL;
static unsigned int delayBufferSize = 0; static unsigned int delayBufferSize = 0;
static unsigned int delayReadIndex = 2; static unsigned int delayReadIndex = 2;
@ -146,8 +150,8 @@ int main(void)
static void AudioProcessEffectLPF(void *buffer, unsigned int frames) static void AudioProcessEffectLPF(void *buffer, unsigned int frames)
{ {
static float low[2] = { 0.0f, 0.0f }; static float low[2] = { 0.0f, 0.0f };
static const float cutoff = 70.0f / 44100.0f; // 70 Hz lowpass filter static const float cutoff = 70.0f/44100.0f; // 70 Hz lowpass filter
const float k = cutoff / (cutoff + 0.1591549431f); // RC filter formula const float k = cutoff/(cutoff + 0.1591549431f); // RC filter formula
// Converts the buffer data before using it // Converts the buffer data before using it
float *bufferData = (float *)buffer; float *bufferData = (float *)buffer;
@ -156,8 +160,8 @@ static void AudioProcessEffectLPF(void *buffer, unsigned int frames)
const float l = bufferData[i]; const float l = bufferData[i];
const float r = bufferData[i + 1]; const float r = bufferData[i + 1];
low[0] += k * (l - low[0]); low[0] += k*(l - low[0]);
low[1] += k * (r - low[1]); low[1] += k*(r - low[1]);
bufferData[i] = low[0]; bufferData[i] = low[0];
bufferData[i + 1] = low[1]; bufferData[i + 1] = low[1];
} }

View File

@ -1,110 +0,0 @@
const std = @import("std");
const builtin = @import("builtin");
// This has been tested to work with zig 0.12.0
fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) !*std.Build.Step {
if (target.result.os.tag == .emscripten) {
@panic("Emscripten building via Zig unsupported");
}
const all = b.step(module, "All " ++ module ++ " examples");
var dir = try std.fs.cwd().openDir(module, .{ .iterate = true });
defer if (comptime builtin.zig_version.minor >= 12) dir.close();
var iter = dir.iterate();
while (try iter.next()) |entry| {
if (entry.kind != .file) continue;
const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue;
const name = entry.name[0..extension_idx];
const path = try std.fs.path.join(b.allocator, &.{ module, entry.name });
// 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;
const exe = b.addExecutable(.{
.name = name,
.target = target,
.optimize = optimize,
});
exe.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
exe.linkLibC();
exe.addObjectFile(switch (target.result.os.tag) {
.windows => b.path("../zig-out/lib/raylib.lib"),
.linux => b.path("../zig-out/lib/libraylib.a"),
.macos => b.path("../zig-out/lib/libraylib.a"),
.emscripten => b.path("../zig-out/lib/libraylib.a"),
else => @panic("Unsupported OS"),
});
exe.addIncludePath(b.path("../src"));
exe.addIncludePath(b.path("../src/external"));
exe.addIncludePath(b.path("../src/external/glfw/include"));
switch (target.result.os.tag) {
.windows => {
exe.linkSystemLibrary("winmm");
exe.linkSystemLibrary("gdi32");
exe.linkSystemLibrary("opengl32");
exe.defineCMacro("PLATFORM_DESKTOP", null);
},
.linux => {
exe.linkSystemLibrary("GL");
exe.linkSystemLibrary("rt");
exe.linkSystemLibrary("dl");
exe.linkSystemLibrary("m");
exe.linkSystemLibrary("X11");
exe.defineCMacro("PLATFORM_DESKTOP", null);
},
.macos => {
exe.linkFramework("Foundation");
exe.linkFramework("Cocoa");
exe.linkFramework("OpenGL");
exe.linkFramework("CoreAudio");
exe.linkFramework("CoreVideo");
exe.linkFramework("IOKit");
exe.defineCMacro("PLATFORM_DESKTOP", null);
},
else => {
@panic("Unsupported OS");
},
}
const install_cmd = b.addInstallArtifact(exe, .{});
const run_cmd = b.addRunArtifact(exe);
run_cmd.cwd = b.path(module);
run_cmd.step.dependOn(&install_cmd.step);
const run_step = b.step(name, name);
run_step.dependOn(&run_cmd.step);
all.dependOn(&install_cmd.step);
}
return all;
}
pub fn build(b: *std.Build) !void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard optimization options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
// set a preferred release mode, allowing the user to decide how to optimize.
const optimize = b.standardOptimizeOption(.{});
const all = b.getInstallStep();
all.dependOn(try add_module("audio", b, target, optimize));
all.dependOn(try add_module("core", b, target, optimize));
all.dependOn(try add_module("models", b, target, optimize));
all.dependOn(try add_module("others", b, target, optimize));
all.dependOn(try add_module("shaders", b, target, optimize));
all.dependOn(try add_module("shapes", b, target, optimize));
all.dependOn(try add_module("text", b, target, optimize));
all.dependOn(try add_module("textures", b, target, optimize));
}

View File

@ -0,0 +1,44 @@
::@echo off
:: .
:: Compile your examples for web using: build_example_web.bat <example_category>/<example_name>
:: .
SET "INPUT_FILE=%1"
:: Change delimiter for the FOR loop
FOR /f "tokens=1-10 delims=/" %%a IN ("%INPUT_FILE%") DO (
SET CATEGORY=%%a
SET FILENAME=%%b
)
:: > SETup required Environment
:: -------------------------------------
SET RAYLIB_PATH=C:\GitHub\raylib
SET EMSDK_PATH=C:\raylib\emsdk
SET COMPILER_PATH=C:\raylib\w64devkit\bin
ENV_SET PATH=%COMPILER_PATH%
SET MAKE=mingw32-make
echo
:: Set required web compilation options
:: -------------------------------------
::SET CC=%EMSDK_PATH%\upstream\emscripten\emcc
::SET CFLAGS=-Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result -O3 -I. -Iexternal -I%RAYLIB_PATH%\src -I%RAYLIB_PATH%\external -DPLATFORM_WEB
::SET LDFLAGS=-L. -L$(RAYLIB_PATH)\src -sUSE_GLFW=3 -sEXPORTED_RUNTIME_METHODS=ccall -sASYNCIFY --shell-file %RAYLIB_PATH%\src\shell.html
::SET LDLIBS=%RAYLIB_PATH%\src\libraylib.web.a
echo
:: Clean latest build
:: ------------------------
cmd /c if exist %FILENAME%.html del /F %FILENAME%.html
cmd /c if exist %FILENAME%.wasm del /F %FILENAME%.wasm
cmd /c if exist %FILENAME%.js del /F %FILENAME%.js
cmd /c if exist %FILENAME%.data del /F %FILENAME%.data
echo
:: Setup emsdk environment
:: --------------------------
call %EMSDK_PATH%\emsdk_env.bat
echo on
:: Compile program
:: -----------------------
C:
cd %RAYLIB_PATH%\examples
%MAKE% -f Makefile.Web %CATEGORY%/%FILENAME% PLATFORM=PLATFORM_WEB -B
::%CC% -o %FILENAME%.html %FILENAME%.c %CFLAGS% %LDFLAGS% %LDLIBS% %RESOURCES%
cd ..
echo

View File

@ -1,17 +1,20 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - 2D Camera system * raylib [core] example - 2d camera
*
* Example complexity rating: [] 2/4
* *
* Example originally created with raylib 1.5, last time updated with raylib 3.0 * Example originally created with raylib 1.5, last time updated with raylib 3.0
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2016-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2016-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include <math.h>
#define MAX_BUILDINGS 100 #define MAX_BUILDINGS 100
@ -42,7 +45,11 @@ int main(void)
spacing += (int)buildings[i].width; spacing += (int)buildings[i].width;
buildColors[i] = (Color){ GetRandomValue(200, 240), GetRandomValue(200, 240), GetRandomValue(200, 250), 255 }; buildColors[i] = (Color){
(unsigned char)GetRandomValue(200, 240),
(unsigned char)GetRandomValue(200, 240),
(unsigned char)GetRandomValue(200, 250),
255};
} }
Camera2D camera = { 0 }; Camera2D camera = { 0 };
@ -75,7 +82,8 @@ int main(void)
else if (camera.rotation < -40) camera.rotation = -40; else if (camera.rotation < -40) camera.rotation = -40;
// Camera zoom controls // Camera zoom controls
camera.zoom += ((float)GetMouseWheelMove()*0.05f); // Uses log scaling to provide consistent zoom speed
camera.zoom = expf(logf(camera.zoom) + ((float)GetMouseWheelMove()*0.1f));
if (camera.zoom > 3.0f) camera.zoom = 3.0f; if (camera.zoom > 3.0f) camera.zoom = 3.0f;
else if (camera.zoom < 0.1f) camera.zoom = 0.1f; else if (camera.zoom < 0.1f) camera.zoom = 0.1f;

View File

@ -2,12 +2,16 @@
* *
* raylib [core] example - 2d camera mouse zoom * raylib [core] example - 2d camera mouse zoom
* *
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 4.2, last time updated with raylib 4.2 * Example originally created with raylib 4.2, last time updated with raylib 4.2
* *
* Example contributed by Jeffery Myers (@JeffM2501) 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) 2022-2024 Jeffery Myers (@JeffM2501) * Copyright (c) 2022-2025 Jeffery Myers (@JeffM2501)
* *
********************************************************************************************/ ********************************************************************************************/
@ -69,9 +73,9 @@ int main ()
camera.target = mouseWorldPos; camera.target = mouseWorldPos;
// Zoom increment // Zoom increment
float scaleFactor = 1.0f + (0.25f*fabsf(wheel)); // Uses log scaling to provide consistent zoom speed
if (wheel < 0) scaleFactor = 1.0f/scaleFactor; float scale = 0.2f*wheel;
camera.zoom = Clamp(camera.zoom*scaleFactor, 0.125f, 64.0f); camera.zoom = Clamp(expf(logf(camera.zoom)+scale), 0.125f, 64.0f);
} }
} }
else else
@ -92,10 +96,10 @@ int main ()
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
{ {
// Zoom increment // Zoom increment
// Uses log scaling to provide consistent zoom speed
float deltaX = GetMouseDelta().x; float deltaX = GetMouseDelta().x;
float scaleFactor = 1.0f + (0.01f*fabsf(deltaX)); float scale = 0.005f*deltaX;
if (deltaX < 0) scaleFactor = 1.0f/scaleFactor; camera.zoom = Clamp(expf(logf(camera.zoom)+scale), 0.125f, 64.0f);
camera.zoom = Clamp(camera.zoom*scaleFactor, 0.125f, 64.0f);
} }
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - 2D Camera platformer * raylib [core] example - 2d camera platformer
*
* Example complexity rating: [] 3/4
* *
* Example originally created with raylib 2.5, last time updated with raylib 3.0 * Example originally created with raylib 2.5, last time updated with raylib 3.0
* *
@ -9,7 +11,7 @@
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2019-2024 arvyy (@arvyy) * Copyright (c) 2019-2025 arvyy (@arvyy)
* *
********************************************************************************************/ ********************************************************************************************/
@ -20,6 +22,9 @@
#define PLAYER_JUMP_SPD 350.0f #define PLAYER_JUMP_SPD 350.0f
#define PLAYER_HOR_SPD 200.0f #define PLAYER_HOR_SPD 200.0f
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct Player { typedef struct Player {
Vector2 position; Vector2 position;
float speed; float speed;
@ -33,7 +38,7 @@ typedef struct EnvItem {
} EnvItem; } EnvItem;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module functions declaration // Module Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
void UpdatePlayer(Player *player, EnvItem *envItems, int envItemsLength, float delta); void UpdatePlayer(Player *player, EnvItem *envItems, int envItemsLength, float delta);
void UpdateCameraCenter(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height); void UpdateCameraCenter(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
@ -52,7 +57,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera"); InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera platformer");
Player player = { 0 }; Player player = { 0 };
player.position = (Vector2){ 400, 280 }; player.position = (Vector2){ 400, 280 };
@ -292,7 +297,7 @@ void UpdateCameraPlayerBoundsPush(Camera2D *camera, Player *player, EnvItem *env
Vector2 bboxWorldMin = GetScreenToWorld2D((Vector2){ (1 - bbox.x)*0.5f*width, (1 - bbox.y)*0.5f*height }, *camera); Vector2 bboxWorldMin = GetScreenToWorld2D((Vector2){ (1 - bbox.x)*0.5f*width, (1 - bbox.y)*0.5f*height }, *camera);
Vector2 bboxWorldMax = GetScreenToWorld2D((Vector2){ (1 + bbox.x)*0.5f*width, (1 + bbox.y)*0.5f*height }, *camera); Vector2 bboxWorldMax = GetScreenToWorld2D((Vector2){ (1 + bbox.x)*0.5f*width, (1 + bbox.y)*0.5f*height }, *camera);
camera->offset = (Vector2){ (1 - bbox.x)*0.5f * width, (1 - bbox.y)*0.5f*height }; camera->offset = (Vector2){ (1 - bbox.x)*0.5f*width, (1 - bbox.y)*0.5f*height };
if (player->position.x < bboxWorldMin.x) camera->target.x = player->position.x; if (player->position.x < bboxWorldMin.x) camera->target.x = player->position.x;
if (player->position.y < bboxWorldMin.y) camera->target.y = player->position.y; if (player->position.y < bboxWorldMin.y) camera->target.y = player->position.y;

View File

@ -2,6 +2,8 @@
* *
* raylib [core] example - 2d camera split screen * raylib [core] example - 2d camera split screen
* *
* Example complexity rating: [] 4/4
*
* Addapted from the core_3d_camera_split_screen example: * Addapted from the core_3d_camera_split_screen example:
* https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_split_screen.c * https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_split_screen.c
* *
@ -12,7 +14,7 @@
* 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) 2023 Gabriel dos Santos Sanches (@gabrielssanches) * Copyright (c) 2023-2025 Gabriel dos Santos Sanches (@gabrielssanches)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -2,12 +2,14 @@
* *
* raylib [core] example - 3d camera first person * raylib [core] example - 3d camera first person
* *
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 1.3, last time updated with raylib 1.3 * Example originally created with raylib 1.3, last time updated with raylib 1.3
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -98,8 +100,8 @@ int main(void)
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
camera.projection = CAMERA_ORTHOGRAPHIC; camera.projection = CAMERA_ORTHOGRAPHIC;
camera.fovy = 20.0f; // near plane width in CAMERA_ORTHOGRAPHIC camera.fovy = 20.0f; // near plane width in CAMERA_ORTHOGRAPHIC
CameraYaw(&camera, -135 * DEG2RAD, true); CameraYaw(&camera, -135*DEG2RAD, true);
CameraPitch(&camera, -45 * DEG2RAD, true, true, false); CameraPitch(&camera, -45*DEG2RAD, true, true, false);
} }
else if (camera.projection == CAMERA_ORTHOGRAPHIC) else if (camera.projection == CAMERA_ORTHOGRAPHIC)
{ {

View File

@ -0,0 +1,329 @@
/*******************************************************************************************
*
* raylib [core] example - 3d camera fps
*
* Example complexity rating: [] 3/4
*
* 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 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 Aldins (@nezvers)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
// Movement constants
#define GRAVITY 32.0f
#define MAX_SPEED 20.0f
#define CROUCH_SPEED 5.0f
#define JUMP_FORCE 12.0f
#define MAX_ACCEL 150.0f
// Grounded drag
#define FRICTION 0.86f
// Increasing air drag, increases strafing speed
#define AIR_DRAG 0.98f
// Responsiveness for turning movement direction to looked direction
#define CONTROL 15.0f
#define CROUCH_HEIGHT 0.0f
#define STAND_HEIGHT 1.0f
#define BOTTOM_HEIGHT 0.5f
#define NORMALIZE_INPUT 0
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Body structure
typedef struct {
Vector3 position;
Vector3 velocity;
Vector3 dir;
bool isGrounded;
} Body;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
static Vector2 sensitivity = { 0.001f, 0.001f };
static Body player = { 0 };
static Vector2 lookRotation = { 0 };
static float headTimer = 0.0f;
static float walkLerp = 0.0f;
static float headLerp = STAND_HEIGHT;
static Vector2 lean = { 0 };
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
static void DrawLevel(void);
static void UpdateCameraFPS(Camera *camera);
static void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed, bool crouchHold);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera fps");
// Initialize camera variables
// NOTE: UpdateCameraFPS() takes care of the rest
Camera camera = { 0 };
camera.fovy = 60.0f;
camera.projection = CAMERA_PERSPECTIVE;
camera.position = (Vector3){
player.position.x,
player.position.y + (BOTTOM_HEIGHT + headLerp),
player.position.z,
};
UpdateCameraFPS(&camera); // Update camera parameters
DisableCursor(); // Limit cursor to relative movement inside the window
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
//----------------------------------------------------------------------------------
Vector2 mouseDelta = GetMouseDelta();
lookRotation.x -= mouseDelta.x*sensitivity.x;
lookRotation.y += mouseDelta.y*sensitivity.y;
char sideway = (IsKeyDown(KEY_D) - IsKeyDown(KEY_A));
char forward = (IsKeyDown(KEY_W) - IsKeyDown(KEY_S));
bool crouching = IsKeyDown(KEY_LEFT_CONTROL);
UpdateBody(&player, lookRotation.x, sideway, forward, IsKeyPressed(KEY_SPACE), crouching);
float delta = GetFrameTime();
headLerp = Lerp(headLerp, (crouching ? CROUCH_HEIGHT : STAND_HEIGHT), 20.0f*delta);
camera.position = (Vector3){
player.position.x,
player.position.y + (BOTTOM_HEIGHT + headLerp),
player.position.z,
};
if (player.isGrounded && ((forward != 0) || (sideway != 0)))
{
headTimer += delta*3.0f;
walkLerp = Lerp(walkLerp, 1.0f, 10.0f*delta);
camera.fovy = Lerp(camera.fovy, 55.0f, 5.0f*delta);
}
else
{
walkLerp = Lerp(walkLerp, 0.0f, 10.0f*delta);
camera.fovy = Lerp(camera.fovy, 60.0f, 5.0f*delta);
}
lean.x = Lerp(lean.x, sideway*0.02f, 10.0f*delta);
lean.y = Lerp(lean.y, forward*0.015f, 10.0f*delta);
UpdateCameraFPS(&camera);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawLevel();
EndMode3D();
// Draw info box
DrawRectangle(5, 5, 330, 75, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(5, 5, 330, 75, BLUE);
DrawText("Camera controls:", 15, 15, 10, BLACK);
DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, BLACK);
DrawText("- Look around: arrow keys or mouse", 15, 45, 10, BLACK);
DrawText(TextFormat("- Velocity Len: (%06.3f)", Vector2Length((Vector2){ player.velocity.x, player.velocity.z })), 15, 60, 10, BLACK);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Update body considering current world state
void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed, bool crouchHold)
{
Vector2 input = (Vector2){ (float)side, (float)-forward };
#if defined(NORMALIZE_INPUT)
// Slow down diagonal movement
if ((side != 0) && (forward != 0)) input = Vector2Normalize(input);
#endif
float delta = GetFrameTime();
if (!body->isGrounded) body->velocity.y -= GRAVITY*delta;
if (body->isGrounded && jumpPressed)
{
body->velocity.y = JUMP_FORCE;
body->isGrounded = false;
// Sound can be played at this moment
//SetSoundPitch(fxJump, 1.0f + (GetRandomValue(-100, 100)*0.001));
//PlaySound(fxJump);
}
Vector3 front = (Vector3){ sin(rot), 0.f, cos(rot) };
Vector3 right = (Vector3){ cos(-rot), 0.f, sin(-rot) };
Vector3 desiredDir = (Vector3){ input.x*right.x + input.y*front.x, 0.0f, input.x*right.z + input.y*front.z, };
body->dir = Vector3Lerp(body->dir, desiredDir, CONTROL*delta);
float decel = (body->isGrounded ? FRICTION : AIR_DRAG);
Vector3 hvel = (Vector3){ body->velocity.x*decel, 0.0f, body->velocity.z*decel };
float hvelLength = Vector3Length(hvel); // Magnitude
if (hvelLength < (MAX_SPEED*0.01f)) hvel = (Vector3){ 0 };
// This is what creates strafing
float speed = Vector3DotProduct(hvel, body->dir);
// Whenever the amount of acceleration to add is clamped by the maximum acceleration constant,
// a Player can make the speed faster by bringing the direction closer to horizontal velocity angle
// More info here: https://youtu.be/v3zT3Z5apaM?t=165
float maxSpeed = (crouchHold? CROUCH_SPEED : MAX_SPEED);
float accel = Clamp(maxSpeed - speed, 0.f, MAX_ACCEL*delta);
hvel.x += body->dir.x*accel;
hvel.z += body->dir.z*accel;
body->velocity.x = hvel.x;
body->velocity.z = hvel.z;
body->position.x += body->velocity.x*delta;
body->position.y += body->velocity.y*delta;
body->position.z += body->velocity.z*delta;
// Fancy collision system against the floor
if (body->position.y <= 0.0f)
{
body->position.y = 0.0f;
body->velocity.y = 0.0f;
body->isGrounded = true; // Enable jumping
}
}
// Update camera for FPS behaviour
static void UpdateCameraFPS(Camera *camera)
{
const Vector3 up = (Vector3){ 0.0f, 1.0f, 0.0f };
const Vector3 targetOffset = (Vector3){ 0.0f, 0.0f, -1.0f };
// Left and right
Vector3 yaw = Vector3RotateByAxisAngle(targetOffset, up, lookRotation.x);
// Clamp view up
float maxAngleUp = Vector3Angle(up, yaw);
maxAngleUp -= 0.001f; // Avoid numerical errors
if ( -(lookRotation.y) > maxAngleUp) { lookRotation.y = -maxAngleUp; }
// Clamp view down
float maxAngleDown = Vector3Angle(Vector3Negate(up), yaw);
maxAngleDown *= -1.0f; // Downwards angle is negative
maxAngleDown += 0.001f; // Avoid numerical errors
if ( -(lookRotation.y) < maxAngleDown) { lookRotation.y = -maxAngleDown; }
// Up and down
Vector3 right = Vector3Normalize(Vector3CrossProduct(yaw, up));
// Rotate view vector around right axis
float pitchAngle = -lookRotation.y - lean.y;
pitchAngle = Clamp(pitchAngle, -PI/2 + 0.0001f, PI/2 - 0.0001f); // Clamp angle so it doesn't go past straight up or straight down
Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, pitchAngle);
// Head animation
// Rotate up direction around forward axis
float headSin = sin(headTimer*PI);
float headCos = cos(headTimer*PI);
const float stepRotation = 0.01f;
camera->up = Vector3RotateByAxisAngle(up, pitch, headSin*stepRotation + lean.x);
// Camera BOB
const float bobSide = 0.1f;
const float bobUp = 0.15f;
Vector3 bobbing = Vector3Scale(right, headSin*bobSide);
bobbing.y = fabsf(headCos*bobUp);
camera->position = Vector3Add(camera->position, Vector3Scale(bobbing, walkLerp));
camera->target = Vector3Add(camera->position, pitch);
}
// Draw game level
static void DrawLevel(void)
{
const int floorExtent = 25;
const float tileSize = 5.0f;
const Color tileColor1 = (Color){ 150, 200, 200, 255 };
// Floor tiles
for (int y = -floorExtent; y < floorExtent; y++)
{
for (int x = -floorExtent; x < floorExtent; x++)
{
if ((y & 1) && (x & 1))
{
DrawPlane((Vector3){ x*tileSize, 0.0f, y*tileSize}, (Vector2){ tileSize, tileSize }, tileColor1);
}
else if (!(y & 1) && !(x & 1))
{
DrawPlane((Vector3){ x*tileSize, 0.0f, y*tileSize}, (Vector2){ tileSize, tileSize }, LIGHTGRAY);
}
}
}
const Vector3 towerSize = (Vector3){ 16.0f, 32.0f, 16.0f };
const Color towerColor = (Color){ 150, 200, 200, 255 };
Vector3 towerPos = (Vector3){ 16.0f, 16.0f, 16.0f };
DrawCubeV(towerPos, towerSize, towerColor);
DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
towerPos.x *= -1;
DrawCubeV(towerPos, towerSize, towerColor);
DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
towerPos.z *= -1;
DrawCubeV(towerPos, towerSize, towerColor);
DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
towerPos.x *= -1;
DrawCubeV(towerPos, towerSize, towerColor);
DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
// Red sun
DrawSphere((Vector3){ 300.0f, 300.0f, 0.0f }, 100.0f, (Color){ 255, 0, 0, 255 });
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Initialize 3d camera free * raylib [core] example - 3d camera free
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 1.3, last time updated with raylib 1.3 * Example originally created with raylib 1.3, last time updated with raylib 1.3
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Initialize 3d camera mode * raylib [core] example - 3d camera mode
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 1.0, last time updated with raylib 1.0 * Example originally created with raylib 1.0, last time updated with raylib 1.0
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - 3d cmaera split screen * raylib [core] example - 3d camera split screen
*
* Example complexity rating: [] 3/4
* *
* Example originally created with raylib 3.7, last time updated with raylib 4.0 * Example originally created with raylib 3.7, last time updated with raylib 4.0
* *
@ -9,7 +11,7 @@
* 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) 2021-2024 Jeffery Myers (@JeffM2501) * Copyright (c) 2021-2025 Jeffery Myers (@JeffM2501)
* *
********************************************************************************************/ ********************************************************************************************/
@ -45,7 +47,7 @@ int main(void)
cameraPlayer2.position.x = -3.0f; cameraPlayer2.position.x = -3.0f;
cameraPlayer2.position.y = 3.0f; cameraPlayer2.position.y = 3.0f;
RenderTexture screenPlayer2 = LoadRenderTexture(screenWidth / 2, screenHeight); RenderTexture screenPlayer2 = LoadRenderTexture(screenWidth/2, screenHeight);
// Build a flipped rectangle the size of the split view to use for drawing later // Build a flipped rectangle the size of the split view to use for drawing later
Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenPlayer1.texture.width, (float)-screenPlayer1.texture.height }; Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenPlayer1.texture.width, (float)-screenPlayer1.texture.height };
@ -63,7 +65,7 @@ int main(void)
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// If anyone moves this frame, how far will they move based on the time since the last frame // If anyone moves this frame, how far will they move based on the time since the last frame
// this moves thigns at 10 world units per second, regardless of the actual FPS // this moves things at 10 world units per second, regardless of the actual FPS
float offsetThisFrame = 10.0f*GetFrameTime(); float offsetThisFrame = 10.0f*GetFrameTime();
// Move Player1 forward and backwards (no turning) // Move Player1 forward and backwards (no turning)

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Picking in 3d mode * raylib [core] example - 3d picking
*
* Example complexity rating: [] 2/4
* *
* Example originally created with raylib 1.3, last time updated with raylib 4.0 * Example originally created with raylib 1.3, last time updated with raylib 4.0
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -99,7 +101,7 @@ int main(void)
DrawText("Try clicking on the box with your mouse!", 240, 10, 20, DARKGRAY); DrawText("Try clicking on the box with your mouse!", 240, 10, 20, DARKGRAY);
if (collision.hit) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, (int)(screenHeight * 0.1f), 30, GREEN); if (collision.hit) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30))/2, (int)(screenHeight*0.1f), 30, GREEN);
DrawText("Right click mouse to toggle camera controls", 10, 430, 10, GRAY); DrawText("Right click mouse to toggle camera controls", 10, 430, 10, GRAY);

View File

@ -2,6 +2,8 @@
* *
* raylib [core] example - automation events * raylib [core] example - automation events
* *
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 5.0, last time updated with raylib 5.0 * Example originally created with raylib 5.0, last time updated with raylib 5.0
* *
* Example based on 2d_camera_platformer example by arvyy (@arvyy) * Example based on 2d_camera_platformer example by arvyy (@arvyy)
@ -9,7 +11,7 @@
* 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) 2023 Ramon Santamaria (@raysan5) * Copyright (c) 2023-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -22,6 +24,9 @@
#define MAX_ENVIRONMENT_ELEMENTS 5 #define MAX_ENVIRONMENT_ELEMENTS 5
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct Player { typedef struct Player {
Vector2 position; Vector2 position;
float speed; float speed;
@ -34,7 +39,6 @@ typedef struct EnvElement {
Color color; Color color;
} EnvElement; } EnvElement;
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] examples - basic screen manager * raylib [core] example - basic screen manager
*
* Example complexity rating: [] 1/4
* *
* NOTE: This example illustrates a very simple screen manager based on a states machines * NOTE: This example illustrates a very simple screen manager based on a states machines
* *
@ -9,7 +11,7 @@
* 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) 2021-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2021-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -46,7 +48,7 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
switch(currentScreen) switch (currentScreen)
{ {
case LOGO: case LOGO:
{ {

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Basic window * raylib [core] example - basic window
*
* Example complexity rating: [] 1/4
* *
* Welcome to raylib! * Welcome to raylib!
* *
@ -20,7 +22,7 @@
* 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) 2013-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -1,87 +0,0 @@
/*******************************************************************************************
*
* raylib [core] example - Basic window (adapted for HTML5 platform)
*
* NOTE: This example is prepared to compile for PLATFORM_WEB, and PLATFORM_DESKTOP
* As you will notice, code structure is slightly diferent to the other examples...
* To compile it for PLATFORM_WEB just uncomment #define PLATFORM_WEB at beginning
*
* Example originally created with raylib 1.3, last time updated with raylib 1.3
*
* 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) 2015-2024 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
//#define PLATFORM_WEB
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#endif
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
//----------------------------------------------------------------------------------
// Module functions declaration
//----------------------------------------------------------------------------------
void UpdateDrawFrame(void); // Update and Draw one frame
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
#if defined(PLATFORM_WEB)
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
UpdateDrawFrame();
}
#endif
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
void UpdateDrawFrame(void)
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}

View File

@ -2,6 +2,8 @@
* *
* raylib [core] example - custom frame control * raylib [core] example - custom frame control
* *
* Example complexity rating: [] 4/4
*
* NOTE: WARNING: This is an example for advanced users willing to have full control over * NOTE: WARNING: This is an example for advanced users willing to have full control over
* the frame processes. By default, EndDrawing() calls the following processes: * the frame processes. By default, EndDrawing() calls the following processes:
* 1. Draw remaining batch data: rlDrawRenderBatchActive() * 1. Draw remaining batch data: rlDrawRenderBatchActive()
@ -10,7 +12,7 @@
* 4. PollInputEvents() * 4. PollInputEvents()
* *
* To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in * To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in
* config.h (it requires recompiling raylib). This way those steps are up to the user. * config.h (it requires recompiling raylib). This way those steps are up to the user
* *
* Note that enabling this flag invalidates some functions: * Note that enabling this flag invalidates some functions:
* - GetFrameTime() * - GetFrameTime()
@ -22,7 +24,7 @@
* 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) 2021-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2021-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -59,7 +61,9 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
PollInputEvents(); // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL) #ifndef PLATFORM_WEB // NOTE: On non web platforms the PollInputEvents just works before the inputs checks
PollInputEvents(); // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL)
#endif
if (IsKeyPressed(KEY_SPACE)) pause = !pause; if (IsKeyPressed(KEY_SPACE)) pause = !pause;
@ -74,6 +78,10 @@ int main(void)
if (position >= GetScreenWidth()) position = 0; if (position >= GetScreenWidth()) position = 0;
timeCounter += deltaTime; // We count time (seconds) timeCounter += deltaTime; // We count time (seconds)
} }
#ifdef PLATFORM_WEB // NOTE: On web platform for some reason the PollInputEvents only works after the inputs check, so just call it after check all your inputs (on web)
PollInputEvents(); // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL)
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -93,7 +101,10 @@ int main(void)
DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 60, 20, GRAY); DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 60, 20, GRAY);
DrawText("PRESS UP | DOWN to CHANGE TARGET FPS", 10, GetScreenHeight() - 30, 20, GRAY); DrawText("PRESS UP | DOWN to CHANGE TARGET FPS", 10, GetScreenHeight() - 30, 20, GRAY);
DrawText(TextFormat("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME); DrawText(TextFormat("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME);
DrawText(TextFormat("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN); if (deltaTime != 0)
{
DrawText(TextFormat("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN);
}
EndDrawing(); EndDrawing();

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Custom logging * raylib [core] example - custom logging
*
* Example complexity rating: [] 3/4
* *
* Example originally created with raylib 2.5, last time updated with raylib 2.5 * Example originally created with raylib 2.5, last time updated with raylib 2.5
* *
@ -9,7 +11,7 @@
* 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) 2018-2024 Pablo Marcos Oltra (@pamarcos) and Ramon Santamaria (@raysan5) * Copyright (c) 2018-2025 Pablo Marcos Oltra (@pamarcos) and Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Windows drop files * raylib [core] example - drop files
*
* Example complexity rating: [] 2/4
* *
* NOTE: This example only works on platforms that support drag & drop (Windows, Linux, OSX, Html5?) * NOTE: This example only works on platforms that support drag & drop (Windows, Linux, OSX, Html5?)
* *
@ -9,7 +11,7 @@
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -0,0 +1,134 @@
/*******************************************************************************************
*
* raylib [core] example - high dpi
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.0, last time updated with raylib 5.5
*
* Example contributed by Jonathan Marler (@marler8997) 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 Jonathan Marler (@marler8997)
*
********************************************************************************************/
#include "raylib.h"
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static void DrawTextCenter(const char *text, int x, int y, int fontSize, Color color);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
InitWindow(screenWidth, screenHeight, "raylib [core] example - high dpi");
SetWindowMinSize(450, 450);
int logicalGridDescY = 120;
int logicalGridLabelY = logicalGridDescY + 30;
int logicalGridTop = logicalGridLabelY + 30;
int logicalGridBottom = logicalGridTop + 80;
int pixelGridTop = logicalGridBottom - 20;
int pixelGridBottom = pixelGridTop + 80;
int pixelGridLabelY = pixelGridBottom + 30;
int pixelGridDescY = pixelGridLabelY + 30;
int cellSize = 50;
float cellSizePx = (float)cellSize;
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
//----------------------------------------------------------------------------------
int monitorCount = GetMonitorCount();
if ((monitorCount > 1) && IsKeyPressed(KEY_N))
{
SetWindowMonitor((GetCurrentMonitor() + 1)%monitorCount);
}
int currentMonitor = GetCurrentMonitor();
Vector2 dpiScale = GetWindowScaleDPI();
cellSizePx = ((float)cellSize)/dpiScale.x;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
int windowCenter = GetScreenWidth()/2;
DrawTextCenter(TextFormat("Dpi Scale: %f", dpiScale.x), windowCenter, 30, 40, DARKGRAY);
DrawTextCenter(TextFormat("Monitor: %d/%d ([N] next monitor)", currentMonitor+1, monitorCount), windowCenter, 70, 20, LIGHTGRAY);
DrawTextCenter(TextFormat("Window is %d \"logical points\" wide", GetScreenWidth()), windowCenter, logicalGridDescY, 20, ORANGE);
bool odd = true;
for (int i = cellSize; i < GetScreenWidth(); i += cellSize, odd = !odd)
{
if (odd) DrawRectangle(i, logicalGridTop, cellSize, logicalGridBottom-logicalGridTop, ORANGE);
DrawTextCenter(TextFormat("%d", i), i, logicalGridLabelY, 10, LIGHTGRAY);
DrawLine(i, logicalGridLabelY + 10, i, logicalGridBottom, GRAY);
}
odd = true;
const int minTextSpace = 30;
int lastTextX = -minTextSpace;
for (int i = cellSize; i < GetRenderWidth(); i += cellSize, odd = !odd)
{
int x = (int)(((float)i)/dpiScale.x);
if (odd) DrawRectangle(x, pixelGridTop, (int)cellSizePx, pixelGridBottom - pixelGridTop, CLITERAL(Color){ 0, 121, 241, 100 });
DrawLine(x, pixelGridTop, (int)(((float)i)/dpiScale.x), pixelGridLabelY - 10, GRAY);
if ((x - lastTextX) >= minTextSpace)
{
DrawTextCenter(TextFormat("%d", i), x, pixelGridLabelY, 10, LIGHTGRAY);
lastTextX = x;
}
}
DrawTextCenter(TextFormat("Window is %d \"physical pixels\" wide", GetRenderWidth()), windowCenter, pixelGridDescY, 20, BLUE);
const char *text = "Can you see this?";
Vector2 size = MeasureTextEx(GetFontDefault(), text, 20, 3);
Vector2 pos = (Vector2){ GetScreenWidth() - size.x - 5, GetScreenHeight() - size.y - 5 };
DrawTextEx(GetFontDefault(), text, pos, 20, 3, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
static void DrawTextCenter(const char *text, int x, int y, int fontSize, Color color)
{
Vector2 size = MeasureTextEx(GetFontDefault(), text, (float)fontSize, 3);
Vector2 pos = (Vector2){ x - size.x/2, y - size.y/2 };
DrawTextEx(GetFontDefault(), text, pos, (float)fontSize, 3, color);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Gamepad input * raylib [core] example - input gamepad
*
* Example complexity rating: [] 1/4
* *
* NOTE: This example requires a Gamepad connected to the system * NOTE: This example requires a Gamepad connected to the system
* raylib is configured to work with the following gamepads: * raylib is configured to work with the following gamepads:
@ -13,7 +15,7 @@
* 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) 2013-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -36,7 +38,7 @@ int main(void)
SetConfigFlags(FLAG_MSAA_4X_HINT); // Set MSAA 4X hint before windows creation SetConfigFlags(FLAG_MSAA_4X_HINT); // Set MSAA 4X hint before windows creation
InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad input"); InitWindow(screenWidth, screenHeight, "raylib [core] example - input gamepad");
Texture2D texPs3Pad = LoadTexture("resources/ps3.png"); Texture2D texPs3Pad = LoadTexture("resources/ps3.png");
Texture2D texXboxPad = LoadTexture("resources/xbox.png"); Texture2D texXboxPad = LoadTexture("resources/xbox.png");
@ -254,11 +256,11 @@ int main(void)
} }
DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(0)), 10, 50, 10, MAROON); DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(gamepad)), 10, 50, 10, MAROON);
for (int i = 0; i < GetGamepadAxisCount(0); i++) for (int i = 0; i < GetGamepadAxisCount(gamepad); i++)
{ {
DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(0, i)), 20, 70 + 20*i, 10, DARKGRAY); DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(gamepad, i)), 20, 70 + 20*i, 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);

View File

@ -1,83 +0,0 @@
/*******************************************************************************************
*
* raylib [core] example - Gamepad information
*
* NOTE: This example requires a Gamepad connected to the system
* Check raylib.h for buttons configuration
*
* Example originally created with raylib 4.6, last time updated with raylib 4.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) 2013-2024 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT); // Set MSAA 4X hint before windows creation
InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad information");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
for (int i = 0, y = 5; i < 4; i++) // MAX_GAMEPADS = 4
{
if (IsGamepadAvailable(i))
{
DrawText(TextFormat("Gamepad name: %s", GetGamepadName(i)), 10, y, 10, BLACK);
y += 11;
DrawText(TextFormat("\tAxis count: %d", GetGamepadAxisCount(i)), 10, y, 10, BLACK);
y += 11;
for (int axis = 0; axis < GetGamepadAxisCount(i); axis++)
{
DrawText(TextFormat("\tAxis %d = %f", axis, GetGamepadAxisMovement(i, axis)), 10, y, 10, BLACK);
y += 11;
}
for (int button = 0; button < 32; button++)
{
DrawText(TextFormat("\tButton %d = %d", button, IsGamepadButtonDown(i, button)), 10, y, 10, BLACK);
y += 11;
}
}
}
DrawFPS(GetScreenWidth() - 100, 100);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
}

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Input Gestures Detection * raylib [core] example - input gestures
*
* Example complexity rating: [] 2/4
* *
* Example originally created with raylib 1.4, last time updated with raylib 4.2 * Example originally created with raylib 1.4, last time updated with raylib 4.2
* *
* 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) 2016-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2016-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -0,0 +1,316 @@
/*******************************************************************************************
*
* raylib [core] example - input gestures testbed
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 5.0, last time updated with raylib 5.6-dev
*
* Example contributed by ubkp (@ubkp) 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) 2023-2025 ubkp (@ubkp)
*
********************************************************************************************/
#include "raylib.h"
#include <math.h> // Required for the protractor angle graphic drawing
#define GESTURE_LOG_SIZE 20
#define MAX_TOUCH_COUNT 32
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
static char const *GetGestureName(int gesture); // Get text string for gesture value
static Color GetGestureColor(int gesture); // Get color for gesture value
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures testbed");
Vector2 messagePosition = { 160, 7 };
// Last gesture variables definitions
int lastGesture = 0;
Vector2 lastGesturePosition = { 165, 130 };
// Gesture log variables definitions
// NOTE: The gesture log uses an array (as an inverted circular queue) to store the performed gestures
char gestureLog[GESTURE_LOG_SIZE][12] = { "" };
// NOTE: The index for the inverted circular queue (moving from last to first direction, then looping around)
int gestureLogIndex = GESTURE_LOG_SIZE;
int previousGesture = 0;
// Log mode values:
// - 0 shows repeated events
// - 1 hides repeated events
// - 2 shows repeated events but hide hold events
// - 3 hides repeated events and hide hold events
int logMode = 1;
Color gestureColor = { 0, 0, 0, 255 };
Rectangle logButton1 = { 53, 7, 48, 26 };
Rectangle logButton2 = { 108, 7, 36, 26 };
Vector2 gestureLogPosition = { 10, 10 };
// Protractor variables definitions
float angleLength = 90.0f;
float currentAngleDegrees = 0.0f;
Vector2 finalVector = { 0.0f, 0.0f };
char currentAngleStr[7] = "";
Vector2 protractorPosition = { 266.0f, 315.0f };
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
//--------------------------------------------------------------------------------------
// Handle common gestures data
int i, ii; // Iterators that will be reused by all for loops
const int currentGesture = GetGestureDetected();
const float currentDragDegrees = GetGestureDragAngle();
const float currentPitchDegrees = GetGesturePinchAngle();
const int touchCount = GetTouchPointCount();
// Handle last gesture
if ((currentGesture != 0) && (currentGesture != 4) && (currentGesture != previousGesture))
lastGesture = currentGesture; // Filter the meaningful gestures (1, 2, 8 to 512) for the display
// Handle gesture log
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
{
if (CheckCollisionPointRec(GetMousePosition(), logButton1))
{
switch (logMode)
{
case 3: logMode = 2; break;
case 2: logMode = 3; break;
case 1: logMode = 0; break;
default: logMode = 1; break;
}
}
else if (CheckCollisionPointRec(GetMousePosition(), logButton2))
{
switch (logMode)
{
case 3: logMode = 1; break;
case 2: logMode = 0; break;
case 1: logMode = 3; break;
default: logMode = 2; break;
}
}
}
int fillLog = 0; // Gate variable to be used to allow or not the gesture log to be filled
if (currentGesture !=0)
{
if (logMode == 3) // 3 hides repeated events and hide hold events
{
if (((currentGesture != 4) && (currentGesture != previousGesture)) || (currentGesture < 3)) fillLog = 1;
}
else if (logMode == 2) // 2 shows repeated events but hide hold events
{
if (currentGesture != 4) fillLog = 1;
}
else if (logMode == 1) // 1 hides repeated events
{
if (currentGesture != previousGesture) fillLog = 1;
}
else // 0 shows repeated events
{
fillLog = 1;
}
}
if (fillLog) // If one of the conditions from logMode was met, fill the gesture log
{
previousGesture = currentGesture;
gestureColor = GetGestureColor(currentGesture);
if (gestureLogIndex <= 0) gestureLogIndex = GESTURE_LOG_SIZE;
gestureLogIndex--;
// Copy the gesture respective name to the gesture log array
TextCopy(gestureLog[gestureLogIndex], GetGestureName(currentGesture));
}
// Handle protractor
if (currentGesture > 255) currentAngleDegrees = currentPitchDegrees; // Pinch In and Pinch Out
else if (currentGesture > 15) currentAngleDegrees = currentDragDegrees; // Swipe Right, Swipe Left, Swipe Up and Swipe Down
else if (currentGesture > 0) currentAngleDegrees = 0.0f; // Tap, Doubletap, Hold and Grab
float currentAngleRadians = ((currentAngleDegrees + 90.0f)*PI/180); // Convert the current angle to Radians
// Calculate the final vector for display
finalVector = (Vector2){ (angleLength*sinf(currentAngleRadians)) + protractorPosition.x,
(angleLength*cosf(currentAngleRadians)) + protractorPosition.y };
// Handle touch and mouse pointer points
Vector2 touchPosition[MAX_TOUCH_COUNT] = { 0 };
Vector2 mousePosition = { 0 };
if (currentGesture != GESTURE_NONE)
{
if (touchCount != 0)
{
for (i = 0; i < touchCount; i++) touchPosition[i] = GetTouchPosition(i); // Fill the touch positions
}
else mousePosition = GetMousePosition();
}
//--------------------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw common elements
DrawText("*", messagePosition.x + 5, messagePosition.y + 5, 10, BLACK);
DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", messagePosition.x + 15, messagePosition.y + 5, 10, BLACK);
DrawText("*", messagePosition.x + 5, messagePosition.y + 35, 10, BLACK);
DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.", messagePosition.x + 15, messagePosition.y + 35, 10, BLACK);
// Draw last gesture
DrawText("Last gesture", lastGesturePosition.x + 33, lastGesturePosition.y - 47, 20, BLACK);
DrawText("Swipe Tap Pinch Touch", lastGesturePosition.x + 17, lastGesturePosition.y - 18, 10, BLACK);
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y, 20, 20, lastGesture == GESTURE_SWIPE_UP ? RED : LIGHTGRAY);
DrawRectangle(lastGesturePosition.x, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_LEFT ? RED : LIGHTGRAY);
DrawRectangle(lastGesturePosition.x + 40, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_RIGHT ? RED : LIGHTGRAY);
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y + 40, 20, 20, lastGesture == GESTURE_SWIPE_DOWN ? RED : LIGHTGRAY);
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 16, 10, lastGesture == GESTURE_TAP ? BLUE : LIGHTGRAY);
DrawRing( (Vector2){lastGesturePosition.x + 103, lastGesturePosition.y + 16}, 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == GESTURE_DRAG ? LIME : LIGHTGRAY);
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
DrawCircle(lastGesturePosition.x + 103, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 122, lastGesturePosition.y + 16 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 6 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 6 }, (Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 162, lastGesturePosition.y + 16 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 33 }, (Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 140, lastGesturePosition.y + 43 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 144, lastGesturePosition.y + 43 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 33 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
for (i = 0; i < 4; i++) DrawCircle(lastGesturePosition.x + 180, lastGesturePosition.y + 7 + i*15, 5, touchCount <= i? LIGHTGRAY : gestureColor);
// Draw gesture log
DrawText("Log", gestureLogPosition.x, 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)
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], gestureLogPosition.x, gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
Color logButton1Color, logButton2Color;
switch (logMode)
{
case 3: logButton1Color=MAROON; logButton2Color=MAROON; break;
case 2: logButton1Color=GRAY; logButton2Color=MAROON; break;
case 1: logButton1Color=MAROON; logButton2Color=GRAY; break;
default: logButton1Color=GRAY; logButton2Color=GRAY; break;
}
DrawRectangleRec(logButton1, logButton1Color);
DrawText("Hide", logButton1.x + 7, logButton1.y + 3, 10, WHITE);
DrawText("Repeat", logButton1.x + 7, logButton1.y + 13, 10, WHITE);
DrawRectangleRec(logButton2, logButton2Color);
DrawText("Hide", logButton1.x + 62, logButton1.y + 3, 10, WHITE);
DrawText("Hold", logButton1.x + 62, logButton1.y + 13, 10, WHITE);
// Draw protractor
DrawText("Angle", protractorPosition.x + 55, protractorPosition.y + 76, 10, BLACK);
const char *angleString = TextFormat("%f", currentAngleDegrees);
const int angleStringDot = TextFindIndex(angleString, ".");
const char *angleStringTrim = TextSubtext(angleString, 0, angleStringDot + 3);
DrawText( angleStringTrim, protractorPosition.x + 55, protractorPosition.y + 92, 20, gestureColor);
DrawCircle(protractorPosition.x, protractorPosition.y, 80.0f, WHITE);
DrawLineEx((Vector2){ protractorPosition.x - 90, protractorPosition.y }, (Vector2){ protractorPosition.x + 90, protractorPosition.y }, 3.0f, LIGHTGRAY);
DrawLineEx((Vector2){ protractorPosition.x, protractorPosition.y - 90 }, (Vector2){ protractorPosition.x, protractorPosition.y + 90 }, 3.0f, LIGHTGRAY);
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y - 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y + 45 }, 3.0f, GREEN);
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y + 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y - 45 }, 3.0f, GREEN);
DrawText("0", protractorPosition.x + 96, protractorPosition.y - 9, 20, BLACK);
DrawText("30", protractorPosition.x + 74, protractorPosition.y - 68, 20, BLACK);
DrawText("90", protractorPosition.x - 11, protractorPosition.y - 110, 20, BLACK);
DrawText("150", protractorPosition.x - 100, protractorPosition.y - 68, 20, BLACK);
DrawText("180", protractorPosition.x - 124, protractorPosition.y - 9, 20, BLACK);
DrawText("210", protractorPosition.x - 100, protractorPosition.y + 50, 20, BLACK);
DrawText("270", protractorPosition.x - 18, protractorPosition.y + 92, 20, BLACK);
DrawText("330", protractorPosition.x + 72, protractorPosition.y + 50, 20, BLACK);
if (currentAngleDegrees != 0.0f) DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
// Draw touch and mouse pointer points
if (currentGesture != GESTURE_NONE)
{
if ( touchCount != 0 )
{
for (i = 0; i < touchCount; i++)
{
DrawCircleV(touchPosition[i], 50.0f, Fade(gestureColor, 0.5f));
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
}
if (touchCount == 2) DrawLineEx(touchPosition[0], touchPosition[1], ((currentGesture == 512)? 8 : 12), gestureColor);
}
else
{
DrawCircleV(mousePosition, 35.0f, Fade(gestureColor, 0.5f));
DrawCircleV(mousePosition, 5.0f, gestureColor);
}
}
EndDrawing();
//--------------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Get text string for gesture value
static char const *GetGestureName(int gesture)
{
switch (gesture)
{
case 0: return "None"; break;
case 1: return "Tap"; break;
case 2: return "Double Tap"; break;
case 4: return "Hold"; break;
case 8: return "Drag"; break;
case 16: return "Swipe Right"; break;
case 32: return "Swipe Left"; break;
case 64: return "Swipe Up"; break;
case 128: return "Swipe Down"; break;
case 256: return "Pinch In"; break;
case 512: return "Pinch Out"; break;
default: return "Unknown"; break;
}
}
// Get color for gesture value
static Color GetGestureColor(int gesture)
{
switch (gesture)
{
case 0: return BLACK; break;
case 1: return BLUE; break;
case 2: return SKYBLUE; break;
case 4: return BLACK; break;
case 8: return LIME; break;
case 16: return RED; break;
case 32: return RED; break;
case 64: return RED; break;
case 128: return RED; break;
case 256: return VIOLET; break;
case 512: return ORANGE; break;
default: return BLACK; break;
}
}

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -1,330 +0,0 @@
/*******************************************************************************************
*
* raylib [core] example - Input Gestures for Web
*
* Example originally created with raylib 4.6-dev, last time updated with raylib 4.6-dev
*
* Example contributed by ubkp (@ubkp) 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) 2023 ubkp (@ubkp)
*
********************************************************************************************/
#include "raylib.h"
#include "math.h" // Required for the protractor angle graphic drawing
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h> // Required for the Web/HTML5
#endif
//--------------------------------------------------------------------------------------
// Global definitions and declarations
//--------------------------------------------------------------------------------------
// Common variables definitions
//--------------------------------------------------------------------------------------
int screenWidth = 800; // Update depending on web canvas
const int screenHeight = 450;
Vector2 messagePosition = { 160, 7 };
// Last gesture variables definitions
//--------------------------------------------------------------------------------------
int lastGesture = 0;
Vector2 lastGesturePosition = { 165, 130 };
// Gesture log variables definitions and functions declarations
//--------------------------------------------------------------------------------------
#define GESTURE_LOG_SIZE 20
char gestureLog[GESTURE_LOG_SIZE][12] = { "" }; // The gesture log uses an array (as an inverted circular queue) to store the performed gestures
int gestureLogIndex = GESTURE_LOG_SIZE; // The index for the inverted circular queue (moving from last to first direction, then looping around)
int previousGesture = 0;
char const *GetGestureName(int i)
{
switch (i) {
case 0: return "None"; break;
case 1: return "Tap"; break;
case 2: return "Double Tap"; break;
case 4: return "Hold"; break;
case 8: return "Drag"; break;
case 16: return "Swipe Right"; break;
case 32: return "Swipe Left"; break;
case 64: return "Swipe Up"; break;
case 128: return "Swipe Down"; break;
case 256: return "Pinch In"; break;
case 512: return "Pinch Out"; break;
default: return "Unknown"; break;
}
}
Color GetGestureColor(int i)
{
switch (i) {
case 0: return BLACK; break;
case 1: return BLUE; break;
case 2: return SKYBLUE; break;
case 4: return BLACK; break;
case 8: return LIME; break;
case 16: return RED; break;
case 32: return RED; break;
case 64: return RED; break;
case 128: return RED; break;
case 256: return VIOLET; break;
case 512: return ORANGE; break;
default: return BLACK; break;
}
}
int logMode = 1; // Log mode values: 0 shows repeated events; 1 hides repeated events; 2 shows repeated events but hide hold events; 3 hides repeated events and hide hold events
Color gestureColor = { 0, 0, 0, 255 };
Rectangle logButton1 = { 53, 7, 48, 26 };
Rectangle logButton2 = { 108, 7, 36, 26 };
Vector2 gestureLogPosition = { 10, 10 };
// Protractor variables definitions
//--------------------------------------------------------------------------------------
float angleLength = 90.0f;
float currentAngleDegrees = 0.0f;
Vector2 finalVector = { 0.0f, 0.0f };
char currentAngleStr[7] = "";
Vector2 protractorPosition = { 266.0f, 315.0f };
// Update
//--------------------------------------------------------------------------------------
void Update(void)
{
// Handle common
//--------------------------------------------------------------------------------------
int i, ii; // Iterators that will be reused by all for loops
const int currentGesture = GetGestureDetected();
const float currentDragDegrees = GetGestureDragAngle();
const float currentPitchDegrees = GetGesturePinchAngle();
const int touchCount = GetTouchPointCount();
// Handle last gesture
//--------------------------------------------------------------------------------------
if ((currentGesture != 0) && (currentGesture != 4) && (currentGesture != previousGesture)) lastGesture = currentGesture; // Filter the meaningful gestures (1, 2, 8 to 512) for the display
// Handle gesture log
//--------------------------------------------------------------------------------------
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
{
if (CheckCollisionPointRec(GetMousePosition(), logButton1))
{
switch (logMode)
{
case 3: logMode=2; break;
case 2: logMode=3; break;
case 1: logMode=0; break;
default: logMode=1; break;
}
}
else if (CheckCollisionPointRec(GetMousePosition(), logButton2))
{
switch (logMode)
{
case 3: logMode=1; break;
case 2: logMode=0; break;
case 1: logMode=3; break;
default: logMode=2; break;
}
}
}
int fillLog = 0; // Gate variable to be used to allow or not the gesture log to be filled
if (currentGesture !=0)
{
if (logMode == 3) // 3 hides repeated events and hide hold events
{
if (((currentGesture != 4) && (currentGesture != previousGesture)) || (currentGesture < 3)) fillLog = 1;
}
else if (logMode == 2) // 2 shows repeated events but hide hold events
{
if (currentGesture != 4) fillLog = 1;
}
else if (logMode == 1) // 1 hides repeated events
{
if (currentGesture != previousGesture) fillLog = 1;
}
else // 0 shows repeated events
{
fillLog = 1;
}
}
if (fillLog) // If one of the conditions from logMode was met, fill the gesture log
{
previousGesture = currentGesture;
gestureColor = GetGestureColor(currentGesture);
if (gestureLogIndex <= 0) gestureLogIndex = GESTURE_LOG_SIZE;
gestureLogIndex--;
// Copy the gesture respective name to the gesture log array
TextCopy(gestureLog[gestureLogIndex], GetGestureName(currentGesture));
}
// Handle protractor
//--------------------------------------------------------------------------------------
if (currentGesture > 255) // aka Pinch In and Pinch Out
{
currentAngleDegrees = currentPitchDegrees;
}
else if (currentGesture > 15) // aka Swipe Right, Swipe Left, Swipe Up and Swipe Down
{
currentAngleDegrees = currentDragDegrees;
}
else if (currentGesture > 0) // aka Tap, Doubletap, Hold and Grab
{
currentAngleDegrees = 0.0f;
}
float currentAngleRadians = ((currentAngleDegrees +90.0f)*PI/180); // Convert the current angle to Radians
finalVector = (Vector2){ (angleLength*sinf(currentAngleRadians)) + protractorPosition.x, (angleLength*cosf(currentAngleRadians)) + protractorPosition.y }; // Calculate the final vector for display
// Handle touch and mouse pointer points
//--------------------------------------------------------------------------------------
#define MAX_TOUCH_COUNT 32
Vector2 touchPosition[MAX_TOUCH_COUNT] = { 0 };
Vector2 mousePosition = {0, 0};
if (currentGesture != GESTURE_NONE)
{
if (touchCount != 0)
{
for (i = 0; i < touchCount; i++) touchPosition[i] = GetTouchPosition(i); // Fill the touch positions
}
else mousePosition = GetMousePosition();
}
// Draw
//--------------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw common
//--------------------------------------------------------------------------------------
DrawText("*", messagePosition.x + 5, messagePosition.y + 5, 10, BLACK);
DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", messagePosition.x + 15, messagePosition.y + 5, 10, BLACK);
DrawText("*", messagePosition.x + 5, messagePosition.y + 35, 10, BLACK);
DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.", messagePosition.x + 15, messagePosition.y + 35, 10, BLACK);
// Draw last gesture
//--------------------------------------------------------------------------------------
DrawText("Last gesture", lastGesturePosition.x + 33, lastGesturePosition.y - 47, 20, BLACK);
DrawText("Swipe Tap Pinch Touch", lastGesturePosition.x + 17, lastGesturePosition.y - 18, 10, BLACK);
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y, 20, 20, lastGesture == GESTURE_SWIPE_UP ? RED : LIGHTGRAY);
DrawRectangle(lastGesturePosition.x, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_LEFT ? RED : LIGHTGRAY);
DrawRectangle(lastGesturePosition.x + 40, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_RIGHT ? RED : LIGHTGRAY);
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y + 40, 20, 20, lastGesture == GESTURE_SWIPE_DOWN ? RED : LIGHTGRAY);
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 16, 10, lastGesture == GESTURE_TAP ? BLUE : LIGHTGRAY);
DrawRing( (Vector2){lastGesturePosition.x + 103, lastGesturePosition.y + 16}, 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == GESTURE_DRAG ? LIME : LIGHTGRAY);
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
DrawCircle(lastGesturePosition.x + 103, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 122, lastGesturePosition.y + 16 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 6 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 6 }, (Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 162, lastGesturePosition.y + 16 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 33 }, (Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 140, lastGesturePosition.y + 43 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
DrawTriangle((Vector2){ lastGesturePosition.x + 144, lastGesturePosition.y + 43 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 33 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
for (i = 0; i < 4; i++) DrawCircle(lastGesturePosition.x + 180, lastGesturePosition.y + 7 + i*15, 5, touchCount <= i? LIGHTGRAY : gestureColor);
// Draw gesture log
//--------------------------------------------------------------------------------------
DrawText("Log", gestureLogPosition.x, 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)
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], gestureLogPosition.x, gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
Color logButton1Color, logButton2Color;
switch (logMode)
{
case 3: logButton1Color=MAROON; logButton2Color=MAROON; break;
case 2: logButton1Color=GRAY; logButton2Color=MAROON; break;
case 1: logButton1Color=MAROON; logButton2Color=GRAY; break;
default: logButton1Color=GRAY; logButton2Color=GRAY; break;
}
DrawRectangleRec(logButton1, logButton1Color);
DrawText("Hide", logButton1.x + 7, logButton1.y + 3, 10, WHITE);
DrawText("Repeat", logButton1.x + 7, logButton1.y + 13, 10, WHITE);
DrawRectangleRec(logButton2, logButton2Color);
DrawText("Hide", logButton1.x + 62, logButton1.y + 3, 10, WHITE);
DrawText("Hold", logButton1.x + 62, logButton1.y + 13, 10, WHITE);
// Draw protractor
//--------------------------------------------------------------------------------------
DrawText("Angle", protractorPosition.x + 55, protractorPosition.y + 76, 10, BLACK);
const char *angleString = TextFormat("%f", currentAngleDegrees);
const int angleStringDot = TextFindIndex(angleString, ".");
const char *angleStringTrim = TextSubtext(angleString, 0, angleStringDot + 3);
DrawText( angleStringTrim, protractorPosition.x + 55, protractorPosition.y + 92, 20, gestureColor);
DrawCircle(protractorPosition.x, protractorPosition.y, 80.0f, WHITE);
DrawLineEx((Vector2){ protractorPosition.x - 90, protractorPosition.y }, (Vector2){ protractorPosition.x + 90, protractorPosition.y }, 3.0f, LIGHTGRAY);
DrawLineEx((Vector2){ protractorPosition.x, protractorPosition.y - 90 }, (Vector2){ protractorPosition.x, protractorPosition.y + 90 }, 3.0f, LIGHTGRAY);
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y - 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y + 45 }, 3.0f, GREEN);
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y + 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y - 45 }, 3.0f, GREEN);
DrawText("0", protractorPosition.x + 96, protractorPosition.y - 9, 20, BLACK);
DrawText("30", protractorPosition.x + 74, protractorPosition.y - 68, 20, BLACK);
DrawText("90", protractorPosition.x - 11, protractorPosition.y - 110, 20, BLACK);
DrawText("150", protractorPosition.x - 100, protractorPosition.y - 68, 20, BLACK);
DrawText("180", protractorPosition.x - 124, protractorPosition.y - 9, 20, BLACK);
DrawText("210", protractorPosition.x - 100, protractorPosition.y + 50, 20, BLACK);
DrawText("270", protractorPosition.x - 18, protractorPosition.y + 92, 20, BLACK);
DrawText("330", protractorPosition.x + 72, protractorPosition.y + 50, 20, BLACK);
if (currentAngleDegrees != 0.0f) DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
// Draw touch and mouse pointer points
//--------------------------------------------------------------------------------------
if (currentGesture != GESTURE_NONE)
{
if ( touchCount != 0 )
{
for (i = 0; i < touchCount; i++)
{
DrawCircleV(touchPosition[i], 50.0f, Fade(gestureColor, 0.5f));
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
}
if (touchCount == 2) DrawLineEx(touchPosition[0], touchPosition[1], ((currentGesture == 512)? 8 : 12), gestureColor);
}
else
{
DrawCircleV(mousePosition, 35.0f, Fade(gestureColor, 0.5f));
DrawCircleV(mousePosition, 5.0f, gestureColor);
}
}
EndDrawing();
//--------------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures web");
//--------------------------------------------------------------------------------------
// Main game loop
//--------------------------------------------------------------------------------------
#if defined(PLATFORM_WEB)
emscripten_set_main_loop(Update, 0, 1);
#else
SetTargetFPS(60);
while (!WindowShouldClose()) Update(); // Detect window close button or ESC key
#endif
//--------------------------------------------------------------------------------------
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Keyboard input * raylib [core] example - input keys
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 1.0, last time updated with raylib 1.0 * Example originally created with raylib 1.0, last time updated with raylib 1.0
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -23,7 +25,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard input"); InitWindow(screenWidth, screenHeight, "raylib [core] example - input keys");
Vector2 ballPosition = { (float)screenWidth/2, (float)screenHeight/2 }; Vector2 ballPosition = { (float)screenWidth/2, (float)screenHeight/2 };

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Mouse input * raylib [core] example - input mouse
* *
* Example originally created with raylib 1.0, last time updated with raylib 4.0 * Example complexity rating: [] 1/4
*
* Example originally created with raylib 1.0, last time updated with raylib 5.5
* *
* 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) 2014-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -23,7 +25,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse input"); InitWindow(screenWidth, screenHeight, "raylib [core] example - input mouse");
Vector2 ballPosition = { -100.0f, -100.0f }; Vector2 ballPosition = { -100.0f, -100.0f };
Color ballColor = DARKBLUE; Color ballColor = DARKBLUE;
@ -36,6 +38,18 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_H))
{
if (IsCursorHidden())
{
ShowCursor();
}
else
{
HideCursor();
}
}
ballPosition = GetMousePosition(); ballPosition = GetMousePosition();
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) ballColor = MAROON; if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) ballColor = MAROON;
@ -56,6 +70,10 @@ int main(void)
DrawCircleV(ballPosition, 40, ballColor); DrawCircleV(ballPosition, 40, ballColor);
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY); DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);
DrawText("Press 'H' to toggle cursor visibility", 10, 30, 20, DARKGRAY);
if (!IsCursorHidden()) DrawText("CURSOR HIDDEN", 20, 60, 20, RED);
else DrawText("CURSOR VISIBLE", 20, 60, 20, LIME);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] examples - Mouse wheel input * raylib [core] example - input mouse wheel
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 1.1, last time updated with raylib 1.3 * Example originally created with raylib 1.1, last time updated with raylib 1.3
* *
* 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) 2014-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Input multitouch * raylib [core] example - input multitouch
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 2.1, last time updated with raylib 2.5 * Example originally created with raylib 2.1, last time updated with raylib 2.5
* *
@ -9,7 +11,7 @@
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2019-2024 Berni (@Berni8k) and Ramon Santamaria (@raysan5) * Copyright (c) 2019-2025 Berni (@Berni8k) and Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -42,7 +44,7 @@ int main(void)
// Get the touch point count ( how many fingers are touching the screen ) // Get the touch point count ( how many fingers are touching the screen )
int tCount = GetTouchPointCount(); int tCount = GetTouchPointCount();
// 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);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -2,21 +2,33 @@
* *
* raylib [core] example - input virtual controls * raylib [core] example - input virtual controls
* *
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.0, last time updated with raylib 5.0 * Example originally created with raylib 5.0, last time updated with raylib 5.0
* *
* Example create by GreenSnakeLinux (@GreenSnakeLinux), * Example contributed by GreenSnakeLinux (@GreenSnakeLinux),
* lighter by oblerion (@oblerion) and * reviewed by Ramon Santamaria (@raysan5), oblerion (@oblerion) and danilwhale (@danilwhale)
* 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) 2024 Ramon Santamaria (@raysan5) * Copyright (c) 2024-2025 GreenSnakeLinux (@GreenSnakeLinux) and Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include <math.h> #include <math.h>
typedef enum {
BUTTON_NONE = -1,
BUTTON_UP,
BUTTON_LEFT,
BUTTON_RIGHT,
BUTTON_DOWN,
BUTTON_MAX
} PadButton;
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -29,24 +41,35 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls"); InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls");
const float dpadX = 90; Vector2 padPosition = { 100, 350 };
const float dpadY = 300; float buttonRadius = 30;
const float dpadRad = 25.0f;//radius of each pad
Color dpadColor = BLUE;
int dpadKeydown = -1;//-1 if not down, else 0,1,2,3
Vector2 buttonPositions[BUTTON_MAX] = {
const float dpadCollider[4][2]= // collider array with x,y position { padPosition.x,padPosition.y - buttonRadius*1.5f }, // Up
{ { padPosition.x - buttonRadius*1.5f, padPosition.y }, // Left
{dpadX,dpadY-dpadRad*1.5f},//up { padPosition.x + buttonRadius*1.5f, padPosition.y }, // Right
{dpadX-dpadRad*1.5f,dpadY},//left { padPosition.x, padPosition.y + buttonRadius*1.5f } // Down
{dpadX+dpadRad*1.5f,dpadY},//right
{dpadX,dpadY+dpadRad*1.5f}//down
}; };
const char dpadLabel[4]="XYBA";//label of Dpad
float playerX=100; const char *buttonLabels[BUTTON_MAX] = {
float playerY=100; "Y", // Up
"X", // Left
"B", // Right
"A" // Down
};
Color buttonLabelColors[BUTTON_MAX] = {
YELLOW, // Up
BLUE, // Left
RED, // Right
GREEN // Down
};
int pressedButton = BUTTON_NONE;
Vector2 inputPosition = { 0, 0 };
Vector2 playerPosition = { (float)screenWidth/2, (float)screenHeight/2 };
float playerSpeed = 75;
SetTargetFPS(60); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -54,63 +77,66 @@ int main(void)
// Main game loop // Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key while (!WindowShouldClose()) // Detect window close button or ESC key
{ {
// Update // Update
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
dpadKeydown = -1; //reset if ((GetTouchPointCount() > 0)) inputPosition = GetTouchPosition(0); // Use touch position
int inputX = 0; else inputPosition = GetMousePosition(); // Use mouse position
int inputY = 0;
if(GetTouchPointCount()>0) // Reset pressed button to none
{//use touch pos pressedButton = BUTTON_NONE;
inputX = GetTouchX();
inputY = GetTouchY(); // Make sure user is pressing left mouse button if they're from desktop
} if ((GetTouchPointCount() > 0) ||
else ((GetTouchPointCount() == 0) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)))
{//use mouse pos
inputX = GetMouseX();
inputY = GetMouseY();
}
for(int i=0;i<4;i++)
{ {
//test distance each collider and input < radius // Find nearest D-Pad button to the input position
if( fabsf(dpadCollider[i][1]-inputY) + fabsf(dpadCollider[i][0]-inputX) < dpadRad) for (int i = 0; i < BUTTON_MAX; i++)
{ {
dpadKeydown = i; float distX = fabsf(buttonPositions[i].x - inputPosition.x);
break; float distY = fabsf(buttonPositions[i].y - inputPosition.y);
}
} if ((distX + distY < buttonRadius))
// move player
switch(dpadKeydown){
case 0: playerY -= 50*GetFrameTime();
break;
case 1: playerX -= 50*GetFrameTime();
break;
case 2: playerX += 50*GetFrameTime();
break;
case 3: playerY += 50*GetFrameTime();
default:;
};
//--------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
for(int i=0;i<4;i++)
{
//draw all pad
DrawCircleV((Vector2) { dpadCollider[i][0], dpadCollider[i][1] }, dpadRad, dpadColor);
if(i!=dpadKeydown)
{ {
//draw label pressedButton = i;
DrawText(TextSubtext(dpadLabel,i,1), break;
(int)dpadCollider[i][0]-7,
(int)dpadCollider[i][1]-8,20,BLACK);
} }
} }
}
// Move player according to pressed button
switch (pressedButton)
{
case BUTTON_UP: playerPosition.y -= playerSpeed*GetFrameTime(); break;
case BUTTON_LEFT: playerPosition.x -= playerSpeed*GetFrameTime(); break;
case BUTTON_RIGHT: playerPosition.x += playerSpeed*GetFrameTime(); break;
case BUTTON_DOWN: playerPosition.y += playerSpeed*GetFrameTime(); break;
default: break;
};
//--------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw world
DrawCircleV(playerPosition, 50, MAROON);
// Draw GUI
for (int i = 0; i < BUTTON_MAX; i++)
{
DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton)? DARKGRAY : BLACK);
DrawText(buttonLabels[i],
(int)buttonPositions[i].x - 7, (int)buttonPositions[i].y - 8,
20, buttonLabelColors[i]);
}
DrawText("move the player with D-Pad buttons", 10, 10, 20, DARKGRAY);
DrawRectangleRec((Rectangle) { playerX - 4, playerY - 4, 75, 28 }, RED);
DrawText("Player", (int)playerX, (int)playerY, 20, WHITE);
EndDrawing(); EndDrawing();
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
} }
// De-Initialization // De-Initialization
@ -120,4 +146,3 @@ int main(void)
return 0; return 0;
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,156 +0,0 @@
/*******************************************************************************************
*
* raylib [core] example - loading thread
*
* NOTE: This example requires linking with pthreads library on MinGW,
* it can be accomplished passing -static parameter to compiler
*
* Example originally created with raylib 2.5, last time updated with raylib 3.0
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
*
* Copyright (c) 2014-2024 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
// WARNING: This example does not build on Windows with MSVC compiler
#include "pthread.h" // POSIX style threads management
#include <stdatomic.h> // C11 atomic data types
#include <time.h> // Required for: clock()
// Using C11 atomics for synchronization
// NOTE: A plain bool (or any plain data type for that matter) can't be used for inter-thread synchronization
static atomic_bool dataLoaded = false; // Data Loaded completion indicator
static void *LoadDataThread(void *arg); // Loading data thread function declaration
static atomic_int dataProgress = 0; // Data progress accumulator
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - loading thread");
pthread_t threadId = { 0 }; // Loading data thread id
enum { STATE_WAITING, STATE_LOADING, STATE_FINISHED } state = STATE_WAITING;
int framesCounter = 0;
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
//----------------------------------------------------------------------------------
switch (state)
{
case STATE_WAITING:
{
if (IsKeyPressed(KEY_ENTER))
{
int error = pthread_create(&threadId, NULL, &LoadDataThread, NULL);
if (error != 0) TraceLog(LOG_ERROR, "Error creating loading thread");
else TraceLog(LOG_INFO, "Loading thread initialized successfully");
state = STATE_LOADING;
}
} break;
case STATE_LOADING:
{
framesCounter++;
if (atomic_load_explicit(&dataLoaded, memory_order_relaxed))
{
framesCounter = 0;
int error = pthread_join(threadId, NULL);
if (error != 0) TraceLog(LOG_ERROR, "Error joining loading thread");
else TraceLog(LOG_INFO, "Loading thread terminated successfully");
state = STATE_FINISHED;
}
} break;
case STATE_FINISHED:
{
if (IsKeyPressed(KEY_ENTER))
{
// Reset everything to launch again
atomic_store_explicit(&dataLoaded, false, memory_order_relaxed);
atomic_store_explicit(&dataProgress, 0, memory_order_relaxed);
state = STATE_WAITING;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
switch (state)
{
case STATE_WAITING: DrawText("PRESS ENTER to START LOADING DATA", 150, 170, 20, DARKGRAY); break;
case STATE_LOADING:
{
DrawRectangle(150, 200, atomic_load_explicit(&dataProgress, memory_order_relaxed), 60, SKYBLUE);
if ((framesCounter/15)%2) DrawText("LOADING DATA...", 240, 210, 40, DARKBLUE);
} break;
case STATE_FINISHED:
{
DrawRectangle(150, 200, 500, 60, LIME);
DrawText("DATA LOADED!", 250, 210, 40, GREEN);
} break;
default: break;
}
DrawRectangleLines(150, 200, 500, 60, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
// Loading data thread function definition
static void *LoadDataThread(void *arg)
{
int timeCounter = 0; // Time counted in ms
clock_t prevTime = clock(); // Previous time
// We simulate data loading with a time counter for 5 seconds
while (timeCounter < 5000)
{
clock_t currentTime = clock() - prevTime;
timeCounter = currentTime*1000/CLOCKS_PER_SEC;
// We accumulate time over a global variable to be used in
// main thread as a progress bar
atomic_store_explicit(&dataProgress, timeCounter/10, memory_order_relaxed);
}
// When data has finished loading, we set global variable
atomic_store_explicit(&dataLoaded, true, memory_order_relaxed);
return NULL;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Generates a random sequence * raylib [core] example - random sequence
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 5.0, last time updated with raylib 5.0 * Example originally created with raylib 5.0, last time updated with raylib 5.0
* *
@ -9,168 +11,169 @@
* 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) 2023 Dalton Overmyer (@REDl3east) * Copyright (c) 2023-2025 Dalton Overmyer (@REDl3east)
* *
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include "raymath.h" #include "raymath.h"
#include <stdlib.h> // Required for: malloc() and free() #include <stdlib.h> // Required for: malloc(), free()
typedef struct ColorRect{ //----------------------------------------------------------------------------------
Color c; // Types and Structures Definition
Rectangle r; //----------------------------------------------------------------------------------
typedef struct ColorRect {
Color color;
Rectangle rect;
} ColorRect; } ColorRect;
static Color GenerateRandomColor(); //------------------------------------------------------------------------------------
static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight); // Module Functions Declaration
static void ShuffleColorRectSequence(ColorRect* rectangles, int rectCount); //------------------------------------------------------------------------------------
static void DrawTextCenterKeyHelp(const char* key, const char* text, int posX, int posY, int fontSize, Color color); static Color GenerateRandomColor(void);
static ColorRect *GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight);
static void ShuffleColorRectSequence(ColorRect *rectangles, int rectCount);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
int main(void) { int main(void)
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - Generates a random sequence");
int rectCount = 20;
float rectSize = (float)screenWidth/rectCount;
ColorRect* rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if(IsKeyPressed(KEY_SPACE))
{
ShuffleColorRectSequence(rectangles, rectCount);
}
if(IsKeyPressed(KEY_UP))
{
rectCount++;
rectSize = (float)screenWidth/rectCount;
free(rectangles);
rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
}
if(IsKeyPressed(KEY_DOWN))
{
if(rectCount >= 4){
rectCount--;
rectSize = (float)screenWidth/rectCount;
free(rectangles);
rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
}
}
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
int fontSize = 20;
for(int x=0;x<rectCount;x++)
{
DrawRectangleRec(rectangles[x].r, rectangles[x].c);
DrawTextCenterKeyHelp("SPACE", "to shuffle the sequence.", 10, screenHeight - 96, fontSize, BLACK);
DrawTextCenterKeyHelp("UP", "to add a rectangle and generate a new sequence.", 10, screenHeight - 64, fontSize, BLACK);
DrawTextCenterKeyHelp("DOWN", "to remove a rectangle and generate a new sequence.", 10, screenHeight - 32, fontSize, BLACK);
}
const char* rectCountText = TextFormat("%d rectangles", rectCount);
int rectCountTextSize = MeasureText(rectCountText, fontSize);
DrawText(rectCountText, screenWidth - rectCountTextSize - 10, 10, fontSize, BLACK);
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
free(rectangles);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
static Color GenerateRandomColor()
{ {
return CLITERAL(Color){ // Initialization
GetRandomValue(0, 255), //--------------------------------------------------------------------------------------
GetRandomValue(0, 255), const int screenWidth = 800;
GetRandomValue(0, 255), const int screenHeight = 450;
255,
}; InitWindow(screenWidth, screenHeight, "raylib [core] example - random sequence");
int rectCount = 20;
float rectSize = (float)screenWidth/rectCount;
ColorRect *rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f*screenHeight);
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_SPACE)) ShuffleColorRectSequence(rectangles, rectCount);
if (IsKeyPressed(KEY_UP))
{
rectCount++;
rectSize = (float)screenWidth/rectCount;
RL_FREE(rectangles);
// Re-generate random sequence with new count
rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f*screenHeight);
}
if (IsKeyPressed(KEY_DOWN))
{
if (rectCount >= 4)
{
rectCount--;
rectSize = (float)screenWidth/rectCount;
RL_FREE(rectangles);
// Re-generate random sequence with new count
rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f*screenHeight);
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
for (int i = 0; i < rectCount; i++)
{
DrawRectangleRec(rectangles[i].rect, rectangles[i].color);
DrawText("Press SPACE to shuffle the sequence", 10, screenHeight - 96, 20, BLACK);
DrawText("Press SPACE to shuffle the current sequence", 10, screenHeight - 96, 20, BLACK);
DrawText("Press UP to add a rectangle and generate a new sequence", 10, screenHeight - 64, 20, BLACK);
DrawText("Press DOWN to remove a rectangle and generate a new sequence", 10, screenHeight - 32, 20, BLACK);
}
DrawText(TextFormat("Count: %d rectangles", rectCount), 10, 10, 20, MAROON);
DrawFPS(screenWidth - 80, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
free(rectangles);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
} }
static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight){ //------------------------------------------------------------------------------------
int *seq = LoadRandomSequence((unsigned int)rectCount, 0, (unsigned int)rectCount-1); // Module Functions Definition
ColorRect* rectangles = (ColorRect *)malloc((int)rectCount*sizeof(ColorRect)); //------------------------------------------------------------------------------------
static Color GenerateRandomColor(void)
float rectSeqWidth = rectCount * rectWidth; {
float startX = (screenWidth - rectSeqWidth) * 0.5f; Color color = {
GetRandomValue(0, 255),
for(int x=0;x<rectCount;x++){ GetRandomValue(0, 255),
int rectHeight = (int)Remap((float)seq[x], 0, rectCount-1, 0, screenHeight); GetRandomValue(0, 255),
rectangles[x].c = GenerateRandomColor(); 255
rectangles[x].r = CLITERAL(Rectangle){
startX + x * rectWidth, screenHeight - rectHeight, rectWidth, (float)rectHeight
}; };
}
UnloadRandomSequence(seq); return color;
return rectangles;
} }
static void ShuffleColorRectSequence(ColorRect* rectangles, int rectCount) static ColorRect *GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight)
{ {
int *seq = LoadRandomSequence(rectCount, 0, rectCount-1); ColorRect *rectangles = (ColorRect *)RL_CALLOC((int)rectCount, sizeof(ColorRect));
for(int i1=0;i1<rectCount;i1++){
ColorRect* r1 = &rectangles[i1];
ColorRect* r2 = &rectangles[seq[i1]];
// swap only the color and height int *seq = LoadRandomSequence((unsigned int)rectCount, 0, (unsigned int)rectCount - 1);
ColorRect tmp = *r1; float rectSeqWidth = rectCount*rectWidth;
r1->c = r2->c; float startX = (screenWidth - rectSeqWidth)*0.5f;
r1->r.height = r2->r.height;
r1->r.y = r2->r.y;
r2->c = tmp.c;
r2->r.height = tmp.r.height;
r2->r.y = tmp.r.y;
} for (int i = 0; i < rectCount; i++)
UnloadRandomSequence(seq); {
int rectHeight = (int)Remap((float)seq[i], 0, rectCount - 1, 0, screenHeight);
rectangles[i].color = GenerateRandomColor();
rectangles[i].rect = CLITERAL(Rectangle){ startX + i*rectWidth, screenHeight - rectHeight, rectWidth, (float)rectHeight };
}
UnloadRandomSequence(seq);
return rectangles;
} }
static void DrawTextCenterKeyHelp(const char* key, const char* text, int posX, int posY, int fontSize, Color color) static void ShuffleColorRectSequence(ColorRect *rectangles, int rectCount)
{ {
int spaceSize = MeasureText(" ", fontSize); int *seq = LoadRandomSequence(rectCount, 0, rectCount - 1);
int pressSize = MeasureText("Press", fontSize);
int keySize = MeasureText(key, fontSize);
int textSize = MeasureText(text, fontSize);
int totalSize = pressSize + 2 * spaceSize + keySize + 2 * spaceSize + textSize;
int textSizeCurrent = 0;
DrawText("Press", posX, posY, fontSize, color); for (int i1 = 0; i1 < rectCount; i1++)
textSizeCurrent += pressSize + 2 * spaceSize; {
DrawText(key, posX + textSizeCurrent, posY, fontSize, RED); ColorRect *r1 = &rectangles[i1];
DrawRectangle(posX + textSizeCurrent, posY + fontSize, keySize, 3, RED); ColorRect *r2 = &rectangles[seq[i1]];
textSizeCurrent += keySize + 2 * spaceSize;
DrawText(text, posX + textSizeCurrent, posY, fontSize, color); // Swap only the color and height
ColorRect tmp = *r1;
r1->color = r2->color;
r1->rect.height = r2->rect.height;
r1->rect.y = r2->rect.y;
r2->color = tmp.color;
r2->rect.height = tmp.rect.height;
r2->rect.y = tmp.rect.y;
}
UnloadRandomSequence(seq);
} }

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Generate random values * raylib [core] example - random values
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 1.1, last time updated with raylib 1.1 * Example originally created with raylib 1.1, last time updated with raylib 1.1
* *
* 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) 2014-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -23,7 +25,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - generate random values"); InitWindow(screenWidth, screenHeight, "raylib [core] example - random values");
// SetRandomSeed(0xaabbccff); // Set a custom random seed if desired, by default: "time(NULL)" // SetRandomSeed(0xaabbccff); // Set a custom random seed if desired, by default: "time(NULL)"

View File

@ -0,0 +1,99 @@
/*******************************************************************************************
*
* raylib [core] example - render texture
*
* Example complexity rating: [] 1/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"
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//---------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - render texture");
// Define a render texture to render
int renderTextureWidth = 300;
int renderTextureHeight = 300;
RenderTexture2D target = LoadRenderTexture(renderTextureWidth, renderTextureHeight);
Vector2 ballPosition = { renderTextureWidth/2.0f, renderTextureHeight/2.0f };
Vector2 ballSpeed = { 5.0f, 4.0f };
int ballRadius = 20;
float rotation = 0.0f;
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
//-----------------------------------------------------
// Ball movement logic
ballPosition.x += ballSpeed.x;
ballPosition.y += ballSpeed.y;
// Check walls collision for bouncing
if ((ballPosition.x >= (renderTextureWidth - ballRadius)) || (ballPosition.x <= ballRadius)) ballSpeed.x *= -1.0f;
if ((ballPosition.y >= (renderTextureHeight - ballRadius)) || (ballPosition.y <= ballRadius)) ballSpeed.y *= -1.0f;
// Render texture rotation
rotation += 0.5f;
//-----------------------------------------------------
// Draw
//-----------------------------------------------------
// Draw our scene to the render texture
BeginTextureMode(target);
ClearBackground(SKYBLUE);
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
EndTextureMode();
// Draw render texture to main framebuffer
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw our render texture with rotation applied
// NOTE: We set the origin of the texture to the center of the render texture
DrawTexturePro(target.texture,
(Rectangle){ 0, 0, target.texture.width, -target.texture.height },
(Rectangle){ screenWidth/2, screenHeight/2, target.texture.width, -target.texture.height },
(Vector2){ target.texture.width/2, target.texture.height/2 }, rotation, WHITE);
DrawText("DRAWING BOUNCING BALL INSIDE RENDER TEXTURE!", 10, screenHeight - 40, 20, BLACK);
DrawFPS(10, 10);
EndDrawing();
//-----------------------------------------------------
}
// De-Initialization
//---------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//----------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Scissor test * raylib [core] example - scissor test
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 2.5, last time updated with raylib 3.0 * Example originally created with raylib 2.5, last time updated with raylib 3.0
* *
@ -9,7 +11,7 @@
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2019-2024 Chris Dill (@MysteriousSpace) * Copyright (c) 2019-2025 Chris Dill (@MysteriousSpace)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Smooth Pixel-perfect camera * raylib [core] example - smooth pixelperfect
*
* Example complexity rating: [] 3/4
* *
* Example originally created with raylib 3.7, last time updated with raylib 4.0 * Example originally created with raylib 3.7, last time updated with raylib 4.0
* *
@ -10,7 +12,7 @@
* 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) 2021-2024 Giancamillo Alessandroni (@NotManyIdeasDev) and Ramon Santamaria (@raysan5) * Copyright (c) 2021-2025 Giancamillo Alessandroni (@NotManyIdeasDev) and Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -33,7 +35,7 @@ int main(void)
const float virtualRatio = (float)screenWidth/(float)virtualScreenWidth; const float virtualRatio = (float)screenWidth/(float)virtualScreenWidth;
InitWindow(screenWidth, screenHeight, "raylib [core] example - smooth pixel-perfect camera"); InitWindow(screenWidth, screenHeight, "raylib [core] example - smooth pixelperfect");
Camera2D worldSpaceCamera = { 0 }; // Game world camera Camera2D worldSpaceCamera = { 0 }; // Game world camera
worldSpaceCamera.zoom = 1.0f; worldSpaceCamera.zoom = 1.0f;
@ -41,7 +43,8 @@ int main(void)
Camera2D screenSpaceCamera = { 0 }; // Smoothing camera Camera2D screenSpaceCamera = { 0 }; // Smoothing camera
screenSpaceCamera.zoom = 1.0f; screenSpaceCamera.zoom = 1.0f;
RenderTexture2D target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight); // This is where we'll draw all our objects. // Load render texture to draw all our objects
RenderTexture2D target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight);
Rectangle rec01 = { 70.0f, 35.0f, 20.0f, 20.0f }; Rectangle rec01 = { 70.0f, 35.0f, 20.0f, 20.0f };
Rectangle rec02 = { 90.0f, 55.0f, 30.0f, 10.0f }; Rectangle rec02 = { 90.0f, 55.0f, 30.0f, 10.0f };

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Storage save/load values * raylib [core] example - storage values
*
* Example complexity rating: [] 2/4
* *
* Example originally created with raylib 1.4, last time updated with raylib 4.2 * Example originally created with raylib 1.4, last time updated with raylib 4.2
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -23,7 +25,9 @@ typedef enum {
STORAGE_POSITION_HISCORE = 1 STORAGE_POSITION_HISCORE = 1
} StorageData; } StorageData;
// Persistent storage functions //------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static bool SaveStorageValue(unsigned int position, int value); static bool SaveStorageValue(unsigned int position, int value);
static int LoadStorageValue(unsigned int position); static int LoadStorageValue(unsigned int position);
@ -37,7 +41,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - storage save/load values"); InitWindow(screenWidth, screenHeight, "raylib [core] example - storage values");
int score = 0; int score = 0;
int hiscore = 0; int hiscore = 0;
@ -99,6 +103,9 @@ int main(void)
return 0; return 0;
} }
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
// Save integer value to storage file (to defined position) // Save integer value to storage file (to defined position)
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer) // NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
bool SaveStorageValue(unsigned int position, int value) bool SaveStorageValue(unsigned int position, int value)

View File

@ -0,0 +1,312 @@
/*******************************************************************************************
*
* raylib [core] example - undo redo
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6
*
* Example contributed 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 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <stdlib.h> // Required for: calloc(), free()
#include <string.h> // Required for: memcpy(), strcmp()
#define MAX_UNDO_STATES 26 // Maximum undo states supported for the ring buffer
#define GRID_CELL_SIZE 24
#define MAX_GRID_CELLS_X 30
#define MAX_GRID_CELLS_Y 13
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Point struct, like Vector2 but using int
typedef struct {
int x;
int y;
} Point;
// Player state struct
// NOTE: Contains all player data that needs to be affected by undo/redo
typedef struct {
Point cell;
Color color;
} PlayerState;
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
// Draw undo system visualization logic
static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoIndex, int currentUndoIndex, int slotSize);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
// We have multiple options to implement an Undo/Redo system
// Probably the most professional one is using the Command pattern to
// define Actions and store those actions into an array as the events happen,
// raylib internal Automation System actually uses a similar approach,
// but in this example we are using another more simple solution,
// just record PlayerState changes when detected, checking for changes every certain frames
// This approach requires more memory and is more performance costly but it is quite simple to implement
InitWindow(screenWidth, screenHeight, "raylib [core] example - undo redo");
// Undo/redo system variables
int currentUndoIndex = 0;
int firstUndoIndex = 0;
int lastUndoIndex = 0;
int undoFrameCounter = 0;
Vector2 undoInfoPos = { 110, 400 };
// Init current player state and undo/redo recorded states array
PlayerState player = { 0 };
player.cell = (Point){ 10, 10 };
player.color = RED;
// Init undo buffer to store MAX_UNDO_STATES states
PlayerState *states = (PlayerState *)RL_CALLOC(MAX_UNDO_STATES, sizeof(PlayerState));
// Init all undo states to current state
for (int i = 0; i < MAX_UNDO_STATES; i++) memcpy(&states[i], &player, sizeof(PlayerState));
// Grid variables
Vector2 gridPosition = { 40, 60 };
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Player movement logic
if (IsKeyPressed(KEY_RIGHT)) player.cell.x++;
else if (IsKeyPressed(KEY_LEFT)) player.cell.x--;
else if (IsKeyPressed(KEY_UP)) player.cell.y--;
else if (IsKeyPressed(KEY_DOWN)) player.cell.y++;
// Make sure player does not go out of bounds
if (player.cell.x < 0) player.cell.x = 0;
else if (player.cell.x >= MAX_GRID_CELLS_X) player.cell.x = MAX_GRID_CELLS_X - 1;
if (player.cell.y < 0) player.cell.y = 0;
else if (player.cell.y >= MAX_GRID_CELLS_Y) player.cell.y = MAX_GRID_CELLS_Y - 1;
// Player color change logic
if (IsKeyPressed(KEY_SPACE))
{
player.color.r = (unsigned char)GetRandomValue(20, 255);
player.color.g = (unsigned char)GetRandomValue(20, 220);
player.color.b = (unsigned char)GetRandomValue(20, 240);
}
// Undo state change logic
undoFrameCounter++;
// Waiting a number of frames before checking if we should store a new state snapshot
if (undoFrameCounter >= 2) // Checking every 2 frames
{
if (memcmp(&states[currentUndoIndex], &player, sizeof(PlayerState)) != 0)
{
// Move cursor to next available position of the undo ring buffer to record state
currentUndoIndex++;
if (currentUndoIndex >= MAX_UNDO_STATES) currentUndoIndex = 0;
if (currentUndoIndex == firstUndoIndex) firstUndoIndex++;
if (firstUndoIndex >= MAX_UNDO_STATES) firstUndoIndex = 0;
memcpy(&states[currentUndoIndex], &player, sizeof(PlayerState));
lastUndoIndex = currentUndoIndex;
}
undoFrameCounter = 0;
}
// Recover previous state from buffer: CTRL+Z
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_Z))
{
if (currentUndoIndex != firstUndoIndex)
{
currentUndoIndex--;
if (currentUndoIndex < 0) currentUndoIndex = MAX_UNDO_STATES - 1;
if (memcmp(&states[currentUndoIndex], &player, sizeof(PlayerState)) != 0)
{
memcpy(&player, &states[currentUndoIndex], sizeof(PlayerState));
}
}
}
// Recover next state from buffer: CTRL+Y
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_Y))
{
if (currentUndoIndex != lastUndoIndex)
{
int nextUndoIndex = currentUndoIndex + 1;
if (nextUndoIndex >= MAX_UNDO_STATES) nextUndoIndex = 0;
if (nextUndoIndex != firstUndoIndex)
{
currentUndoIndex = nextUndoIndex;
if (memcmp(&states[currentUndoIndex], &player, sizeof(PlayerState)) != 0)
{
memcpy(&player, &states[currentUndoIndex], sizeof(PlayerState));
}
}
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw controls info
DrawText("[ARROWS] MOVE PLAYER - [SPACE] CHANGE PLAYER COLOR", 40, 20, 20, DARKGRAY);
// Draw player visited cells recorded by undo
// NOTE: Remember we are using a ring buffer approach so,
// some cells info could start at the end of the array and end at the beginning
if (lastUndoIndex > firstUndoIndex)
{
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
DrawRectangle(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);
}
else if (firstUndoIndex > lastUndoIndex)
{
if ((currentUndoIndex < MAX_UNDO_STATES) && (currentUndoIndex > lastUndoIndex))
{
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
DrawRectangle(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);
}
else
{
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
DrawRectangle(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);
for (int i = 0; i < currentUndoIndex; i++)
DrawRectangle(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);
}
}
// Draw game grid
for (int y = 0; y <= MAX_GRID_CELLS_Y; y++)
DrawLine(gridPosition.x, gridPosition.y + y*GRID_CELL_SIZE,
gridPosition.x + MAX_GRID_CELLS_X*GRID_CELL_SIZE, gridPosition.y + y*GRID_CELL_SIZE, GRAY);
for (int x = 0; x <= MAX_GRID_CELLS_X; x++)
DrawLine(gridPosition.x + x*GRID_CELL_SIZE, gridPosition.y,
gridPosition.x + x*GRID_CELL_SIZE, gridPosition.y + MAX_GRID_CELLS_Y*GRID_CELL_SIZE, GRAY);
// Draw player
DrawRectangle(gridPosition.x + player.cell.x*GRID_CELL_SIZE, gridPosition.y + player.cell.y*GRID_CELL_SIZE,
GRID_CELL_SIZE + 1, GRID_CELL_SIZE + 1, player.color);
// Draw undo system buffer info
DrawText("UNDO STATES:", undoInfoPos.x - 85, undoInfoPos.y + 9, 10, DARKGRAY);
DrawUndoBuffer(undoInfoPos, firstUndoIndex, lastUndoIndex, currentUndoIndex, 24);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
RL_FREE(states); // Free undo states array
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
// Draw undo system visualization logic
// NOTE: Visualizing the ring buffer array, every square can store a player state
static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoIndex, int currentUndoIndex, int slotSize)
{
// Draw index marks
DrawRectangle(position.x + 8 + slotSize*currentUndoIndex, position.y - 10, 8, 8, RED);
DrawRectangleLines(position.x + 2 + slotSize*firstUndoIndex, position.y + 27, 8, 8, BLACK);
DrawRectangle(position.x + 14 + slotSize*lastUndoIndex, position.y + 27, 8, 8, BLACK);
// Draw background gray slots
for (int i = 0; i < MAX_UNDO_STATES; i++)
{
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, LIGHTGRAY);
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, GRAY);
}
// Draw occupied slots: firstUndoIndex --> lastUndoIndex
if (firstUndoIndex <= lastUndoIndex)
{
for (int i = firstUndoIndex; i < lastUndoIndex + 1; i++)
{
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
}
}
else if (lastUndoIndex < firstUndoIndex)
{
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
{
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
}
for (int i = 0; i < lastUndoIndex + 1; i++)
{
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
}
}
// Draw occupied slots: firstUndoIndex --> currentUndoIndex
if (firstUndoIndex < currentUndoIndex)
{
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
{
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
}
}
else if (currentUndoIndex < firstUndoIndex)
{
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
{
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
}
for (int i = 0; i < currentUndoIndex; i++)
{
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
}
}
// Draw current selected UNDO slot
DrawRectangle(position.x + slotSize*currentUndoIndex, position.y, slotSize, slotSize, GOLD);
DrawRectangleLines(position.x + slotSize*currentUndoIndex, position.y, slotSize, slotSize, ORANGE);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - VR Simulator (Oculus Rift CV1 parameters) * raylib [core] example - vr simulator
*
* Example complexity rating: [] 3/4
* *
* Example originally created with raylib 2.5, last time updated with raylib 4.0 * Example originally created with raylib 2.5, last time updated with raylib 4.0
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2017-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -59,7 +61,7 @@ int main(void)
VrStereoConfig config = LoadVrStereoConfig(device); VrStereoConfig config = LoadVrStereoConfig(device);
// Distortion shader (uses device lens distortion and chroma) // Distortion shader (uses device lens distortion and chroma)
Shader distortion = LoadShader(0, TextFormat("resources/distortion%i.fs", GLSL_VERSION)); Shader distortion = LoadShader(0, TextFormat("resources/shaders/glsl%i/distortion.fs", GLSL_VERSION));
// Update distortion shader with lens and distortion-scale parameters // Update distortion shader with lens and distortion-scale parameters
SetShaderValue(distortion, GetShaderLocation(distortion, "leftLensCenter"), SetShaderValue(distortion, GetShaderLocation(distortion, "leftLensCenter"),

View File

@ -2,12 +2,14 @@
* *
* raylib [core] example - window flags * raylib [core] example - window flags
* *
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 3.5, last time updated with raylib 3.5 * Example originally created with raylib 3.5, last time updated with raylib 3.5
* *
* 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) 2020-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2020-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -44,13 +46,13 @@ int main(void)
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI); //SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
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 };
Vector2 ballSpeed = { 5.0f, 4.0f }; Vector2 ballSpeed = { 5.0f, 4.0f };
float ballRadius = 20; float ballRadius = 20;
int framesCounter = 0; int framesCounter = 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
//---------------------------------------------------------- //----------------------------------------------------------
// Main game loop // Main game loop
@ -95,7 +97,10 @@ int main(void)
if (IsWindowState(FLAG_WINDOW_MINIMIZED)) if (IsWindowState(FLAG_WINDOW_MINIMIZED))
{ {
framesCounter++; framesCounter++;
if (framesCounter >= 240) RestoreWindow(); // Restore window after 3 seconds if (framesCounter >= 240) {
RestoreWindow(); // Restore window after 3 seconds
framesCounter = 0;
}
} }
if (IsKeyPressed(KEY_M)) if (IsKeyPressed(KEY_M))
@ -129,6 +134,9 @@ int main(void)
else SetWindowState(FLAG_VSYNC_HINT); else SetWindowState(FLAG_VSYNC_HINT);
} }
if (IsKeyPressed(KEY_B)) ToggleBorderlessWindowed();
// Bouncing ball logic // Bouncing ball logic
ballPosition.x += ballSpeed.x; ballPosition.x += ballSpeed.x;
ballPosition.y += ballSpeed.y; ballPosition.y += ballSpeed.y;
@ -161,9 +169,9 @@ int main(void)
if (IsWindowState(FLAG_WINDOW_UNDECORATED)) DrawText("[D] FLAG_WINDOW_UNDECORATED: on", 10, 120, 10, LIME); if (IsWindowState(FLAG_WINDOW_UNDECORATED)) DrawText("[D] FLAG_WINDOW_UNDECORATED: on", 10, 120, 10, LIME);
else DrawText("[D] FLAG_WINDOW_UNDECORATED: off", 10, 120, 10, MAROON); else DrawText("[D] FLAG_WINDOW_UNDECORATED: off", 10, 120, 10, MAROON);
if (IsWindowState(FLAG_WINDOW_HIDDEN)) DrawText("[H] FLAG_WINDOW_HIDDEN: on", 10, 140, 10, LIME); if (IsWindowState(FLAG_WINDOW_HIDDEN)) DrawText("[H] FLAG_WINDOW_HIDDEN: on", 10, 140, 10, LIME);
else DrawText("[H] FLAG_WINDOW_HIDDEN: off", 10, 140, 10, MAROON); else DrawText("[H] FLAG_WINDOW_HIDDEN: off (hides for 3 seconds)", 10, 140, 10, MAROON);
if (IsWindowState(FLAG_WINDOW_MINIMIZED)) DrawText("[N] FLAG_WINDOW_MINIMIZED: on", 10, 160, 10, LIME); if (IsWindowState(FLAG_WINDOW_MINIMIZED)) DrawText("[N] FLAG_WINDOW_MINIMIZED: on", 10, 160, 10, LIME);
else DrawText("[N] FLAG_WINDOW_MINIMIZED: off", 10, 160, 10, MAROON); else DrawText("[N] FLAG_WINDOW_MINIMIZED: off (restores after 3 seconds)", 10, 160, 10, MAROON);
if (IsWindowState(FLAG_WINDOW_MAXIMIZED)) DrawText("[M] FLAG_WINDOW_MAXIMIZED: on", 10, 180, 10, LIME); if (IsWindowState(FLAG_WINDOW_MAXIMIZED)) DrawText("[M] FLAG_WINDOW_MAXIMIZED: on", 10, 180, 10, LIME);
else DrawText("[M] FLAG_WINDOW_MAXIMIZED: off", 10, 180, 10, MAROON); else DrawText("[M] FLAG_WINDOW_MAXIMIZED: off", 10, 180, 10, MAROON);
if (IsWindowState(FLAG_WINDOW_UNFOCUSED)) DrawText("[G] FLAG_WINDOW_UNFOCUSED: on", 10, 200, 10, LIME); if (IsWindowState(FLAG_WINDOW_UNFOCUSED)) DrawText("[G] FLAG_WINDOW_UNFOCUSED: on", 10, 200, 10, LIME);
@ -174,14 +182,16 @@ int main(void)
else DrawText("[A] FLAG_WINDOW_ALWAYS_RUN: off", 10, 240, 10, MAROON); else DrawText("[A] FLAG_WINDOW_ALWAYS_RUN: off", 10, 240, 10, MAROON);
if (IsWindowState(FLAG_VSYNC_HINT)) DrawText("[V] FLAG_VSYNC_HINT: on", 10, 260, 10, LIME); if (IsWindowState(FLAG_VSYNC_HINT)) DrawText("[V] FLAG_VSYNC_HINT: on", 10, 260, 10, LIME);
else DrawText("[V] FLAG_VSYNC_HINT: off", 10, 260, 10, MAROON); else DrawText("[V] FLAG_VSYNC_HINT: off", 10, 260, 10, MAROON);
if (IsWindowState(FLAG_BORDERLESS_WINDOWED_MODE)) DrawText("[B] FLAG_BORDERLESS_WINDOWED_MODE: on", 10, 280, 10, LIME);
else DrawText("[B] FLAG_BORDERLESS_WINDOWED_MODE: off", 10, 280, 10, MAROON);
DrawText("Following flags can only be set before window creation:", 10, 300, 10, GRAY); DrawText("Following flags can only be set before window creation:", 10, 320, 10, GRAY);
if (IsWindowState(FLAG_WINDOW_HIGHDPI)) DrawText("FLAG_WINDOW_HIGHDPI: on", 10, 320, 10, LIME); if (IsWindowState(FLAG_WINDOW_HIGHDPI)) DrawText("FLAG_WINDOW_HIGHDPI: on", 10, 340, 10, LIME);
else DrawText("FLAG_WINDOW_HIGHDPI: off", 10, 320, 10, MAROON); else DrawText("FLAG_WINDOW_HIGHDPI: off", 10, 340, 10, MAROON);
if (IsWindowState(FLAG_WINDOW_TRANSPARENT)) DrawText("FLAG_WINDOW_TRANSPARENT: on", 10, 340, 10, LIME); if (IsWindowState(FLAG_WINDOW_TRANSPARENT)) DrawText("FLAG_WINDOW_TRANSPARENT: on", 10, 360, 10, LIME);
else DrawText("FLAG_WINDOW_TRANSPARENT: off", 10, 340, 10, MAROON); else DrawText("FLAG_WINDOW_TRANSPARENT: off", 10, 360, 10, MAROON);
if (IsWindowState(FLAG_MSAA_4X_HINT)) DrawText("FLAG_MSAA_4X_HINT: on", 10, 360, 10, LIME); if (IsWindowState(FLAG_MSAA_4X_HINT)) DrawText("FLAG_MSAA_4X_HINT: on", 10, 380, 10, LIME);
else DrawText("FLAG_MSAA_4X_HINT: off", 10, 360, 10, MAROON); else DrawText("FLAG_MSAA_4X_HINT: off", 10, 380, 10, MAROON);
EndDrawing(); EndDrawing();
//----------------------------------------------------- //-----------------------------------------------------

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - window scale letterbox (and virtual mouse) * raylib [core] example - window letterbox
*
* Example complexity rating: [] 2/4
* *
* Example originally created with raylib 2.5, last time updated with raylib 4.0 * Example originally created with raylib 2.5, last time updated with raylib 4.0
* *
@ -9,7 +11,7 @@
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2019-2024 Anata (@anatagawa) and Ramon Santamaria (@raysan5) * Copyright (c) 2019-2025 Anata (@anatagawa) and Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -25,12 +27,12 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
int main(void) int main(void)
{ {
const int windowWidth = 800; const int screenWidth = 800;
const int windowHeight = 450; const int screenHeight = 450;
// Enable config flags for resizable window and vertical synchro // Enable config flags for resizable window and vertical synchro
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT); SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT);
InitWindow(windowWidth, windowHeight, "raylib [core] example - window scale letterbox"); InitWindow(screenWidth, screenHeight, "raylib [core] example - window letterbox");
SetWindowMinSize(320, 240); SetWindowMinSize(320, 240);
int gameScreenWidth = 640; int gameScreenWidth = 640;

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Window should close * raylib [core] example - window should close
*
* Example complexity rating: [] 1/4
* *
* Example originally created with raylib 4.2, last time updated with raylib 4.2 * Example originally created with raylib 4.2, last time updated with raylib 4.2
* *
* 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) 2013-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - World to screen * raylib [core] example - world screen
*
* Example complexity rating: [] 2/4
* *
* Example originally created with raylib 1.3, last time updated with raylib 1.4 * Example originally created with raylib 1.3, last time updated with raylib 1.4
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -23,7 +25,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - core world screen"); InitWindow(screenWidth, screenHeight, "raylib [core] example - world screen");
// Define the camera to look into our 3d world // Define the camera to look into our 3d world
Camera camera = { 0 }; Camera camera = { 0 };
@ -67,7 +69,7 @@ int main(void)
EndMode3D(); EndMode3D();
DrawText("Enemy: 100 / 100", (int)cubeScreenPosition.x - MeasureText("Enemy: 100/100", 20)/2, (int)cubeScreenPosition.y, 20, BLACK); DrawText("Enemy: 100/100", (int)cubeScreenPosition.x - MeasureText("Enemy: 100/100", 20)/2, (int)cubeScreenPosition.y, 20, BLACK);
DrawText(TextFormat("Cube position in screen space coordinates: [%i, %i]", (int)cubeScreenPosition.x, (int)cubeScreenPosition.y), 10, 10, 20, LIME); DrawText(TextFormat("Cube position in screen space coordinates: [%i, %i]", (int)cubeScreenPosition.x, (int)cubeScreenPosition.y), 10, 10, 20, LIME);
DrawText("Text 2d should be always on top of the cube", 10, 40, 20, GRAY); DrawText("Text 2d should be always on top of the cube", 10, 40, 20, GRAY);

View File

@ -10,7 +10,7 @@ varying vec4 fragColor;
uniform sampler2D texture0; uniform sampler2D texture0;
uniform vec4 colDiffuse; uniform vec4 colDiffuse;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
uniform vec2 leftLensCenter; uniform vec2 leftLensCenter;
uniform vec2 rightLensCenter; uniform vec2 rightLensCenter;
uniform vec2 leftScreenCenter; uniform vec2 leftScreenCenter;

View File

@ -0,0 +1,50 @@
#version 120
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// NOTE: Add your custom variables here
uniform vec2 leftLensCenter;
uniform vec2 rightLensCenter;
uniform vec2 leftScreenCenter;
uniform vec2 rightScreenCenter;
uniform vec2 scale;
uniform vec2 scaleIn;
uniform vec4 deviceWarpParam;
uniform vec4 chromaAbParam;
void main()
{
// Compute lens distortion
vec2 lensCenter = fragTexCoord.x < 0.5? leftLensCenter : rightLensCenter;
vec2 screenCenter = fragTexCoord.x < 0.5? leftScreenCenter : rightScreenCenter;
vec2 theta = (fragTexCoord - lensCenter)*scaleIn;
float rSq = theta.x*theta.x + theta.y*theta.y;
vec2 theta1 = theta*(deviceWarpParam.x + deviceWarpParam.y*rSq + deviceWarpParam.z*rSq*rSq + deviceWarpParam.w*rSq*rSq*rSq);
vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq);
vec2 tcBlue = lensCenter + scale*thetaBlue;
if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue)))
{
// Set black fragment for everything outside the lens border
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
else
{
// Compute color chroma aberration
float blue = texture2D(texture0, tcBlue).b;
vec2 tcGreen = lensCenter + scale*theta1;
float green = texture2D(texture0, tcGreen).g;
vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq);
vec2 tcRed = lensCenter + scale*thetaRed;
float red = texture2D(texture0, tcRed).r;
gl_FragColor = vec4(red, green, blue, 1.0);
}
}

View File

@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
// Output fragment color // Output fragment color
out vec4 finalColor; out vec4 finalColor;
// NOTE: Add here your custom variables // NOTE: Add your custom variables here
uniform vec2 leftLensCenter = vec2(0.288, 0.5); uniform vec2 leftLensCenter = vec2(0.288, 0.5);
uniform vec2 rightLensCenter = vec2(0.712, 0.5); uniform vec2 rightLensCenter = vec2(0.712, 0.5);
uniform vec2 leftScreenCenter = vec2(0.25, 0.5); uniform vec2 leftScreenCenter = vec2(0.25, 0.5);

View File

@ -1,27 +1,27 @@
GLFW_ICON ICON "raylib.ico" GLFW_ICON ICON "raylib.ico"
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 1,0,0,0 FILEVERSION 5,5,0,0
PRODUCTVERSION 1,0,0,0 PRODUCTVERSION 5,5,0,0
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
//BLOCK "080904E4" // English UK //BLOCK "080904E4" // English UK
BLOCK "040904E4" // English US BLOCK "040904E4" // English US
BEGIN BEGIN
VALUE "CompanyName", "raylib technologies" VALUE "CompanyName", "raylib technologies"
VALUE "FileDescription", "raylib example" VALUE "FileDescription", "raylib application (www.raylib.com)"
VALUE "FileVersion", "1.0" VALUE "FileVersion", "5.5.0"
VALUE "InternalName", "raylib-example" VALUE "InternalName", "raylib-example"
VALUE "LegalCopyright", "(c) 2024 raylib technologies (@raylibtech)" VALUE "LegalCopyright", "(c) 2025 Ramon Santamaria (@raysan5)"
//VALUE "OriginalFilename", "raylib_app.exe" VALUE "OriginalFilename", "raylib-example"
VALUE "ProductName", "raylib-example" VALUE "ProductName", "raylib-example"
VALUE "ProductVersion", "1.0" VALUE "ProductVersion", "5.5.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
BEGIN BEGIN
//VALUE "Translation", 0x809, 1252 // English UK //VALUE "Translation", 0x809, 1252 // English UK
VALUE "Translation", 0x409, 1252 // English US VALUE "Translation", 0x409, 1252 // English US
END END
END END

172
examples/examples_list.txt Normal file
View File

@ -0,0 +1,172 @@
#
# raylib examples list used to generate/update collection
# 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>
#
# 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_input_keys;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
core;core_input_mouse;★☆☆☆;1.0;5.5;2014;2025;"Ramon Santamaria";@raysan5
core;core_input_mouse_wheel;★☆☆☆;1.1;1.3;2014;2025;"Ramon Santamaria";@raysan5
core;core_input_gamepad;★☆☆☆;1.1;4.2;2013;2025;"Ramon Santamaria";@raysan5
core;core_input_multitouch;★☆☆☆;2.1;2.5;2019;2025;"Berni";@Berni8k
core;core_input_gestures;★★☆☆;1.4;4.2;2016;2025;"Ramon Santamaria";@raysan5
core;core_input_gestures_testbed;★★★☆;5.0;5.6-dev;2023;2025;"ubkp";@ubkp
core;core_input_virtual_controls;★★☆☆;5.0;5.0;2024;2025;"GreenSnakeLinux";@GreenSnakeLinux
core;core_2d_camera;★★☆☆;1.5;3.0;2016;2025;"Ramon Santamaria";@raysan5
core;core_2d_camera_mouse_zoom;★★☆☆;4.2;4.2;2022;2025;"Jeffery Myers";@JeffM2501
core;core_2d_camera_platformer;★★★☆;2.5;3.0;2019;2025;"arvyy";@arvyy
core;core_2d_camera_split_screen;★★★★;4.5;4.5;2023;2025;"Gabriel dos Santos Sanches";@gabrielssanches
core;core_3d_camera_mode;★☆☆☆;1.0;1.0;2014;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_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_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_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
core;core_window_letterbox;★★☆☆;2.5;4.0;2019;2025;"Anata";@anatagawa
core;core_window_should_close;★☆☆☆;4.2;4.2;2013;2025;"Ramon Santamaria";@raysan5
core;core_custom_logging;★★★☆;2.5;2.5;2018;2025;"Pablo Marcos Oltra";@pamarcos
core;core_drop_files;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
core;core_random_values;★☆☆☆;1.1;1.1;2014;2025;"Ramon Santamaria";@raysan5
core;core_storage_values;★★☆☆;1.4;4.2;2015;2025;"Ramon Santamaria";@raysan5
core;core_vr_simulator;★★★☆;2.5;4.0;2017;2025;"Ramon Santamaria";@raysan5
core;core_scissor_test;★☆☆☆;2.5;3.0;2019;2025;"Chris Dill";@MysteriousSpace
core;core_basic_screen_manager;★☆☆☆;4.0;4.0;2021;2025;"Ramon Santamaria";@raysan5
core;core_custom_frame_control;★★★★;4.0;4.0;2021;2025;"Ramon Santamaria";@raysan5
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_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_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
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_colors_palette;★★☆☆;1.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_logo_raylib_anim;★★☆☆;2.5;4.0;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_rectangle_scaling;★★☆☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
shapes;shapes_lines_bezier;★☆☆☆;1.7;1.7;2017;2025;"Ramon Santamaria";@raysan5
shapes;shapes_collision_area;★★☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
shapes;shapes_following_eyes;★★☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
shapes;shapes_easings_ball;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_easings_box;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_easings_rectangles;★★★☆;2.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_ring_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
shapes;shapes_circle_sector_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
shapes;shapes_rounded_rectangle_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
shapes;shapes_top_down_lights;★★★★;4.2;4.2;2022;2025;"Jeffery Myers";@JeffM2501
shapes;shapes_rectangle_advanced;★★★★;5.5;5.5;2024;2025;"Everton Jr.";@evertonse
shapes;shapes_splines_drawing;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
shapes;shapes_digital_clock;★★★★;5.5;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
shapes;shapes_double_pendulum;★★☆☆;5.5;5.5;2025;2025;"JoeCheong";@Joecheong2006
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_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
textures;textures_image_generation;★★☆☆;1.8;1.8;2017;2025;"Wilhem Barbier";@nounoursheureux
textures;textures_image_loading;★☆☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
textures;textures_image_processing;★★★☆;1.4;3.5;2016;2025;"Ramon Santamaria";@raysan5
textures;textures_image_text;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria";@raysan5
textures;textures_to_image;★☆☆☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5
textures;textures_raw_data;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
textures;textures_particles_blending;★☆☆☆;1.7;3.5;2017;2025;"Ramon Santamaria";@raysan5
textures;textures_npatch_drawing;★★★☆;2.0;2.5;2018;2025;"Jorge A. Gomes";@overdev
textures;textures_background_scrolling;★☆☆☆;2.0;2.5;2019;2025;"Ramon Santamaria";@raysan5
textures;textures_sprite_animation;★★☆☆;1.3;1.3;2014;2025;"Ramon Santamaria";@raysan5
textures;textures_sprite_button;★★☆☆;2.5;2.5;2019;2025;"Ramon Santamaria";@raysan5
textures;textures_sprite_explosion;★★☆☆;2.5;3.5;2019;2025;"Ramon Santamaria";@raysan5
textures;textures_bunnymark;★★★☆;1.6;2.5;2014;2025;"Ramon Santamaria";@raysan5
textures;textures_mouse_painting;★★★☆;3.0;3.0;2019;2025;"Chris Dill";@MysteriousSpace
textures;textures_blend_modes;★☆☆☆;3.5;3.5;2020;2025;"Karlo Licudine";@accidentalrebel
textures;textures_tiled_drawing;★★★☆;3.0;4.2;2020;2025;"Vlad Adrian";@demizdor
textures;textures_polygon_drawing;★☆☆☆;3.7;3.7;2021;2025;"Chris Camacho";@chriscamacho
textures;textures_fog_of_war;★★★☆;4.2;4.2;2018;2025;"Ramon Santamaria";@raysan5
textures;textures_gif_player;★★★☆;4.2;4.2;2021;2025;"Ramon Santamaria";@raysan5
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_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501
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_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
text;text_font_loading;★☆☆☆;1.4;3.0;2016;2025;"Ramon Santamaria";@raysan5
text;text_font_sdf;★★★☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5
text;text_format_text;★☆☆☆;1.1;3.0;2014;2025;"Ramon Santamaria";@raysan5
text;text_input_box;★★☆☆;1.7;3.5;2017;2025;"Ramon Santamaria";@raysan5
text;text_writing_anim;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
text;text_rectangle_bounds;★★★★;2.5;4.0;2018;2025;"Vlad Adrian";@demizdor
text;text_unicode_emojis;★★★★;2.5;4.0;2019;2025;"Vlad Adrian";@demizdor
text;text_unicode_ranges;★★★★;5.5;5.6;2025;2025;"Vlad Adrian";@demizdor
text;text_3d_drawing;★★★★;3.5;4.0;2021;2025;"Vlad Adrian";@demizdor
text;text_codepoints_loading;★★★☆;4.2;4.2;2022;2025;"Ramon Santamaria";@raysan5
text;text_inline_styling;★★★☆;5.6-dev;5.6-dev;2025;2025;"Wagner Barongello";@SultansOfCode
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_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
models;models_cubicmap_rendering;★★☆☆;1.8;3.5;2015;2025;"Ramon Santamaria";@raysan5
models;models_first_person_maze;★★☆☆;2.5;3.5;2019;2025;"Ramon Santamaria";@raysan5
models;models_geometric_shapes;★☆☆☆;1.0;3.5;2014;2025;"Ramon Santamaria";@raysan5
models;models_mesh_generation;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria";@raysan5
models;models_mesh_picking;★★★☆;1.7;4.0;2017;2025;"Joel Davis";@joeld42
models;models_loading;★☆☆☆;2.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
models;models_loading_gltf;★☆☆☆;3.7;4.2;2020;2025;"Ramon Santamaria";@raysan5
models;models_loading_vox;★☆☆☆;4.0;4.0;2021;2025;"Johann Nadalutti";@procfxgen
models;models_loading_m3d;★★☆☆;4.5;4.5;2022;2025;"bzt";@bztsrc
models;models_orthographic_projection;★☆☆☆;2.0;3.7;2018;2025;"Max Danielsson";@autious
models;models_point_rendering;★★★☆;5.0;5.0;2024;2025;"Reese Gallagher";@satchelfrost
models;models_rlgl_solar_system;★★★★;2.5;4.0;2018;2025;"Ramon Santamaria";@raysan5
models;models_yaw_pitch_roll;★★☆☆;1.8;4.0;2017;2025;"Berni";@Berni8k
models;models_waving_cubes;★★★☆;2.5;3.7;2019;2025;"Codecat";@codecat
models;models_heightmap_rendering;★☆☆☆;1.8;3.5;2015;2025;"Ramon Santamaria";@raysan5
models;models_skybox_rendering;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria";@raysan5
models;models_textured_cube;★★☆☆;4.5;4.5;2022;2025;"Ramon Santamaria";@raysan5
models;models_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Holden";@orangeduck
models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur
models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz
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_shapes_textures;★★☆☆;1.7;3.7;2015;2025;"Ramon Santamaria";@raysan5
shaders;shaders_custom_uniform;★★☆☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5
shaders;shaders_postprocessing;★★★☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5
shaders;shaders_palette_switch;★★★☆;2.5;3.7;2019;2025;"Marco Lizza";@MarcoLizza
shaders;shaders_raymarching_rendering;★★★★;2.0;4.2;2018;2025;"Ramon Santamaria";@raysan5
shaders;shaders_texture_rendering;★★☆☆;2.0;3.7;2019;2025;"Michał Ciesielski";@ciessielski
shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff";@GoldenThumbs
shaders;shaders_texture_waves;★★☆☆;2.5;3.7;2019;2025;"Anata";@anatagawa
shaders;shaders_julia_set;★★★☆;2.5;4.0;2019;2025;"Josh Colclough";@joshcol9232
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_simple_mask;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
shaders;shaders_hot_reloading;★★★☆;3.0;3.5;2020;2025;"Ramon Santamaria";@raysan5
shaders;shaders_mesh_instancing;★★★★;3.7;4.2;2020;2025;"seanpringle";@seanpringle
shaders;shaders_multi_sample2d;★★☆☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
shaders;shaders_normalmap_rendering;★★★★;5.6;5.6;2025;2025;"Jeremy Montgomery";@Sir_Irk
shaders;shaders_spotlight_rendering;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
shaders;shaders_deferred_rendering;★★★★;4.5;4.5;2023;2025;"Justin Andreas Lacoste";@27justin
shaders;shaders_hybrid_rendering;★★★★;4.2;4.2;2022;2025;"Buğra Alptekin Sarı";@BugraAlptekinSari
shaders;shaders_texture_tiling;★★☆☆;4.5;4.5;2023;2025;"Luis Almeida";@luis605
shaders;shaders_shadowmap_rendering;★★★★;5.0;5.0;2023;2025;"TheManTheMythTheGameDev";@TheManTheMythTheGameDev
shaders;shaders_vertex_displacement;★★★☆;5.0;4.5;2023;2025;"Alex ZH";@ZzzhHe
shaders;shaders_depth_writing;★★☆☆;4.2;4.2;2022;2025;"Buğra Alptekin Sarı";@BugraAlptekinSari
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_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
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_raw_stream;★★★☆;1.6;4.2;2015;2025;"Ramon Santamaria";@raysan5
audio;audio_sound_loading;★☆☆☆;1.1;3.5;2014;2025;"Ramon Santamaria";@raysan5
audio;audio_mixed_processor;★★★★;4.2;4.2;2023;2025;"hkc";@hatkidchan
audio;audio_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_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71
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;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flashback-fx
others;raylib_opengl_interop;★★★★;3.8;4.0;2021;2025;"Stephan Soller";@arkanis
others;embedded_files_loading;★★☆☆;3.0;3.5;2020;2025;"Kristian Holmgren";@defutura
others;raymath_vector_angle;★★☆☆;1.0;5.0;2023;2025;"Ramon Santamaria";@raysan5

View File

@ -6,30 +6,30 @@
1. File naming: <module>_<description> - Lower case filename, words separated by underscore, 1. File naming: <module>_<description> - Lower case filename, words separated by underscore,
no more than 3-4 words in total to describe the example. <module> referes to the primary no more than 3-4 words in total to describe the example. <module> referes to the primary
raylib module the example is more related with (code, shapes, textures, models, shaders, raudio). raylib module the example is more related with (code, shapes, textures, models, shaders, raudio)
i.e: core_input_multitouch, shapes_lines_bezier, shaders_palette_switch i.e: core_input_multitouch, shapes_lines_bezier, shaders_palette_switch
2. Follow below template structure, example info should list the module, the short description 2. Follow below template structure, example info should list the module, the short description
and the author of the example, twitter or github info could be also provided for the author. and the author of the example, twitter or github info could be also provided for the author
Short description should also be used on the title of the window. Short description should also be used on the title of the window
3. Code should be organized by sections:[Initialization]- [Update] - [Draw] - [De-Initialization] 3. Code should be organized by sections:[Initialization]- [Update] - [Draw] - [De-Initialization]
Place your code between the dotted lines for every section, please don't mix update logic with drawing Place your code between the dotted lines for every section, please don't mix update logic with drawing
and remember to unload all loaded resources. and remember to unload all loaded resources
4. Code should follow raylib conventions: https://github.com/raysan5/raylib/wiki/raylib-coding-conventions 4. Code should follow raylib conventions: https://github.com/raysan5/raylib/wiki/raylib-coding-conventions
Try to be very organized, using line-breaks appropiately. Try to be very organized, using line-breaks appropiately
5. Add comments to the specific parts of code the example is focus on. 5. Add comments to the specific parts of code the example is focus on
Don't abuse with comments, try to be clear and impersonal on the comments. Don't abuse with comments, try to be clear and impersonal on the comments
6. Try to keep the example simple, under 300 code lines if possible. Try to avoid external dependencies. 6. Try to keep the example simple, under 300 code lines if possible. Try to avoid external dependencies
Try to avoid defining functions outside the main(). Example should be as self-contained as possible. Try to avoid defining functions outside the main(). Example should be as self-contained as possible
7. About external resources, they should be placed in a [resources] folder and those resources 7. About external resources, they should be placed in a [resources] folder and those resources
should be open and free for use and distribution. Avoid propietary content. should be open and free for use and distribution. Avoid propietary content
8. Try to keep the example simple but with a creative touch. 8. Try to keep the example simple but with a creative touch
Simple but beautiful examples are more appealing to users! Simple but beautiful examples are more appealing to users!
9. In case of additional information is required, just come to raylib Discord channel: example-contributions 9. In case of additional information is required, just come to raylib Discord channel: example-contributions
@ -37,11 +37,11 @@
10. Have fun! 10. Have fun!
The following files should be updated when adding a new example, it's planned to create some The following files should be updated when adding a new example, it's planned to create some
script to automatize this process but not available yet. script to automatize this process but not available yet
- raylib/examples/<category>/<category>_example_name.c - raylib/examples/<category>/<category>_example_name.c
- raylib/examples/<category>/<category>_example_name.png - raylib/examples/<category>/<category>_example_name.png
- raylib/examples/<category>/resources/*.* - raylib/examples/<category>/resources/..
- raylib/examples/Makefile - raylib/examples/Makefile
- raylib/examples/Makefile.Web - raylib/examples/Makefile.Web
- raylib/examples/README.md - raylib/examples/README.md
@ -56,16 +56,18 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [core] example - Basic window * raylib [<module>] example - <name/short description>
* *
* Example originally created with raylib 4.5, last time updated with raylib 4.5 * Example complexity rating: [] 1/4
* *
* Example contributed by <user_name> (@<user_github>) and reviewed by Ramon Santamaria (@raysan5) * Example originally created with raylib 5.5, last time updated with raylib 5.6
*
* Example contributed by <author_name> (@<user_github>) 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) 2023 <user_name> (@<user_github>) * Copyright (c) <year_created>-<year_updated> <author_name> (@<user_github>)
* *
********************************************************************************************/ ********************************************************************************************/
@ -81,7 +83,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window"); InitWindow(screenWidth, screenHeight, "raylib [<module>] example - <name>");
// TODO: Load resources / Initialize variables at this point // TODO: Load resources / Initialize variables at this point
@ -102,9 +104,11 @@ int main(void)
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
// TODO: Draw everything that requires to be drawn at this point: // TODO: Draw everything that requires to be drawn at this point
DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); // Example DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,6 +1,8 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [models] example - Load 3d model with animations and play them * raylib [models] example - animation playing
*
* Example complexity rating: [] 2/4
* *
* Example originally created with raylib 2.5, last time updated with raylib 3.5 * Example originally created with raylib 2.5, last time updated with raylib 3.5
* *
@ -9,13 +11,13 @@
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2019-2024 Culacant (@culacant) and Ramon Santamaria (@raysan5) * Copyright (c) 2019-2025 Culacant (@culacant) and Ramon Santamaria (@raysan5)
* *
******************************************************************************************** ********************************************************************************************
* *
* NOTE: To export a model from blender, make sure it is not posed, the vertices need to be * NOTE: To export a model from blender, make sure it is not posed, the vertices need to be
* in the same position as they would be in edit mode and the scale of your models is * in the same position as they would be in edit mode and the scale of your models is
* set to 0. Scaling can be done from the export menu. * set to 0. Scaling can be done from the export menu
* *
********************************************************************************************/ ********************************************************************************************/
@ -31,7 +33,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - model animation"); InitWindow(screenWidth, screenHeight, "raylib [models] example - animation playing");
// Define the camera to look into our 3d world // Define the camera to look into our 3d world
Camera camera = { 0 }; Camera camera = { 0 };

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1,13 +1,15 @@
/******************************************************************************************* /*******************************************************************************************
* *
* raylib [models] example - Drawing billboards * raylib [models] example - billboard rendering
*
* Example complexity rating: [] 3/4
* *
* Example originally created with raylib 1.3, last time updated with raylib 3.5 * Example originally created with raylib 1.3, last time updated with raylib 3.5
* *
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5) * Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
* *
********************************************************************************************/ ********************************************************************************************/
@ -24,7 +26,7 @@ int main(void)
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards"); InitWindow(screenWidth, screenHeight, "raylib [models] example - billboard rendering");
// Define the camera to look into our 3d world // Define the camera to look into our 3d world
Camera camera = { 0 }; Camera camera = { 0 };
@ -38,7 +40,7 @@ int main(void)
Vector3 billPositionStatic = { 0.0f, 2.0f, 0.0f }; // Position of static billboard Vector3 billPositionStatic = { 0.0f, 2.0f, 0.0f }; // Position of static billboard
Vector3 billPositionRotating = { 1.0f, 2.0f, 1.0f }; // Position of rotating billboard Vector3 billPositionRotating = { 1.0f, 2.0f, 1.0f }; // Position of rotating billboard
// Entire billboard texture, source is used to take a segment from a larger texture. // Entire billboard texture, source is used to take a segment from a larger texture
Rectangle source = { 0.0f, 0.0f, (float)bill.width, (float)bill.height }; Rectangle source = { 0.0f, 0.0f, (float)bill.width, (float)bill.height };
// NOTE: Billboard locked on axis-Y // NOTE: Billboard locked on axis-Y
@ -52,7 +54,7 @@ int main(void)
Vector2 origin = Vector2Scale(size, 0.5f); Vector2 origin = Vector2Scale(size, 0.5f);
// Distance is needed for the correct billboard draw order // Distance is needed for the correct billboard draw order
// Larger distance (further away from the camera) should be drawn prior to smaller distance. // Larger distance (further away from the camera) should be drawn prior to smaller distance
float distanceStatic; float distanceStatic;
float distanceRotating; float distanceRotating;
float rotation = 0.0f; float rotation = 0.0f;

Some files were not shown because too many files have changed in this diff Show More