mirror of
https://github.com/raysan5/raylib.git
synced 2026-04-10 01:09:10 -04:00
Compare commits
185 Commits
f583674327
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| fbcc8cdb55 | |||
| ca6f188233 | |||
| 8e54b19d9f | |||
| e24b01bb28 | |||
| 68d519910a | |||
| 53915d77e6 | |||
| b202421e08 | |||
| 05a14456ae | |||
| c5fc771622 | |||
| d3c6f426b4 | |||
| c4bd4faab5 | |||
| 4a6ceb9c76 | |||
| 6ef0044381 | |||
| 1122add3ee | |||
| 92f82b4add | |||
| cdff3d7bea | |||
| 138ef838d9 | |||
| 6ff51d3a2a | |||
| ea6292e27a | |||
| bb7b8d70e9 | |||
| f36533cbd8 | |||
| 5c2dee0862 | |||
| 12140cd444 | |||
| 3f7f040c7e | |||
| 4799cab772 | |||
| eb4f1a6da0 | |||
| 449182bb51 | |||
| 4ca9170f5b | |||
| 78797757f0 | |||
| a6dc9f9e92 | |||
| c7df641aa2 | |||
| 63beefd0de | |||
| b3bf537fab | |||
| 8743e11285 | |||
| 04f81538b7 | |||
| 8d70f1007b | |||
| 6c0134bb5c | |||
| e9231bc4f1 | |||
| 4c79c6837b | |||
| e5f0c9f8b1 | |||
| d5326fe880 | |||
| adc4c9b875 | |||
| b09da8fce8 | |||
| 0b87a35e5a | |||
| a1bf8d9c75 | |||
| d3cc78d9d7 | |||
| e3dcb144bc | |||
| da93ec4a21 | |||
| fb0f83bc91 | |||
| 29ded51ea4 | |||
| bb78e98a71 | |||
| 5915584cd6 | |||
| 8c44ea5032 | |||
| 5fad835ff1 | |||
| 4142c89baa | |||
| 990a5e0cb4 | |||
| 8a7aff509d | |||
| ba83bd33f3 | |||
| 98d6e24c44 | |||
| 51f4741912 | |||
| d7bd56ef1b | |||
| a693365bf2 | |||
| bd3a35ca21 | |||
| 0f0983c065 | |||
| 5dd4036ed0 | |||
| cb05ef7f03 | |||
| 52d2158f49 | |||
| 0f1e14a600 | |||
| 6cf71f565c | |||
| e71633a0be | |||
| ca1baca7c2 | |||
| 7e8aca00b6 | |||
| c1dbfc87f3 | |||
| 644e4adbe2 | |||
| 1e74aba7c3 | |||
| 83e35ba170 | |||
| 22cc2554b1 | |||
| 1b084ff9f2 | |||
| 8a685877eb | |||
| 8783e66e21 | |||
| 7ae46fb2e6 | |||
| 04c5dc4493 | |||
| bca4f83a02 | |||
| 7fef65a3fe | |||
| da9e881092 | |||
| 2a3b28b67a | |||
| 2fd058c1e4 | |||
| 528caf8b9d | |||
| 85df4e7de5 | |||
| f23319db3c | |||
| 29e4b77580 | |||
| 2c39703d13 | |||
| d657e86043 | |||
| 0de2e8092b | |||
| 48a34d63ed | |||
| fbce5e7541 | |||
| 18756bb79d | |||
| 6ddf9a1885 | |||
| e7d999e3c7 | |||
| 93be463322 | |||
| 5cd7202777 | |||
| 22e1e86c52 | |||
| 1eea511070 | |||
| e0d3037e15 | |||
| 483d687900 | |||
| 7401214e92 | |||
| d2be4ac2c9 | |||
| 19ec2588be | |||
| e2aed43410 | |||
| 4a16dc9b09 | |||
| ceeaf57a8b | |||
| dfc3f58a06 | |||
| 26f329a5e7 | |||
| 1d9e24eb58 | |||
| 29280971be | |||
| fd017c0b2d | |||
| fbec6b0593 | |||
| 8395374e3d | |||
| 116191fd80 | |||
| a6d5a7ffbc | |||
| f89d38b086 | |||
| 38ed50c07b | |||
| 4b9d802d4e | |||
| 70cb8d15e0 | |||
| 7763da41d7 | |||
| 6ba6df3af3 | |||
| 7b9a2a4145 | |||
| f83590aa37 | |||
| c5712db1e0 | |||
| f9ea607385 | |||
| 8a93587eaa | |||
| 64e8bfcfb6 | |||
| 4e360c97f4 | |||
| ee4f4a29c2 | |||
| 6cebf63cba | |||
| 7b1096dc53 | |||
| e40ddfabbb | |||
| 2b207be11e | |||
| d604cd7f65 | |||
| 78023ffca5 | |||
| 32005b9edf | |||
| 99cab6d3a7 | |||
| 1839b3edb0 | |||
| eed30b6f90 | |||
| a0ffefcb9d | |||
| 12039ba7d0 | |||
| c8d1f3e750 | |||
| 54f630774d | |||
| 3e926d65a0 | |||
| f9ee714c76 | |||
| ea00b97c59 | |||
| 02b592cd7b | |||
| 84dc56ba89 | |||
| d6926eb46a | |||
| eb1e85e400 | |||
| 2eaac95df0 | |||
| de720a8d4c | |||
| 28288fafb1 | |||
| 71677765c5 | |||
| e1959a4e5c | |||
| faf42366ec | |||
| 23c06bc6f1 | |||
| 5ada84cc6d | |||
| d0f899721b | |||
| 23f86689dc | |||
| 1cf278b8b4 | |||
| 1d85071372 | |||
| b4746469d4 | |||
| 70a1a57a12 | |||
| 37a852a7ae | |||
| b68dbaa8af | |||
| 9ae34d2c4b | |||
| 8e705b19e4 | |||
| bf830c3f7b | |||
| 23c8ee855d | |||
| 416da9aca6 | |||
| 936e8ae0db | |||
| ea92677902 | |||
| 3bea7f518d | |||
| e1113c8833 | |||
| 2c5e7f8db6 | |||
| 8596c940ae | |||
| 0b9239eca2 | |||
| 70a58a6ec6 | |||
| 950c064448 |
18
.github/workflows/build_android.yml
vendored
18
.github/workflows/build_android.yml
vendored
@ -28,20 +28,20 @@ jobs:
|
||||
max-parallel: 1
|
||||
matrix:
|
||||
ARCH: ["arm64", "x86_64"]
|
||||
|
||||
|
||||
env:
|
||||
RELEASE_NAME: raylib-dev_android_api29_${{ matrix.ARCH }}
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
|
||||
- name: Setup Release Version
|
||||
run: |
|
||||
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_android_api29_${{ matrix.ARCH }}" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
|
||||
|
||||
- name: Setup Android NDK
|
||||
id: setup-ndk
|
||||
uses: nttld/setup-ndk@v1
|
||||
@ -52,7 +52,7 @@ jobs:
|
||||
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
mkdir ${{ env.RELEASE_NAME }}
|
||||
@ -60,7 +60,7 @@ jobs:
|
||||
mkdir include
|
||||
mkdir lib
|
||||
cd ../..
|
||||
|
||||
|
||||
# Generating static + shared library for 64bit arquitectures and API version 29
|
||||
- name: Build Library
|
||||
run: |
|
||||
@ -69,7 +69,7 @@ jobs:
|
||||
make PLATFORM=PLATFORM_ANDROID ANDROID_ARCH=${{ matrix.ARCH }} ANDROID_API_VERSION=29 ANDROID_NDK=${{ env.ANDROID_NDK_HOME }} RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
|
||||
cd ..
|
||||
shell: cmd
|
||||
|
||||
|
||||
- name: Generate Artifacts
|
||||
run: |
|
||||
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
||||
@ -80,7 +80,7 @@ jobs:
|
||||
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
||||
cd build
|
||||
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
||||
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@ -88,7 +88,7 @@ jobs:
|
||||
path: |
|
||||
./build/${{ env.RELEASE_NAME }}
|
||||
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||
|
||||
|
||||
- name: Upload Artifact to Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
|
||||
8
.github/workflows/build_examples_linux.yml
vendored
8
.github/workflows/build_examples_linux.yml
vendored
@ -23,18 +23,18 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
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
|
||||
|
||||
|
||||
- name: Build Library
|
||||
run: |
|
||||
cd src
|
||||
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC
|
||||
cd ..
|
||||
|
||||
|
||||
- name: Build Examples
|
||||
run: |
|
||||
cd examples
|
||||
|
||||
2
.github/workflows/build_examples_windows.yml
vendored
2
.github/workflows/build_examples_windows.yml
vendored
@ -13,7 +13,7 @@ on:
|
||||
- 'src/**'
|
||||
- 'examples/**'
|
||||
- '.github/workflows/windows_examples.yml'
|
||||
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
||||
20
.github/workflows/build_linux.yml
vendored
20
.github/workflows/build_linux.yml
vendored
@ -42,23 +42,23 @@ jobs:
|
||||
ARCH_NAME: "arm64"
|
||||
COMPILER_PATH: "/usr/bin"
|
||||
runner: "ubuntu-24.04-arm"
|
||||
|
||||
|
||||
runs-on: ${{ matrix.runner }}
|
||||
env:
|
||||
RELEASE_NAME: raylib-dev_linux_${{ matrix.ARCH_NAME }}
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@master
|
||||
|
||||
|
||||
- name: Setup Release Version
|
||||
run: |
|
||||
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_linux_${{ matrix.ARCH_NAME }}" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
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
|
||||
@ -74,7 +74,7 @@ jobs:
|
||||
run : |
|
||||
sudo apt-get install gcc-multilib
|
||||
if: matrix.bits == 32 && matrix.ARCH == 'i386'
|
||||
|
||||
|
||||
# TODO: Support 32bit (i386) static/shared library building
|
||||
- name: Build Library (32-bit)
|
||||
run: |
|
||||
@ -91,7 +91,7 @@ jobs:
|
||||
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 == 'x86_64'
|
||||
|
||||
|
||||
- name: Build Library (64-bit ARM)
|
||||
run: |
|
||||
cd src
|
||||
@ -99,7 +99,7 @@ jobs:
|
||||
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
|
||||
run: |
|
||||
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
||||
@ -110,7 +110,7 @@ jobs:
|
||||
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
||||
cd build
|
||||
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
||||
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@ -118,7 +118,7 @@ jobs:
|
||||
path: |
|
||||
./build/${{ env.RELEASE_NAME }}
|
||||
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||
|
||||
|
||||
- name: Upload Artifact to Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
|
||||
30
.github/workflows/build_macos.yml
vendored
30
.github/workflows/build_macos.yml
vendored
@ -23,14 +23,14 @@ jobs:
|
||||
permissions:
|
||||
contents: write # for actions/upload-release-asset to upload release asset
|
||||
runs-on: macos-latest
|
||||
|
||||
|
||||
env:
|
||||
RELEASE_NAME: raylib-dev_macos
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
|
||||
- name: Setup Release Version
|
||||
run: |
|
||||
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_macos" >> $GITHUB_ENV
|
||||
@ -38,7 +38,7 @@ jobs:
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
mkdir ${{ env.RELEASE_NAME }}
|
||||
@ -46,47 +46,47 @@ jobs:
|
||||
mkdir include
|
||||
mkdir lib
|
||||
cd ../..
|
||||
|
||||
|
||||
# Generating static + shared library, note that i386 architecture is deprecated
|
||||
# Defining GL_SILENCE_DEPRECATION because OpenGL is deprecated on macOS
|
||||
- name: Build Library
|
||||
run: |
|
||||
cd src
|
||||
clang --version
|
||||
|
||||
|
||||
# Extract version numbers from Makefile
|
||||
brew install grep
|
||||
RAYLIB_API_VERSION=`ggrep -Po 'RAYLIB_API_VERSION\s*=\s\K(.*)' Makefile`
|
||||
RAYLIB_VERSION=`ggrep -Po 'RAYLIB_VERSION\s*=\s\K(.*)' Makefile`
|
||||
|
||||
|
||||
# Build raylib x86_64 static
|
||||
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=STATIC CUSTOM_CFLAGS="-target x86_64-apple-macos10.12 -DGL_SILENCE_DEPRECATION"
|
||||
mv libraylib.a /tmp/libraylib_x86_64.a
|
||||
make clean
|
||||
|
||||
|
||||
# Build raylib arm64 static
|
||||
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=STATIC CUSTOM_CFLAGS="-target arm64-apple-macos11 -DGL_SILENCE_DEPRECATION" -B
|
||||
mv libraylib.a /tmp/libraylib_arm64.a
|
||||
make clean
|
||||
|
||||
|
||||
# Join x86_64 and arm64 static
|
||||
lipo -create -output ../build/${{ env.RELEASE_NAME }}/lib/libraylib.a /tmp/libraylib_x86_64.a /tmp/libraylib_arm64.a
|
||||
|
||||
|
||||
# Build raylib x86_64 dynamic
|
||||
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=SHARED CUSTOM_CFLAGS="-target x86_64-apple-macos10.12 -DGL_SILENCE_DEPRECATION" CUSTOM_LDFLAGS="-target x86_64-apple-macos10.12" -B
|
||||
mv libraylib.${RAYLIB_VERSION}.dylib /tmp/libraylib_x86_64.${RAYLIB_VERSION}.dylib
|
||||
make clean
|
||||
|
||||
|
||||
# Build raylib arm64 dynamic
|
||||
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=SHARED CUSTOM_CFLAGS="-target arm64-apple-macos11 -DGL_SILENCE_DEPRECATION" CUSTOM_LDFLAGS="-target arm64-apple-macos11" -B
|
||||
mv libraylib.${RAYLIB_VERSION}.dylib /tmp/libraylib_arm64.${RAYLIB_VERSION}.dylib
|
||||
|
||||
|
||||
# Join x86_64 and arm64 dynamic
|
||||
lipo -create -output ../build/${{ env.RELEASE_NAME }}/lib/libraylib.${RAYLIB_VERSION}.dylib /tmp/libraylib_x86_64.${RAYLIB_VERSION}.dylib /tmp/libraylib_arm64.${RAYLIB_VERSION}.dylib
|
||||
ln -sv libraylib.${RAYLIB_VERSION}.dylib ../build/${{ env.RELEASE_NAME }}/lib/libraylib.dylib
|
||||
ln -sv libraylib.${RAYLIB_VERSION}.dylib ../build/${{ env.RELEASE_NAME }}/lib/libraylib.${RAYLIB_API_VERSION}.dylib
|
||||
cd ..
|
||||
|
||||
|
||||
- name: Generate Artifacts
|
||||
run: |
|
||||
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
||||
@ -97,7 +97,7 @@ jobs:
|
||||
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
||||
cd build
|
||||
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
||||
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@ -105,7 +105,7 @@ jobs:
|
||||
path: |
|
||||
./build/${{ env.RELEASE_NAME }}
|
||||
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||
|
||||
|
||||
- name: Upload Artifact to Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
|
||||
20
.github/workflows/build_webassembly.yml
vendored
20
.github/workflows/build_webassembly.yml
vendored
@ -18,20 +18,20 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
|
||||
env:
|
||||
RELEASE_NAME: raylib-dev_webassembly
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
|
||||
- name: Setup emsdk
|
||||
uses: mymindstorm/setup-emsdk@v14
|
||||
with:
|
||||
version: 3.1.71
|
||||
version: 5.0.3
|
||||
actions-cache-folder: 'emsdk-cache'
|
||||
|
||||
|
||||
- name: Setup Release Version
|
||||
run: |
|
||||
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_webassembly" >> $GITHUB_ENV
|
||||
@ -39,7 +39,7 @@ jobs:
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
|
||||
- name: Setup Environment
|
||||
run: |
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
mkdir ${{ env.RELEASE_NAME }}
|
||||
@ -47,14 +47,14 @@ jobs:
|
||||
mkdir include
|
||||
mkdir lib
|
||||
cd ../..
|
||||
|
||||
|
||||
- name: Build Library
|
||||
run: |
|
||||
cd src
|
||||
emcc -v
|
||||
make PLATFORM=PLATFORM_WEB EMSDK_PATH="D:/a/raylib/raylib/emsdk-cache/emsdk-main" RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
|
||||
cd ..
|
||||
|
||||
|
||||
- name: Generate Artifacts
|
||||
run: |
|
||||
copy /Y .\src\raylib.h .\build\${{ env.RELEASE_NAME }}\include\raylib.h
|
||||
@ -67,7 +67,7 @@ jobs:
|
||||
7z a ./${{ env.RELEASE_NAME }}.zip ./${{ env.RELEASE_NAME }}
|
||||
dir
|
||||
shell: cmd
|
||||
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@ -75,7 +75,7 @@ jobs:
|
||||
path: |
|
||||
./build/${{ env.RELEASE_NAME }}
|
||||
!./build/${{ env.RELEASE_NAME }}.zip
|
||||
|
||||
|
||||
- name: Upload Artifact to Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
|
||||
4
.github/workflows/update_examples.yml
vendored
4
.github/workflows/update_examples.yml
vendored
@ -12,11 +12,11 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Setup emsdk
|
||||
uses: mymindstorm/setup-emsdk@v14
|
||||
with:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -118,6 +118,7 @@ GTAGS
|
||||
# Zig programming language
|
||||
.zig-cache/
|
||||
zig-cache/
|
||||
zig-pkg/
|
||||
zig-out/
|
||||
build/
|
||||
build-*/
|
||||
|
||||
@ -32,7 +32,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||
| [DenoRaylib550](https://github.com/JJLDonley/DenoRaylib550) | **5.5** | [Deno](https://deno.land) | MIT |
|
||||
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |
|
||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 5.5 | [Factor](https://factorcode.org) | BSD |
|
||||
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
||||
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
||||
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
|
||||
@ -59,7 +59,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib |
|
||||
| [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 |
|
||||
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | BSD-3Clause |
|
||||
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | Zlib |
|
||||
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
|
||||
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **5.0** | [OCaml](https://ocaml.org) | MIT |
|
||||
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
||||
|
||||
102
HISTORY.md
102
HISTORY.md
@ -419,7 +419,7 @@ Highlights for `raylib 4.5`:
|
||||
|
||||
- **`NEW` Support QOA audio format (import/export)**: Just a couple of months ago the new [QOA file format](https://qoaformat.org/) was published, a very simple, portable and open source quite-ok-audio file format. raylib already supports it, added to `raudio` module and including audio loading from file, loading from memory, streaming from file, streaming from memory and **exporting to QOA** audio format. **Because simplicity really matters to raylib!**
|
||||
|
||||
- **`NEW` Module for compressed textures loading**: [`rl_gputex`](https://github.com/raysan5/raylib/blob/master/src/external/rl_gputex.h), a portable single-file header-only small library to load compressed texture file-formats (DDS, PKM, KTX, PVR, ASTC). Provided functionality is not new to raylib but it was part of the raylib `rtextures` module, now it has been moved into a separate self-contained library, **improving portability**. Note that this module is only intended to **load compressed data from files, ready to be uploaded to GPU**, no compression/decompression functionality is provided. This change is a first step towards a better modularization of raylib library.
|
||||
- **`NEW` Module for compressed textures loading**: [`rl_gputex`](https://github.com/raysan5/raylib/blob/master/src/external/rltexgpu.h), a portable single-file header-only small library to load compressed texture file-formats (DDS, PKM, KTX, PVR, ASTC). Provided functionality is not new to raylib but it was part of the raylib `rtextures` module, now it has been moved into a separate self-contained library, **improving portability**. Note that this module is only intended to **load compressed data from files, ready to be uploaded to GPU**, no compression/decompression functionality is provided. This change is a first step towards a better modularization of raylib library.
|
||||
|
||||
- **Reviewed `rlgl` module for automatic limits checking**: Again, [`rlgl`](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been reviewed to simplify usage. Now users do not need to worry about reaching the internal render-batch limits when they send their triangles to draw 2d/3d, `rlgl` manages it automatically! This change allows a **great simplification for other modules** like `rshapes`, `rtextures` and `rmodels` that do not need to worry about bufffer overflows and can just define as many vertex as desired!
|
||||
|
||||
@ -449,13 +449,13 @@ Some numbers for this release:
|
||||
Highlights for `raylib 5.0`:
|
||||
|
||||
- **`rcore` module platform-split**: Probably the biggest raylib redesign in the last 10 years. raylib started as a library targeting 3 desktop platforms: `Windows`, `Linux` and `macOS` (thanks to `GLFW` underlying library) but with the years support for several new platforms has been added (`Android`, `Web`, `Rapsberry Pi`, `RPI native`...); lot of the platform code was shared so the logic was all together on `rcore.c` module, separated by compilation flags. This approach was very handy but also made it very difficult to support new platforms and specially painful for contributors not familiar with the module, navigating +8000 lines of code in a single file. A big redesign was really needed but the amount of work required was humungous and quite scary for a solo-developer like me, moreover considering that everything was working and the chances to break things were really high. Fortunately, some contributors were ready for the task (@ubkp, @michaelfiber, @Bigfoot71) and thanks to their initiative and super-hard work, the `rcore` [platform split](https://github.com/raysan5/raylib/blob/master/src/platforms) has been possible! This new raylib architecture greatly improves the platforms maintenance but also greatly simplifies the addition of new platforms. A [`platforms/rcore_template.c`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_template.c) file is provided with the required structure and functions to be filled for the addition of new platforms, actually it has been simplified to mostly filling some pre-defined functions: `InitPlatform()`, `ClosePlatform`, `PollInputEvents`... Undoubtedly, **this redesign opens the doors to a new era for raylib**, letting the users to plug new platforms as desired.
|
||||
|
||||
|
||||
- **`NEW` Platform backend supported: SDL**: Thanks to the new `rcore` platform-split, the addition of new platforms/backends to raylib has been greatly simplified. As a proof of concept, [`SDL2`](https://libsdl.org/) platform backend has been added to raylib as an alternative for `GLFW` library for desktop builds: [`platforms/rcore_desktop_sdl`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_sdl.c). Lot of work has been put to provide exactly the same features as the other platforms and carefully test the new implementation. Now `SDL2` fans can use this new backend, just providing the required include libraries on compilation and linkage (not included in raylib, like `GLFW`). `SDL` backend support also **eases the process of supporting a wider range of platforms** that already support `SDL`.
|
||||
|
||||
- **`NEW` Platform backend supported: Nintendo Switch (closed source)**: The addition of the `SDL` backend was quite a challenge but to really verify the robustness and ease of the new platform plugin system, adding support for a console was a more demanding adventure. Surprisingly, only two days of work were required to add support for `Nintendo Switch` to raylib! Implementation result showed an outstanding level of simplicity, with a **self-contained module** (`rcore_swith.cpp`) supporting graphics and inputs. Unfortunately this module can not be open-sourced due to licensing restrictions.
|
||||
|
||||
- **`NEW` Splines drawing and evaluation API**: A complete set of functions has been added to [draw](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1258) and [evaluate](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1270) different types of splines: `Linear`, `Basis`, `Catmull-Rom`, `Quadratic Bezier` and `Cubic Bezier`. Splines are extremely useful for game development (describe paths, control NPC movement...) but they can also be very useful on tools development (node-conections, elements-movement, 3d modelling, animations...). This was the missing feature on the raylib [`rshapes`](https://github.com/raysan5/raylib/blob/master/src/rshapes.h) module to make it complete! Note that `rshapes` module can also be used independently of raylib just providing the **only 6 functions required for vertex definition and drawing**.
|
||||
|
||||
|
||||
- **`NEW` Pseudo-random numbers generator: rprand**: After several years of users asking for this missing piece, a brand new pseudo-random generator module has been added to raylib. [`rprand`](https://github.com/raysan5/raylib/blob/master/src/external/rprand.h) implements the `Xoshiro128**` algorithm combined with `SplitMix64`, specially suited for **fast software pseudo-random numbers generation**. The module also implies some useful functions to generate non-repetitive random numbers sequences, functionality exposed by raylib. usage of this module can be controlled by a compilation flag, in case the default libc `rand()` function was preferred.
|
||||
|
||||
- **`NEW` Automation Events System API**: This new system was first added in `raylib 4.0` as an experimental feature but it was a bit clumsy and there was no API exposed to users. For the new `raylib 5.0` the system has been redesigned and [proper API](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1135) added for the users. With this new events automation system, users can **record input events for later replay**, very useful feature for testing automation, tutorials generation, assisted game playing, in-game cinematics, speedruns saving or even AI assited game playing!
|
||||
@ -464,8 +464,8 @@ Highlights for `raylib 5.0`:
|
||||
|
||||
- **`NEW` raylib web examples functionality**: Beside the addition of several new examples, the web examples functionality has been improved. Examples have been organized by [complexity level](https://www.raylib.com/examples.html), marked with one star for simple examples and up to 4 stars for more complex ones. A new option has been added to web to allow to **filter examples by function-name** usage, to ease the learning process when looking for an usage example of some function. Finally, **open-graph metadata** information has been added to all examples individual webpages, improving a the visuals and information when sharing those webpages on social networks, sharing the example screenshot and details.
|
||||
|
||||
As always, those are only some highlights of the new `raylib 5.0` but there is many more improvements! Support for 16-bit HDR images/textures, SVG loading and scaling support, new OpenGL ES 3.0 graphic backend, new image gradient generators, sound alias loading, improved 3d models loading, multiple optimizations, new bindings, CodeQL integration and much more!
|
||||
|
||||
As always, those are only some highlights of the new `raylib 5.0` but there is many more improvements! Support for 16-bit HDR images/textures, SVG loading and scaling support, new OpenGL ES 3.0 graphic backend, new image gradient generators, sound alias loading, improved 3d models loading, multiple optimizations, new bindings, CodeQL integration and much more!
|
||||
|
||||
Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes!
|
||||
|
||||
Undoubtedly, this is the **biggest raylib update in 10 years**. Many new features and improvements with a special focus on maintainability and long-term sustainability. **Undoubtedly, this is the raylib of the future**.
|
||||
@ -492,16 +492,16 @@ Highlights for `raylib 5.5`:
|
||||
- **`NEW` raylib project creator tool**: A brand new tool developed to help raylib users to **setup new projects in a professional way**. `raylib project creator` generates a complete project structure with **multiple build systems ready-to-use** and **GitHub CI/CD actions pre-configured**. It only requires providing some C files and basic project parameters! The tools is [free and open-source](https://raysan5.itch.io/raylib-project-creator), and [it can be used online](https://raysan5.itch.io/raylib-project-creator)!.
|
||||
|
||||
- **`NEW` Platform backend supported: RGFW**: Thanks to the `rcore` platform-split implemented in `raylib 5.0`, **adding new platforms backends has been greatly simplified**, new backends can be added using provided template, self-contained in a single C module, completely portable. A new platform backend has been added: [`RGFW`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_rgfw.c). `RGFW` is a **new single-file header-only portable library** ([`RGFW.h`](https://github.com/ColleagueRiley/RGFW)) intended for platform-functionality management (windowing and inputs); in this case for **desktop platforms** (Windows, Linux, macOS) but also for **Web platform**. It adds a new alternative to the already existing `GLFW` and `SDL` platform backends.
|
||||
|
||||
|
||||
- **`NEW` Platform backend version supported: SDL3**: Previous `raylib 5.0` added support for `SDL2` library, and `raylib 5.5` not only improves SDL2 functionality, with several issues reviewed, but also adds support for the recently released big SDL update in years: [`SDL3`](https://wiki.libsdl.org/SDL3/FrontPage). Now users can **select at compile time the desired SDL version to use**, increasing the number of potential platforms supported in the future!
|
||||
|
||||
|
||||
- **`NEW` Retro-console platforms supported: Dreamcast, N64, PSP, PSVita, PS4**: Thanks to the platform-split on `raylib 5.0`, **supporting new platform backends is easier than ever!** Along the raylib `rlgl` module support for the `OpenGL 1.1` graphics API, it opened the door to [**multiple homebrew retro-consoles backend implementations!**](https://github.com/raylib4Consoles) It's amazing to see raylib running on +20 year old consoles like [Dreamcast](https://github.com/raylib4Consoles/raylib4Dreamcast), [PSP](https://github.com/raylib4Consoles/raylib4Psp) or [PSVita](https://github.com/psp2dev/raylib4Vita), considering the hardware constraints of those platforms and proves **raylib outstanding versability!** Those additional platforms can be found in separate repositories and have been created by the amazing programmer Antonio Jose Ramos Marquez (@psxdev).
|
||||
|
||||
|
||||
- **`NEW` GPU Skinning support**: After lots of requests for this feature, it has been finally added to raylib thanks to the contributor Daniel Holden (@orangeduck), probably the developer that has further pushed models animations with raylib, developing two amazing tools to visualize and test animations: [GenoView](https://github.com/orangeduck/GenoView) and [BVHView](https://github.com/orangeduck/BVHView). Adding GPU skinning was a tricky feature, considering it had to be **available for all raylib supported platforms**, including limited ones like Raspberry Pi with OpenGL ES 2.0, where some advance OpenGL features are not available (UBO, SSBO, Transform Feedback) but a multi-platform solution was found to make it possible. A new example, [`models_gpu_skinning`](https://github.com/raysan5/raylib/blob/master/examples/models/models_gpu_skinning.c) has been added to illustrate this new functionality. As an extra, previous existing CPU animation system has been greatly improved, multiplying performance by a factor (simplifiying required maths).
|
||||
|
||||
|
||||
- **`NEW` [`raymath`](https://github.com/raysan5/raylib/blob/master/src/raymath.h) C++ operators**: After several requested for this feature, C++ math operators for `Vector2`, `Vector3`, `Vector4`, `Quaternion` and `Matrix` has been added to `raymath` as an extension to current implementation. Despite being only available for C++ because C does not support it, these operators **simplify C++ code when doing math operations**.
|
||||
|
||||
Beside those new big features, `raylib 5.5` comes with MANY other improvements:
|
||||
Beside those new big features, `raylib 5.5` comes with MANY other improvements:
|
||||
|
||||
- Normals support on batching system
|
||||
- Clipboard images reading support
|
||||
@ -512,7 +512,7 @@ Beside those new big features, `raylib 5.5` comes with MANY other improvements:
|
||||
- Improved GLTF animations loading
|
||||
|
||||
...and [much much more](https://github.com/raysan5/raylib/blob/master/CHANGELOG), including **many functions reviews and new functions added!**
|
||||
|
||||
|
||||
Make sure to check raylib [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) for a detailed list of changes!
|
||||
|
||||
To end with, I want to **thank all the contributors (+640!**) that along the years have **greatly improved raylib** and pushed it further and better day after day. Thanks to all of them, raylib is the amazing library it is today.
|
||||
@ -522,3 +522,83 @@ Last but not least, I want to thank **raylib sponsors and all the raylib communi
|
||||
**After 11 years of development, `raylib 5.5` is the best raylib ever.**
|
||||
|
||||
**Enjoy programming with raylib!** :)
|
||||
|
||||
notes on raylib 6.0
|
||||
-------------------
|
||||
|
||||
A new `raylib` release is finally ready and, again, this is the **biggest `raylib` release ever**! Thanks to the support of many amazing contributors this release comes packed with many new features and improvements, also thanks to the financial support of [NLnet](https://nlnet.nl/) and the [NGI Zero Commond Fund](https://nlnet.nl/NGI0/) that allow me to work on this project mostly fulltime for the past few months.
|
||||
|
||||
Some astonishing numbers for this release:
|
||||
|
||||
- **+320** closed issues (for a TOTAL of **+2140**!)
|
||||
- **+1950** commits since previous RELEASE (for a TOTAL of **+9700**!)
|
||||
- **+20** new functions ADDED to raylib API (for a TOTAL of **600**!)
|
||||
- **+50** new examples to learn from (for a TOTAL of **+210**!)
|
||||
- **+210** new contributors (for a TOTAL of **+850**!)
|
||||
|
||||
Highlights for `raylib 6.0`:
|
||||
|
||||
- **`NEW` Software Renderer - [`rlsw`](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h)**: The biggest addition of this new release. A new software renderer backend, that allows raylib to run purely on CPU, with no neeed for a GPU. It finally closes the circle of my search for a portable self-contained, with **no-external-dependencies**, graphics library, able to run on any device providing some CPU-power and some RAM memory. It has been possible thanks to the amazing work of **Le Juez Victor** ([@Bigfoot71](https://github.com/Bigfoot71)), who created [`rlsw`](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h), a single-file header-only library implementing OpenGL 1.1+ specification, tailored to fit into raylib [`rlgl`](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) OpenGL wrapper, and allowing to run raylib seamlessly over CPU with **no code changes required on user side**. As expected, software rendering is slower than hardware-accelerated rendering but it is still fast enough to run basic application at 30-60 fps. Actually, it already proved it usefulness on a new [raylib port for ESP32](https://components.espressif.com/components/georgik/raylib/versions/6.0.0/readme) microcontroller by Espressif, useful for industrial applications, and opens the door to the upcoming RISC-V powered devices that start arriving to the marked, and many times come with no GPU. Along the new software renderer, some of the existing platform backends have been adapted to support it (SDL, RGFW, DRM) and also **new platforms backends have been created** to accomodate it (Win32, Emscripten), incluing a new `PLATFORM_MEMORY`, that allows direct rendering to a memory framebuffer.
|
||||
|
||||
- **`NEW` Platform backend: Memory - [`rcore_memory`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_memory.c)**: This new platform has been added along the **software renderer** backend, allowing 2d and 3d rendering over a **platform-agnostic memory framebuffer**, it can run headless and output frames can be directly exported to images. This new backend could also be useful for graphics rendering on servers or process images directly using the memory buffer.
|
||||
|
||||
- **`NEW` Platform backend: Win32 - [`rcore_desktop_win32`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_win32.c)**: A new **Windows platform backend** and the first step towards a potential replacement/alternative to the platform libraries currently used by raylib (GLFW/SDL/RGFW). This backend follows same API template structure than the other raylib backends, but directly implementing Win32 API calls. It allows initializing OpenGL GPU-accelerated windows and also GDI based windows, useful for the software renderer backend. This new backend approach, following a common template-structure and separating the platform logic by specific OS/Windowing system, will simplify code, improve maintenance, readability and portability for raylib, setting some bases for the future. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
|
||||
|
||||
- **`NEW` Platform backend: Emscripten - [`rcore_web_emscripten`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_web_emscripten.c)**: In the same line as Win32 backend, this new web backend moves away from `libglfw.js` and **directly implements Emscripten/JS functionality**, with **no other dependencies**, adding support for the new software renderer to draw directly on a **non-accelerated 2d canvas** but also supporting a WebGL-hardware-accelerated canvas when required. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
|
||||
|
||||
- **`REDESIGNED` Fullscreen modes and High-DPI content scaling**: After many years and many related issues, the full-screen and high-dpi content scaling support has been **completely redesigned** from scratch. New design prioritizes **borderless fullscreen modes** and automatically detects current monitor content scaling configuration to scale window and framebuffer accordingly when required. Still, High-DPI support must be requested by user if desired enabling `FLAG_WINDOW_HIGHDPI` on window creation. This new system has been carefully tested on Windows, Linux (X11, Wayland), macOS with multiple monitors and multiple resolutions, including 4K monitors.
|
||||
|
||||
- **`REDESIGNED` Skeletal Animation System**: A new animation system for 3d models has been created to support animation blending, between single frames but also between differents frames on different animations, to allow easy **timed transitions** between animations. This redesign implied reviewing several raylib structures to better accomodate animation data: `Model`, `ModelSkeleton`, `ModelAnimation`, but the API was simplified and support for GPU-skinning was improved with multiple optimizations.
|
||||
|
||||
- **`REDESIGNED` Build Config System - [`config.h`](https://github.com/raysan5/raylib/blob/master/src/config.h)**: raylib allows lot of customization for specific needs (i.e. disabling modules not needed for specific applications like rmodels or raudio) but previous implementation did not allow easely disabling some features from **custom build systems**. New design not only allows disabling features with simple `-DSUPPORT_FILEFORMAT_OBJ=0` on building command-line but also the full system has been reviewed, removing useless flags and exposing new ones.
|
||||
|
||||
- **`NEW` File System API**: Along the years, multiple filesystem functions have been added to raylib API as required but it felt somewhat inconsistent with some pieces missing. In this new release, the full filesystem API has beeen reviewed and reorganized, compiling all the functionality single module: [rcore](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1126), consequently `utils` module has been removed and build system has been simplified even more; **only 6-7 modules (.c) need to be compiled containing the full raylib library**. This new filesystem API will allow raylib to be used on the creation of custom build systems, as already demostrated with the new `rexm` tool for examples management. At the moment raylib includes **+40 file system management functions**, here a list with the new functions added:
|
||||
```c
|
||||
int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists)
|
||||
int FileRemove(const char *fileName); // Remove file (if exists)
|
||||
int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist
|
||||
int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist
|
||||
int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file
|
||||
int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file
|
||||
```
|
||||
|
||||
- **`NEW` Text Management API**: Along with the new file system functionality, a new set of text management functions has been added, also very useful for text procesing and also used in custom build systems creation using raylib. At the moment raylib includes **+30 text management functions**, here a list with the new functions added:
|
||||
```c
|
||||
char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
|
||||
void UnloadTextLines(char **text, int lineCount); // Unload text lines
|
||||
const char *TextRemoveSpaces(const char *text); // Remove text spaces, concat words
|
||||
char *GetTextBetween(const char *text, const char *begin, const char *end); // Get text between two strings
|
||||
char *TextReplace(const char *text, const char *search, const char *replacement); // Replace text string with new string
|
||||
char *TextReplaceAlloc(const char *text, const char *search, const char *replacement); // Replace text string with new string, memory must be MemFree()
|
||||
char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings
|
||||
char *TextReplaceBetweenAlloc(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings, memory must be MemFree()
|
||||
char *TextInsertAlloc(const char *text, const char *insert, int position); // Insert text in a defined byte position, memory must be MemFree()
|
||||
```
|
||||
|
||||
- **`NEW` tool: raylib examples manager - [rexm](https://github.com/raysan5/raylib/tree/master/tools/rexm)**: raylib examples collection is huge, with **more than 200 examples** it was quite difficult to manage: adding, removing, renaming examples was a very costly process involving many files to be modified (including build systems), also the examples did not follow a common header convention neither a structure conventions. For that reason, a new support tool has been created: **rexm**, a raylib examples manager that allows to easely add/remove/rename examples, automatically fix inconsistencies and even **building and automated testing** on multiple platforms.
|
||||
```
|
||||
USAGE:
|
||||
> rexm <command> <example_name> [<example_rename>]
|
||||
|
||||
COMMANDS:
|
||||
create <new_example_name> : Creates an empty example, from internal template
|
||||
add <example_name> : Add existing example to collection
|
||||
rename <old_examples_name> <new_example_name> : Rename an existing example
|
||||
remove <example_name> : Remove an existing example from collection
|
||||
build <example_name> : Build example for Desktop and Web platforms
|
||||
test <example_name> : Build and Test example for Desktop and Web platforms
|
||||
validate : Validate examples collection, generates report
|
||||
update : Validate and update examples collection, generates report
|
||||
```
|
||||
|
||||
- **`NEW` +50 new examples**: Thanks to `rexm` and the simplification on examples management, this new raylib release includes +50 new examples to leearn from, most of them contributed by community.
|
||||
|
||||
Make sure to check raylib [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) for a detailed list of changes!
|
||||
|
||||
I want to **thank all the contributors (+850!**) that along the years have **greatly improved raylib** and pushed it further and better day after day. And **many thanks to raylib community and all raylib users** for supporting the library along those many years.
|
||||
|
||||
Finally, I want to thank [puffer.ai](https://puffer.ai/) and [comma.ai](https://comma.ai/) for **supporting and sponsoring the project** as platinum sponsors, along many others individuals that have been sponsoring raylib along the years. Thanks to all of you for allowing me to keep working on this library!
|
||||
|
||||
**After +12 years of development, `raylib 6.0` is today one of the bests libraries to enjoy games/tools/graphic programming!**
|
||||
|
||||
**Enjoy graphics programming with raylib!** :)
|
||||
|
||||
@ -40,9 +40,10 @@ features
|
||||
- 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**
|
||||
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
|
||||
- **Software Renderer** backend (no OpenGL required!): [rlsw](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h)
|
||||
- Multiple **Fonts** formats supported (TTF, OTF, FNT, BDF, sprite fonts)
|
||||
- Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC)
|
||||
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
|
||||
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
|
||||
- Flexible Materials system, supporting classic maps and **PBR maps**
|
||||
- **Animated 3D models** supported (skeletal bones animation) (IQM, M3D, glTF)
|
||||
- Shaders support, including model shaders and **postprocessing** shaders
|
||||
@ -61,7 +62,7 @@ This is a basic raylib example, it creates a window and draws the text `"Congrat
|
||||
|
||||
int main(void)
|
||||
{
|
||||
InitWindow(800, 450, "raylib [core] example - basic window");
|
||||
InitWindow(800, 450, "raylib example - basic window");
|
||||
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
@ -111,7 +112,7 @@ raylib has been developed on Windows platform using [Notepad++](https://notepad-
|
||||
learning and docs
|
||||
------------------
|
||||
|
||||
raylib is designed to be learned using [the examples](https://github.com/raysan5/raylib/tree/master/examples) as the main reference. There is no standard API documentation but there is a [**cheatsheet**](https://www.raylib.com/cheatsheet/cheatsheet.html) containing all the functions available on the library a short description of each one of them, input parameters and result value names should be intuitive enough to understand how each function works.
|
||||
raylib is designed to be learned using [the examples](https://github.com/raysan5/raylib/tree/master/examples) as the main reference. There is no standard API documentation but there is a [**cheatsheet**](https://www.raylib.com/cheatsheet/cheatsheet.html) containing all the functions available on the library a short description of each one of them, input parameters and result value names should be intuitive enough to understand how each function works.
|
||||
|
||||
Some additional documentation about raylib design can be found in [raylib GitHub Wiki](https://github.com/raysan5/raylib/wiki). Here are the relevant links:
|
||||
|
||||
|
||||
36
ROADMAP.md
36
ROADMAP.md
@ -6,24 +6,37 @@ Here is a wishlist with features and ideas to improve the library. Note that fea
|
||||
- [GitHub PRs](https://github.com/raysan5/raylib/pulls) open with improvements to be reviewed.
|
||||
- [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 7.0 wishlist](https://github.com/raysan5/raylib/discussions/5710)
|
||||
- [raylib 6.0 wishlist](https://github.com/raysan5/raylib/discussions/4660)
|
||||
- [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._
|
||||
|
||||
**raylib 5.x**
|
||||
- [ ] `rcore`: Support additional platforms: iOS, consoles?
|
||||
- [x] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK
|
||||
- [ ] `rlgl`: Review GLSL shaders naming conventions for consistency
|
||||
- [ ] `textures`: Improve compressed textures support, loading and saving
|
||||
- [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
|
||||
- [ ] `raudio`: Implement miniaudio high-level provided features
|
||||
- [x] `examples`: Review all examples, add more and better code explanations
|
||||
- [x] Software renderer backend? Maybe using `Image` provided API
|
||||
**raylib 7.0**
|
||||
- [ ] `rcore_desktop_win32`: Improve new Windows platform backend - inputs, highdpi
|
||||
- [ ] `rcore_desktop_emscripten`: Improve new Web platform backend - inputs, highdpi
|
||||
- [ ] `rcore_desktop_cocoa`: Create additional platform backend: macOS
|
||||
- [ ] `rcore_desktop_x11`: Create additional platform backend: Linux/X11
|
||||
- [ ] `rcore_desktop_wayland`: Create additional platform backend: Linux/Wayland
|
||||
- [ ] `rcore`: Investigate alternative embedded platforms and realtime OSs
|
||||
- [ ] `rlsw`: Software renderer optimizations: mipmaps, platform-specific SIMD
|
||||
- [ ] `rtextures`: Consider removing N-patch system, provide as separate example
|
||||
- [ ] `rtextures`: Review blending modes system, provide more options or better samples
|
||||
- [ ] `rtext`: Investigate the recently opened [`Slug`](https://sluglibrary.com/) font rendering algorithm
|
||||
- [ ] `raudio`: Support microphone input, basic API to read microphone
|
||||
- [ ] `rltexgpu`: Improve compressed textures support, loading and saving, improve KTX 2.0
|
||||
- [ ] `rlobj`: Create OBJ loader, supporting material file separately (low priority)
|
||||
|
||||
**raylib 4.x**
|
||||
**raylib 6.0**
|
||||
- [x] `rlsw`: New Software Renderer backend, pseudo-OpenGL 1.1 implementation
|
||||
- [x] `rcore_emscripten`: New emscripten-only backend, avoiding GLFW dependency
|
||||
- [x] `rlgl`: Review GLSL shaders naming conventions for consistency, redesigned shader API
|
||||
- [x] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
|
||||
- [x] `examples`: Review all examples, add more and better code explanations
|
||||
|
||||
**raylib 5.0**
|
||||
- [x] Split core module into separate platforms?
|
||||
- [x] Redesign gestures system, improve touch inputs management
|
||||
- [x] Redesign camera module (more flexible) ([#1143](https://github.com/raysan5/raylib/issues/1143), https://github.com/raysan5/raylib/discussions/2507)
|
||||
@ -31,7 +44,6 @@ _Current version of raylib is complete and functional but there is always room f
|
||||
- [x] Focus on HTML5 ([raylib 5k gamejam](https://itch.io/jam/raylib-5k-gamejam)) and embedded platforms (RPI and similar SOCs)
|
||||
- [x] Additional support libraries: [raygui](https://github.com/raysan5/raygui), [rres](https://github.com/raysan5/rres)
|
||||
|
||||
|
||||
**raylib 4.0**
|
||||
- [x] Improved consistency and coherency in raylib API
|
||||
- [x] Continuous Deployment using GitHub Actions
|
||||
|
||||
123
build.zig
123
build.zig
@ -2,7 +2,7 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
/// Minimum supported version of Zig
|
||||
const min_ver = "0.16.0-dev.2349+204fa8959";
|
||||
const min_ver = "0.16.0-dev.3013+abd131e33";
|
||||
|
||||
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
|
||||
const emccOutputFile = "index.html";
|
||||
@ -90,41 +90,7 @@ fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of all flags from `src/config.h` that one may override
|
||||
const config_h_flags = outer: {
|
||||
// Set this value higher if compile errors happen as `src/config.h` gets larger
|
||||
@setEvalBranchQuota(1 << 20);
|
||||
|
||||
const config_h = @embedFile("src/config.h");
|
||||
var flags: [std.mem.count(u8, config_h, "\n") + 1][]const u8 = undefined;
|
||||
|
||||
var i = 0;
|
||||
var lines = std.mem.tokenizeScalar(u8, config_h, '\n');
|
||||
while (lines.next()) |line| {
|
||||
if (!std.mem.containsAtLeast(u8, line, 1, "SUPPORT")) continue;
|
||||
if (std.mem.containsAtLeast(u8, line, 1, "MODULE")) continue;
|
||||
if (std.mem.startsWith(u8, line, "//")) continue;
|
||||
if (std.mem.startsWith(u8, line, "#if")) continue;
|
||||
|
||||
var flag = std.mem.trimStart(u8, line, " \t"); // Trim whitespace
|
||||
flag = flag["#define ".len - 1 ..]; // Remove #define
|
||||
flag = std.mem.trimStart(u8, flag, " \t"); // Trim whitespace
|
||||
flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
|
||||
flag = "-D" ++ flag; // Prepend with -D
|
||||
|
||||
flags[i] = flag;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// Uncomment this to check what flags normally get passed
|
||||
//@compileLog(flags[0..i].*);
|
||||
break :outer flags[0..i].*;
|
||||
};
|
||||
|
||||
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||
var raylib_flags_arr: std.ArrayList([]const u8) = .empty;
|
||||
defer raylib_flags_arr.deinit(b.allocator);
|
||||
|
||||
const raylib = b.addLibrary(.{
|
||||
.name = "raylib",
|
||||
.linkage = options.linkage,
|
||||
@ -135,29 +101,27 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
}),
|
||||
});
|
||||
|
||||
try raylib_flags_arr.appendSlice(
|
||||
raylib.root_module.addCMacro("_GNU_SOURCE", "");
|
||||
raylib.root_module.addCMacro("GL_SILENCE_DEPRECATION", "199309L");
|
||||
|
||||
var raylib_flags_arr: std.ArrayList([]const u8) = .empty;
|
||||
defer raylib_flags_arr.deinit(b.allocator);
|
||||
|
||||
try raylib_flags_arr.append(
|
||||
b.allocator,
|
||||
&[_][]const u8{
|
||||
"-std=gnu99",
|
||||
"-D_GNU_SOURCE",
|
||||
"-DGL_SILENCE_DEPRECATION=199309L",
|
||||
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
|
||||
},
|
||||
"-std=gnu99",
|
||||
);
|
||||
|
||||
if (options.linkage == .dynamic) {
|
||||
try raylib_flags_arr.appendSlice(
|
||||
try raylib_flags_arr.append(
|
||||
b.allocator,
|
||||
&[_][]const u8{
|
||||
"-fPIC",
|
||||
"-DBUILD_LIBTYPE_SHARED",
|
||||
},
|
||||
"-fPIC",
|
||||
);
|
||||
|
||||
raylib.root_module.addCMacro("BUILD_LIBTYPE_SHARED", "");
|
||||
}
|
||||
|
||||
if (options.config.len > 0) {
|
||||
// Sets a flag indicating the use of a custom `config.h`
|
||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
||||
// Splits a space-separated list of config flags into multiple flags
|
||||
//
|
||||
// Note: This means certain flags like `-x c++` won't be processed properly.
|
||||
@ -165,30 +129,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
var config_iter = std.mem.tokenizeScalar(u8, options.config, ' ');
|
||||
|
||||
// Apply config flags supplied by the user
|
||||
while (config_iter.next()) |config_flag|
|
||||
while (config_iter.next()) |config_flag| {
|
||||
try raylib_flags_arr.append(b.allocator, config_flag);
|
||||
|
||||
// Apply all relevant configs from `src/config.h` *except* the user-specified ones
|
||||
//
|
||||
// Note: Currently using a suboptimal `O(m*n)` time algorithm where:
|
||||
// `m` corresponds roughly to the number of lines in `src/config.h`
|
||||
// `n` corresponds to the number of user-specified flags
|
||||
outer: for (config_h_flags) |flag| {
|
||||
// If a user already specified the flag, skip it
|
||||
config_iter.reset();
|
||||
while (config_iter.next()) |config_flag| {
|
||||
// For a user-specified flag to match, it must share the same prefix and have the
|
||||
// same length or be followed by an equals sign
|
||||
if (!std.mem.startsWith(u8, config_flag, flag)) continue;
|
||||
if (config_flag.len == flag.len or config_flag[flag.len] == '=') continue :outer;
|
||||
}
|
||||
|
||||
// Otherwise, append default value from config.h to compile flags
|
||||
try raylib_flags_arr.append(b.allocator, flag);
|
||||
}
|
||||
} else {
|
||||
// Set default config if no custom config got set
|
||||
try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
|
||||
}
|
||||
|
||||
// No GLFW required on PLATFORM_DRM
|
||||
@ -200,24 +143,38 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
c_source_files.appendSliceAssumeCapacity(&.{"src/rcore.c"});
|
||||
|
||||
if (options.rshapes) {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RSHAPES", "1");
|
||||
try c_source_files.append(b.allocator, "src/rshapes.c");
|
||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RSHAPES");
|
||||
} else {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RSHAPES", "0");
|
||||
}
|
||||
|
||||
if (options.rtextures) {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RTEXTURES", "1");
|
||||
try c_source_files.append(b.allocator, "src/rtextures.c");
|
||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RTEXTURES");
|
||||
} else {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RTEXTURES", "0");
|
||||
}
|
||||
|
||||
if (options.rtext) {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RTEXT", "1");
|
||||
try c_source_files.append(b.allocator, "src/rtext.c");
|
||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RTEXT");
|
||||
} else {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RTEXT", "0");
|
||||
}
|
||||
|
||||
if (options.rmodels) {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RMODELS", "1");
|
||||
try c_source_files.append(b.allocator, "src/rmodels.c");
|
||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RMODELS");
|
||||
} else {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RMODELS", "0");
|
||||
}
|
||||
|
||||
if (options.raudio) {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RAUDIO", "1");
|
||||
try c_source_files.append(b.allocator, "src/raudio.c");
|
||||
try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RAUDIO");
|
||||
} else {
|
||||
raylib.root_module.addCMacro("SUPPORT_MODULE_RAUDIO", "0");
|
||||
}
|
||||
|
||||
if (options.opengl_version != .auto) {
|
||||
@ -245,8 +202,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
|
||||
}
|
||||
|
||||
raylib.root_module.linkSystemLibrary("EGL", .{});
|
||||
raylib.root_module.linkSystemLibrary("gbm", .{});
|
||||
if (options.opengl_version != .gl_soft) {
|
||||
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", "");
|
||||
@ -307,7 +266,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
|
||||
setDesktopPlatform(raylib, .android);
|
||||
} else {
|
||||
try c_source_files.append(b.allocator, "src/rglfw.c");
|
||||
switch (options.platform) {
|
||||
.glfw => try c_source_files.append(b.allocator, "src/rglfw.c"),
|
||||
.rgfw, .sdl, .drm, .android => {},
|
||||
}
|
||||
|
||||
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
||||
raylib.root_module.addCMacro("_GLFW_X11", "");
|
||||
@ -456,6 +418,7 @@ pub const Options = struct {
|
||||
|
||||
pub const OpenglVersion = enum {
|
||||
auto,
|
||||
gl_soft,
|
||||
gl_1_1,
|
||||
gl_2_1,
|
||||
gl_3_3,
|
||||
@ -466,6 +429,7 @@ pub const OpenglVersion = enum {
|
||||
pub fn toCMacroStr(self: @This()) []const u8 {
|
||||
switch (self) {
|
||||
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
|
||||
.gl_soft => return "GRAPHICS_API_OPENGL_SOFTWARE",
|
||||
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
|
||||
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
|
||||
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
|
||||
@ -477,6 +441,7 @@ pub const OpenglVersion = enum {
|
||||
};
|
||||
|
||||
pub const LinuxDisplayBackend = enum {
|
||||
None,
|
||||
X11,
|
||||
Wayland,
|
||||
Both,
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
|
||||
.dependencies = .{
|
||||
.xcode_frameworks = .{
|
||||
.url = "git+https://github.com/hexops/xcode-frameworks#9a45f3ac977fd25dff77e58c6de1870b6808c4a7",
|
||||
.hash = "N-V-__8AABHMqAWYuRdIlflwi8gksPnlUMQBiSxAqQAAZFms",
|
||||
.url = "https://pkg.machengine.org/xcode-frameworks/8a1cfb373587ea4c9bb1468b7c986462d8d4e10e.tar.gz",
|
||||
.hash = "N-V-__8AALShqgXkvqYU6f__FrA22SMWmi2TXCJjNTO1m8XJ",
|
||||
.lazy = true,
|
||||
},
|
||||
.emsdk = .{
|
||||
|
||||
@ -9,7 +9,7 @@ endif()
|
||||
|
||||
set(RAYLIB_DEPENDENCIES "include(CMakeFindDependencyMacro)")
|
||||
|
||||
if (${PLATFORM} MATCHES "Desktop")
|
||||
if (${PLATFORM} STREQUAL "Desktop")
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP")
|
||||
|
||||
if (APPLE)
|
||||
@ -67,14 +67,14 @@ if (${PLATFORM} MATCHES "Desktop")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
elseif (${PLATFORM} MATCHES "Web")
|
||||
elseif (${PLATFORM} STREQUAL "Web")
|
||||
set(PLATFORM_CPP "PLATFORM_WEB")
|
||||
if(NOT GRAPHICS)
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
endif()
|
||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||
|
||||
elseif (${PLATFORM} MATCHES "Android")
|
||||
elseif (${PLATFORM} STREQUAL "Android")
|
||||
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
@ -94,26 +94,35 @@ elseif (${PLATFORM} MATCHES "Android")
|
||||
set(LIBS_PRIVATE log android EGL GLESv2 OpenSLES atomic c)
|
||||
set(LIBS_PUBLIC m)
|
||||
|
||||
elseif ("${PLATFORM}" MATCHES "DRM")
|
||||
elseif ("${PLATFORM}" STREQUAL "DRM")
|
||||
set(PLATFORM_CPP "PLATFORM_DRM")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
|
||||
add_definitions(-D_DEFAULT_SOURCE)
|
||||
add_definitions(-DEGL_NO_X11)
|
||||
add_definitions(-DPLATFORM_DRM)
|
||||
|
||||
find_library(GLESV2 GLESv2)
|
||||
find_library(EGL EGL)
|
||||
find_library(DRM drm)
|
||||
find_library(GBM gbm)
|
||||
|
||||
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
|
||||
include_directories(/usr/include/libdrm)
|
||||
endif ()
|
||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
||||
|
||||
if ("${OPENGL_VERSION}" STREQUAL "Software")
|
||||
# software rendering does not require EGL/GBM.
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||
set(LIBS_PRIVATE ${DRM} atomic pthread dl)
|
||||
else ()
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
add_definitions(-DEGL_NO_X11)
|
||||
|
||||
find_library(GLESV2 GLESv2)
|
||||
find_library(EGL EGL)
|
||||
find_library(GBM gbm)
|
||||
|
||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
||||
endif ()
|
||||
set(LIBS_PUBLIC m)
|
||||
|
||||
elseif ("${PLATFORM}" MATCHES "SDL")
|
||||
elseif ("${PLATFORM}" STREQUAL "SDL")
|
||||
# First, check if SDL is included as a subdirectory
|
||||
if(TARGET SDL3::SDL3)
|
||||
message(STATUS "Using SDL3 from subdirectory")
|
||||
@ -143,11 +152,11 @@ elseif ("${PLATFORM}" MATCHES "SDL")
|
||||
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)")
|
||||
set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL2 REQUIRED)")
|
||||
add_compile_definitions(USING_SDL2_PACKAGE)
|
||||
endif()
|
||||
endif()
|
||||
elseif ("${PLATFORM}" MATCHES "RGFW")
|
||||
elseif ("${PLATFORM}" STREQUAL "RGFW")
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW")
|
||||
|
||||
if (APPLE)
|
||||
@ -168,7 +177,7 @@ elseif ("${PLATFORM}" MATCHES "RGFW")
|
||||
set(LIBS_PRIVATE ${X11_LIBRARIES} ${OPENGL_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
elseif ("${PLATFORM}" MATCHES "WebRGFW")
|
||||
elseif ("${PLATFORM}" STREQUAL "WebRGFW")
|
||||
set(PLATFORM_CPP "PLATFORM_WEB_RGFW")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||
@ -190,7 +199,7 @@ if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||
elseif (${OPENGL_VERSION} MATCHES "ES 3.0")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES3")
|
||||
elseif (${OPENGL_VERSION} MATCHES "Software")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_11_SOFTWARE")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||
endif ()
|
||||
if (NOT "${SUGGESTED_GRAPHICS}" STREQUAL "" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
||||
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail.")
|
||||
|
||||
@ -95,7 +95,7 @@ USE_EXTERNAL_GLFW ?= FALSE
|
||||
GLFW_LINUX_ENABLE_WAYLAND ?= FALSE
|
||||
GLFW_LINUX_ENABLE_X11 ?= TRUE
|
||||
|
||||
# Enable support for X11 by default on Linux when using GLFW
|
||||
# Enable support for X11 by default on Linux when using RGFW
|
||||
# NOTE: Wayland is disabled by default, only enable if you are sure
|
||||
RGFW_LINUX_ENABLE_WAYLAND ?= FALSE
|
||||
RGFW_LINUX_ENABLE_X11 ?= TRUE
|
||||
@ -155,15 +155,6 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
endif
|
||||
endif
|
||||
|
||||
# RAYLIB_PATH adjustment for LINUX platform
|
||||
# TODO: Do we really need this?
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
RAYLIB_PREFIX ?= ..
|
||||
RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX))
|
||||
endif
|
||||
endif
|
||||
|
||||
# Default path for raylib on Raspberry Pi
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
RAYLIB_PATH ?= /home/pi/raylib
|
||||
@ -178,8 +169,8 @@ ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_R
|
||||
EMSDK_PATH ?= C:/raylib/emsdk
|
||||
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
|
||||
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
|
||||
PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
|
||||
NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
|
||||
PYTHON_PATH = $(EMSDK_PATH)/python/3.13.3_64bit
|
||||
NODE_PATH = $(EMSDK_PATH)/node/22.16.0_64bit/bin
|
||||
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
|
||||
endif
|
||||
endif
|
||||
@ -304,7 +295,7 @@ endif
|
||||
|
||||
# Define library paths containing required libs: LDFLAGS
|
||||
#------------------------------------------------------------------------------------------------
|
||||
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
|
||||
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH)
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
@ -631,6 +622,7 @@ TEXTURES = \
|
||||
textures/textures_blend_modes \
|
||||
textures/textures_bunnymark \
|
||||
textures/textures_cellular_automata \
|
||||
textures/textures_clipboard_image \
|
||||
textures/textures_fog_of_war \
|
||||
textures/textures_framebuffer_rendering \
|
||||
textures/textures_gif_player \
|
||||
@ -643,6 +635,7 @@ TEXTURES = \
|
||||
textures/textures_image_rotate \
|
||||
textures/textures_image_text \
|
||||
textures/textures_logo_raylib \
|
||||
textures/textures_magnifying_glass \
|
||||
textures/textures_mouse_painting \
|
||||
textures/textures_npatch_drawing \
|
||||
textures/textures_particles_blending \
|
||||
@ -712,6 +705,7 @@ SHADERS = \
|
||||
shaders/shaders_ascii_rendering \
|
||||
shaders/shaders_basic_lighting \
|
||||
shaders/shaders_basic_pbr \
|
||||
shaders/shaders_cel_shading \
|
||||
shaders/shaders_color_correction \
|
||||
shaders/shaders_custom_uniform \
|
||||
shaders/shaders_deferred_rendering \
|
||||
@ -753,6 +747,7 @@ AUDIO = \
|
||||
audio/audio_sound_multi \
|
||||
audio/audio_sound_positioning \
|
||||
audio/audio_spectrum_visualizer \
|
||||
audio/audio_stream_callback \
|
||||
audio/audio_stream_effects
|
||||
#EXAMPLES_LIST_END
|
||||
|
||||
|
||||
@ -168,8 +168,8 @@ ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_R
|
||||
EMSDK_PATH ?= C:/raylib/emsdk
|
||||
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
|
||||
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
|
||||
PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-nuget_64bit
|
||||
NODE_PATH = $(EMSDK_PATH)/node/20.18.0_64bit/bin
|
||||
PYTHON_PATH = $(EMSDK_PATH)/python/3.13.3_64bit
|
||||
NODE_PATH = $(EMSDK_PATH)/node/22.16.0_64bit/bin
|
||||
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH):$$(PATH)
|
||||
endif
|
||||
endif
|
||||
@ -596,6 +596,7 @@ TEXTURES = \
|
||||
textures/textures_blend_modes \
|
||||
textures/textures_bunnymark \
|
||||
textures/textures_cellular_automata \
|
||||
textures/textures_clipboard_image \
|
||||
textures/textures_fog_of_war \
|
||||
textures/textures_framebuffer_rendering \
|
||||
textures/textures_gif_player \
|
||||
@ -608,6 +609,7 @@ TEXTURES = \
|
||||
textures/textures_image_rotate \
|
||||
textures/textures_image_text \
|
||||
textures/textures_logo_raylib \
|
||||
textures/textures_magnifying_glass \
|
||||
textures/textures_mouse_painting \
|
||||
textures/textures_npatch_drawing \
|
||||
textures/textures_particles_blending \
|
||||
@ -677,6 +679,7 @@ SHADERS = \
|
||||
shaders/shaders_ascii_rendering \
|
||||
shaders/shaders_basic_lighting \
|
||||
shaders/shaders_basic_pbr \
|
||||
shaders/shaders_cel_shading \
|
||||
shaders/shaders_color_correction \
|
||||
shaders/shaders_custom_uniform \
|
||||
shaders/shaders_deferred_rendering \
|
||||
@ -718,6 +721,7 @@ AUDIO = \
|
||||
audio/audio_sound_multi \
|
||||
audio/audio_sound_positioning \
|
||||
audio/audio_spectrum_visualizer \
|
||||
audio/audio_stream_callback \
|
||||
audio/audio_stream_effects
|
||||
|
||||
# Default target entry
|
||||
@ -1023,6 +1027,9 @@ textures/textures_bunnymark: textures/textures_bunnymark.c
|
||||
textures/textures_cellular_automata: textures/textures_cellular_automata.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
textures/textures_clipboard_image: textures/textures_clipboard_image.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
textures/textures_fog_of_war: textures/textures_fog_of_war.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
@ -1071,6 +1078,11 @@ textures/textures_logo_raylib: textures/textures_logo_raylib.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png
|
||||
|
||||
textures/textures_magnifying_glass: textures/textures_magnifying_glass.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/raybunny.png@resources/raybunny.png \
|
||||
--preload-file textures/resources/parrots.png@resources/parrots.png
|
||||
|
||||
textures/textures_mouse_painting: textures/textures_mouse_painting.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
@ -1141,7 +1153,10 @@ text/text_font_filters: text/text_font_filters.c
|
||||
--preload-file text/resources/KAISG.ttf@resources/KAISG.ttf
|
||||
|
||||
text/text_font_loading: text/text_font_loading.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file text/resources/pixantiqua.fnt@resources/pixantiqua.fnt \
|
||||
--preload-file text/resources/pixantiqua.png@resources/pixantiqua.png \
|
||||
--preload-file text/resources/pixantiqua.ttf@resources/pixantiqua.ttf
|
||||
|
||||
text/text_font_sdf: text/text_font_sdf.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
@ -1365,6 +1380,14 @@ shaders/shaders_basic_pbr: shaders/shaders_basic_pbr.c
|
||||
--preload-file shaders/resources/road_mra.png@resources/road_mra.png \
|
||||
--preload-file shaders/resources/road_n.png@resources/road_n.png
|
||||
|
||||
shaders/shaders_cel_shading: shaders/shaders_cel_shading.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file shaders/resources/models/old_car_new.glb@resources/models/old_car_new.glb \
|
||||
--preload-file shaders/resources/shaders/glsl100/cel.vs@resources/shaders/glsl100/cel.vs \
|
||||
--preload-file shaders/resources/shaders/glsl100/cel.fs@resources/shaders/glsl100/cel.fs \
|
||||
--preload-file shaders/resources/shaders/glsl100/outline_hull.vs@resources/shaders/glsl100/outline_hull.vs \
|
||||
--preload-file shaders/resources/shaders/glsl100/outline_hull.fs@resources/shaders/glsl100/outline_hull.fs
|
||||
|
||||
shaders/shaders_color_correction: shaders/shaders_color_correction.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file shaders/resources/parrots.png@resources/parrots.png \
|
||||
@ -1550,7 +1573,8 @@ audio/audio_mixed_processor: audio/audio_mixed_processor.c
|
||||
--preload-file audio/resources/coin.wav@resources/coin.wav
|
||||
|
||||
audio/audio_module_playing: audio/audio_module_playing.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file audio/resources/mini1111.xm@resources/mini1111.xm
|
||||
|
||||
audio/audio_music_stream: audio/audio_music_stream.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
@ -1577,6 +1601,9 @@ audio/audio_spectrum_visualizer: audio/audio_spectrum_visualizer.c
|
||||
--preload-file audio/resources/shaders/glsl100/fft.fs@resources/shaders/glsl100/fft.fs \
|
||||
--preload-file audio/resources/country.mp3@resources/country.mp3
|
||||
|
||||
audio/audio_stream_callback: audio/audio_stream_callback.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
audio/audio_stream_effects: audio/audio_stream_effects.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file audio/resources/country.mp3@resources/country.mp3
|
||||
|
||||
@ -17,7 +17,7 @@ You may find it easier to use than other toolchains, especially when it comes to
|
||||
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
|
||||
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
|
||||
|
||||
## EXAMPLES COLLECTION [TOTAL: 208]
|
||||
## EXAMPLES COLLECTION [TOTAL: 212]
|
||||
|
||||
### category: core [49]
|
||||
|
||||
@ -26,14 +26,14 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
||||
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||
| [core_basic_window](core/core_basic_window.c) | <img src="core/core_basic_window.png" alt="core_basic_window" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_delta_time](core/core_delta_time.c) | <img src="core/core_delta_time.png" alt="core_delta_time" width="80"> | ⭐☆☆☆ | 5.5 | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
||||
| [core_delta_time](core/core_delta_time.c) | <img src="core/core_delta_time.png" alt="core_delta_time" width="80"> | ⭐☆☆☆ | 5.5 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [core_input_keys](core/core_input_keys.c) | <img src="core/core_input_keys.png" alt="core_input_keys" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_input_mouse](core/core_input_mouse.c) | <img src="core/core_input_mouse.png" alt="core_input_mouse" width="80"> | ⭐☆☆☆ | 1.0 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_input_mouse_wheel](core/core_input_mouse_wheel.c) | <img src="core/core_input_mouse_wheel.png" alt="core_input_mouse_wheel" width="80"> | ⭐☆☆☆ | 1.1 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐☆☆☆ | 1.1 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) |
|
||||
| [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐⭐☆☆ | 1.4 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_input_gestures_testbed](core/core_input_gestures_testbed.c) | <img src="core/core_input_gestures_testbed.png" alt="core_input_gestures_testbed" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.6-dev | [ubkp](https://github.com/ubkp) |
|
||||
| [core_input_gestures_testbed](core/core_input_gestures_testbed.c) | <img src="core/core_input_gestures_testbed.png" alt="core_input_gestures_testbed" width="80"> | ⭐⭐⭐☆ | 5.0 | 6.0 | [ubkp](https://github.com/ubkp) |
|
||||
| [core_input_virtual_controls](core/core_input_virtual_controls.c) | <img src="core/core_input_virtual_controls.png" alt="core_input_virtual_controls" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [GreenSnakeLinux](https://github.com/GreenSnakeLinux) |
|
||||
| [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐⭐☆☆ | 1.5 | 3.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐⭐☆☆ | 4.2 | 4.2 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
@ -62,16 +62,16 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
||||
| [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐☆☆☆ | 5.0 | 5.0 | [Dalton Overmyer](https://github.com/REDl3east) |
|
||||
| [core_automation_events](core/core_automation_events.c) | <img src="core/core_automation_events.png" alt="core_automation_events" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_highdpi_demo](core/core_highdpi_demo.c) | <img src="core/core_highdpi_demo.png" alt="core_highdpi_demo" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) |
|
||||
| [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_undo_redo](core/core_undo_redo.c) | <img src="core/core_undo_redo.png" alt="core_undo_redo" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_viewport_scaling](core/core_viewport_scaling.c) | <img src="core/core_viewport_scaling.png" alt="core_viewport_scaling" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
||||
| [core_input_actions](core/core_input_actions.c) | <img src="core/core_input_actions.png" alt="core_input_actions" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) |
|
||||
| [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
|
||||
| [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) |
|
||||
| [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Ananth S](https://github.com/Ananth1839) |
|
||||
| [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
|
||||
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_keyboard_testbed](core/core_keyboard_testbed.c) | <img src="core/core_keyboard_testbed.png" alt="core_keyboard_testbed" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_window_web](core/core_window_web.c) | <img src="core/core_window_web.png" alt="core_window_web" width="80"> | ⭐☆☆☆ | 1.3 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
|
||||
@ -94,7 +94,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||
| [shapes_easings_ball](shapes/shapes_easings_ball.c) | <img src="shapes/shapes_easings_ball.png" alt="shapes_easings_ball" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [shapes_easings_box](shapes/shapes_easings_box.c) | <img src="shapes/shapes_easings_box.png" alt="shapes_easings_box" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [shapes_easings_rectangles](shapes/shapes_easings_rectangles.c) | <img src="shapes/shapes_easings_rectangles.png" alt="shapes_easings_rectangles" width="80"> | ⭐⭐⭐☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [shapes_recursive_tree](shapes/shapes_recursive_tree.c) | <img src="shapes/shapes_recursive_tree.png" alt="shapes_recursive_tree" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [shapes_recursive_tree](shapes/shapes_recursive_tree.c) | <img src="shapes/shapes_recursive_tree.png" alt="shapes_recursive_tree" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [shapes_ring_drawing](shapes/shapes_ring_drawing.c) | <img src="shapes/shapes_ring_drawing.png" alt="shapes_ring_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| [shapes_circle_sector_drawing](shapes/shapes_circle_sector_drawing.c) | <img src="shapes/shapes_circle_sector_drawing.png" alt="shapes_circle_sector_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| [shapes_rounded_rectangle_drawing](shapes/shapes_rounded_rectangle_drawing.c) | <img src="shapes/shapes_rounded_rectangle_drawing.png" alt="shapes_rounded_rectangle_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
@ -104,30 +104,32 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||
| [shapes_digital_clock](shapes/shapes_digital_clock.c) | <img src="shapes/shapes_digital_clock.png" alt="shapes_digital_clock" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
||||
| [shapes_double_pendulum](shapes/shapes_double_pendulum.c) | <img src="shapes/shapes_double_pendulum.png" alt="shapes_double_pendulum" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) |
|
||||
| [shapes_dashed_line](shapes/shapes_dashed_line.c) | <img src="shapes/shapes_dashed_line.png" alt="shapes_dashed_line" width="80"> | ⭐☆☆☆ | 5.5 | 5.5 | [Luís Almeida](https://github.com/luis605) |
|
||||
| [shapes_triangle_strip](shapes/shapes_triangle_strip.c) | <img src="shapes/shapes_triangle_strip.png" alt="shapes_triangle_strip" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [shapes_triangle_strip](shapes/shapes_triangle_strip.c) | <img src="shapes/shapes_triangle_strip.png" alt="shapes_triangle_strip" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [shapes_vector_angle](shapes/shapes_vector_angle.c) | <img src="shapes/shapes_vector_angle.png" alt="shapes_vector_angle" width="80"> | ⭐⭐☆☆ | 1.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [shapes_pie_chart](shapes/shapes_pie_chart.c) | <img src="shapes/shapes_pie_chart.png" alt="shapes_pie_chart" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Gideon Serfontein](https://github.com/GideonSerf) |
|
||||
| [shapes_kaleidoscope](shapes/shapes_kaleidoscope.c) | <img src="shapes/shapes_kaleidoscope.png" alt="shapes_kaleidoscope" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
|
||||
| [shapes_clock_of_clocks](shapes/shapes_clock_of_clocks.c) | <img src="shapes/shapes_clock_of_clocks.png" alt="shapes_clock_of_clocks" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [shapes_math_sine_cosine](shapes/shapes_math_sine_cosine.c) | <img src="shapes/shapes_math_sine_cosine.png" alt="shapes_math_sine_cosine" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [shapes_mouse_trail](shapes/shapes_mouse_trail.c) | <img src="shapes/shapes_mouse_trail.png" alt="shapes_mouse_trail" width="80"> | ⭐☆☆☆ | 5.6 | 5.6-dev | [Balamurugan R](https://github.com/Bala050814) |
|
||||
| [shapes_clock_of_clocks](shapes/shapes_clock_of_clocks.c) | <img src="shapes/shapes_clock_of_clocks.png" alt="shapes_clock_of_clocks" width="80"> | ⭐⭐☆☆ | 5.5 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [shapes_math_sine_cosine](shapes/shapes_math_sine_cosine.c) | <img src="shapes/shapes_math_sine_cosine.png" alt="shapes_math_sine_cosine" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [shapes_mouse_trail](shapes/shapes_mouse_trail.c) | <img src="shapes/shapes_mouse_trail.png" alt="shapes_mouse_trail" width="80"> | ⭐☆☆☆ | 5.6 | 6.0 | [Balamurugan R](https://github.com/Bala050814) |
|
||||
| [shapes_simple_particles](shapes/shapes_simple_particles.c) | <img src="shapes/shapes_simple_particles.png" alt="shapes_simple_particles" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shapes_starfield_effect](shapes/shapes_starfield_effect.c) | <img src="shapes/shapes_starfield_effect.png" alt="shapes_starfield_effect" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | <img src="shapes/shapes_lines_drawing.png" alt="shapes_lines_drawing" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | <img src="shapes/shapes_math_angle_rotation.png" alt="shapes_math_angle_rotation" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6 | [Kris](https://github.com/krispy-snacc) |
|
||||
| [shapes_rlgl_color_wheel](shapes/shapes_rlgl_color_wheel.c) | <img src="shapes/shapes_rlgl_color_wheel.png" alt="shapes_rlgl_color_wheel" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [shapes_starfield_effect](shapes/shapes_starfield_effect.c) | <img src="shapes/shapes_starfield_effect.png" alt="shapes_starfield_effect" width="80"> | ⭐⭐☆☆ | 5.5 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | <img src="shapes/shapes_lines_drawing.png" alt="shapes_lines_drawing" width="80"> | ⭐☆☆☆ | 6.0 | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | <img src="shapes/shapes_math_angle_rotation.png" alt="shapes_math_angle_rotation" width="80"> | ⭐☆☆☆ | 6.0 | 5.6 | [Kris](https://github.com/krispy-snacc) |
|
||||
| [shapes_rlgl_color_wheel](shapes/shapes_rlgl_color_wheel.c) | <img src="shapes/shapes_rlgl_color_wheel.png" alt="shapes_rlgl_color_wheel" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | <img src="shapes/shapes_hilbert_curve.png" alt="shapes_hilbert_curve" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
||||
| [shapes_easings_testbed](shapes/shapes_easings_testbed.c) | <img src="shapes/shapes_easings_testbed.png" alt="shapes_easings_testbed" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||
|
||||
### category: textures [30]
|
||||
### category: textures [32]
|
||||
|
||||
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
|
||||
|
||||
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||
| [textures_clipboard_image](textures/textures_clipboard_image.c) | <img src="textures/textures_clipboard_image.png" alt="textures_clipboard_image" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Maicon Santana](https://github.com/maiconpintoabreu) |
|
||||
| [textures_magnifying_glass](textures/textures_magnifying_glass.c) | <img src="textures/textures_magnifying_glass.png" alt="textures_magnifying_glass" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Luke Vaughan](https://github.com/badram) |
|
||||
| [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐⭐⭐☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐⭐☆☆ | 1.4 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
@ -155,7 +157,7 @@ Examples using raylib textures functionality, including image/textures loading/g
|
||||
| [textures_image_rotate](textures/textures_image_rotate.c) | <img src="textures/textures_image_rotate.png" alt="textures_image_rotate" width="80"> | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [textures_screen_buffer](textures/textures_screen_buffer.c) | <img src="textures/textures_screen_buffer.png" alt="textures_screen_buffer" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
||||
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [textures_framebuffer_rendering](textures/textures_framebuffer_rendering.c) | <img src="textures/textures_framebuffer_rendering.png" alt="textures_framebuffer_rendering" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jack Boakes](https://github.com/jackboakes) |
|
||||
|
||||
@ -178,9 +180,9 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
||||
| [text_unicode_ranges](text/text_unicode_ranges.c) | <img src="text/text_unicode_ranges.png" alt="text_unicode_ranges" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Vadim Gunko](https://github.com/GuvaCode) |
|
||||
| [text_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) |
|
||||
| [text_words_alignment](text/text_words_alignment.c) | <img src="text/text_words_alignment.png" alt="text_words_alignment" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [text_strings_management](text/text_strings_management.c) | <img src="text/text_strings_management.png" alt="text_strings_management" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [text_inline_styling](text/text_inline_styling.c) | <img src="text/text_inline_styling.png" alt="text_inline_styling" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Wagner Barongello](https://github.com/SultansOfCode) |
|
||||
| [text_words_alignment](text/text_words_alignment.c) | <img src="text/text_words_alignment.png" alt="text_words_alignment" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [text_strings_management](text/text_strings_management.c) | <img src="text/text_strings_management.png" alt="text_strings_management" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
|
||||
### category: models [30]
|
||||
|
||||
@ -210,22 +212,22 @@ Examples using raylib models functionality, including models loading/generation
|
||||
| [models_textured_cube](models/models_textured_cube.c) | <img src="models/models_textured_cube.png" alt="models_textured_cube" width="80"> | ⭐⭐☆☆ | 4.5 | 4.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [models_animation_gpu_skinning](models/models_animation_gpu_skinning.c) | <img src="models/models_animation_gpu_skinning.png" alt="models_animation_gpu_skinning" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Daniel Holden](https://github.com/orangeduck) |
|
||||
| [models_bone_socket](models/models_bone_socket.c) | <img src="models/models_bone_socket.png" alt="models_bone_socket" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
|
||||
| [models_tesseract_view](models/models_tesseract_view.c) | <img src="models/models_tesseract_view.png" alt="models_tesseract_view" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) |
|
||||
| [models_tesseract_view](models/models_tesseract_view.c) | <img src="models/models_tesseract_view.png" alt="models_tesseract_view" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Timothy van der Valk](https://github.com/arceryz) |
|
||||
| [models_basic_voxel](models/models_basic_voxel.c) | <img src="models/models_basic_voxel.png" alt="models_basic_voxel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) |
|
||||
| [models_rotating_cube](models/models_rotating_cube.c) | <img src="models/models_rotating_cube.png" alt="models_rotating_cube" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [models_decals](models/models_decals.c) | <img src="models/models_decals.png" alt="models_decals" width="80"> | ⭐⭐⭐⭐️ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [models_directional_billboard](models/models_directional_billboard.c) | <img src="models/models_directional_billboard.png" alt="models_directional_billboard" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [models_animation_blend_custom](models/models_animation_blend_custom.c) | <img src="models/models_animation_blend_custom.png" alt="models_animation_blend_custom" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.5 | [dmitrii-brand](https://github.com/dmitrii-brand) |
|
||||
| [models_animation_blending](models/models_animation_blending.c) | <img src="models/models_animation_blending.png" alt="models_animation_blending" width="80"> | ☆☆☆☆ | 5.5 | 5.6-dev | [Kirandeep](https://github.com/Kirandeep-Singh-Khehra) |
|
||||
| [models_animation_timming](models/models_animation_timming.c) | <img src="models/models_animation_timming.png" alt="models_animation_timming" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [models_rotating_cube](models/models_rotating_cube.c) | <img src="models/models_rotating_cube.png" alt="models_rotating_cube" width="80"> | ⭐☆☆☆ | 6.0 | 6.0 | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [models_decals](models/models_decals.c) | <img src="models/models_decals.png" alt="models_decals" width="80"> | ⭐⭐⭐⭐️ | 6.0 | 6.0 | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [models_directional_billboard](models/models_directional_billboard.c) | <img src="models/models_directional_billboard.png" alt="models_directional_billboard" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [models_animation_blend_custom](models/models_animation_blend_custom.c) | <img src="models/models_animation_blend_custom.png" alt="models_animation_blend_custom" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [dmitrii-brand](https://github.com/dmitrii-brand) |
|
||||
| [models_animation_blending](models/models_animation_blending.c) | <img src="models/models_animation_blending.png" alt="models_animation_blending" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 6.0 | [Kirandeep](https://github.com/Kirandeep-Singh-Khehra) |
|
||||
| [models_animation_timing](models/models_animation_timing.c) | <img src="models/models_animation_timing.png" alt="models_animation_timing" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
|
||||
### category: shaders [34]
|
||||
### category: shaders [35]
|
||||
|
||||
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module.
|
||||
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.h) module.
|
||||
|
||||
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||
| [shaders_ascii_rendering](shaders/shaders_ascii_rendering.c) | <img src="shaders/shaders_ascii_rendering.png" alt="shaders_ascii_rendering" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Maicon Santana](https://github.com/maiconpintoabreu) |
|
||||
| [shaders_ascii_rendering](shaders/shaders_ascii_rendering.c) | <img src="shaders/shaders_ascii_rendering.png" alt="shaders_ascii_rendering" width="80"> | ⭐⭐☆☆ | 5.5 | 6.0 | [Maicon Santana](https://github.com/maiconpintoabreu) |
|
||||
| [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐⭐⭐⭐️ | 3.0 | 4.2 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||
| [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐⭐☆☆ | 1.3 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐⭐☆☆ | 1.7 | 3.7 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
@ -237,15 +239,15 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
||||
| [shaders_texture_outline](shaders/shaders_texture_outline.c) | <img src="shaders/shaders_texture_outline.png" alt="shaders_texture_outline" width="80"> | ⭐⭐⭐☆ | 4.0 | 4.0 | [Serenity Skiff](https://github.com/GoldenThumbs) |
|
||||
| [shaders_texture_waves](shaders/shaders_texture_waves.c) | <img src="shaders/shaders_texture_waves.png" alt="shaders_texture_waves" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) |
|
||||
| [shaders_julia_set](shaders/shaders_julia_set.c) | <img src="shaders/shaders_julia_set.png" alt="shaders_julia_set" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [Josh Colclough](https://github.com/joshcol9232) |
|
||||
| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | <img src="shaders/shaders_mandelbrot_set.png" alt="shaders_mandelbrot_set" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shaders_color_correction](shaders/shaders_color_correction.c) | <img src="shaders/shaders_color_correction.png" alt="shaders_color_correction" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | <img src="shaders/shaders_mandelbrot_set.png" alt="shaders_mandelbrot_set" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shaders_color_correction](shaders/shaders_color_correction.c) | <img src="shaders/shaders_color_correction.png" alt="shaders_color_correction" width="80"> | ⭐⭐☆☆ | 6.0 | 6.0 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shaders_eratosthenes_sieve](shaders/shaders_eratosthenes_sieve.c) | <img src="shaders/shaders_eratosthenes_sieve.png" alt="shaders_eratosthenes_sieve" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [ProfJski](https://github.com/ProfJski) |
|
||||
| [shaders_fog_rendering](shaders/shaders_fog_rendering.c) | <img src="shaders/shaders_fog_rendering.png" alt="shaders_fog_rendering" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||
| [shaders_simple_mask](shaders/shaders_simple_mask.c) | <img src="shaders/shaders_simple_mask.png" alt="shaders_simple_mask" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||
| [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐⭐⭐☆ | 3.0 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐⭐⭐⭐️ | 3.7 | 4.2 | [seanpringle](https://github.com/seanpringle) |
|
||||
| [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐⭐☆☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [shaders_normalmap_rendering](shaders/shaders_normalmap_rendering.c) | <img src="shaders/shaders_normalmap_rendering.png" alt="shaders_normalmap_rendering" width="80"> | ⭐⭐⭐⭐️ | 5.6 | 5.6 | [Jeremy Montgomery](https://github.com/Sir_Irk) |
|
||||
| [shaders_normalmap_rendering](shaders/shaders_normalmap_rendering.c) | <img src="shaders/shaders_normalmap_rendering.png" alt="shaders_normalmap_rendering" width="80"> | ⭐⭐⭐⭐️ | 6.0 | 6.0 | [Jeremy Montgomery](https://github.com/Sir_Irk) |
|
||||
| [shaders_spotlight_rendering](shaders/shaders_spotlight_rendering.c) | <img src="shaders/shaders_spotlight_rendering.png" alt="shaders_spotlight_rendering" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
|
||||
| [shaders_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) |
|
||||
@ -256,11 +258,12 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
||||
| [shaders_basic_pbr](shaders/shaders_basic_pbr.c) | <img src="shaders/shaders_basic_pbr.png" alt="shaders_basic_pbr" width="80"> | ⭐⭐⭐⭐️ | 5.0 | 5.5 | [Afan OLOVCIC](https://github.com/_DevDad) |
|
||||
| [shaders_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) |
|
||||
| [shaders_game_of_life](shaders/shaders_game_of_life.c) | <img src="shaders/shaders_game_of_life.png" alt="shaders_game_of_life" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shaders_depth_rendering](shaders/shaders_depth_rendering.c) | <img src="shaders/shaders_depth_rendering.png" alt="shaders_depth_rendering" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Luís Almeida](https://github.com/luis605) |
|
||||
| [shaders_game_of_life](shaders/shaders_game_of_life.c) | <img src="shaders/shaders_game_of_life.png" alt="shaders_game_of_life" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shaders_rlgl_compute](shaders/shaders_rlgl_compute.c) | <img src="shaders/shaders_rlgl_compute.png" alt="shaders_rlgl_compute" width="80"> | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
|
||||
| [shaders_cel_shading](shaders/shaders_cel_shading.c) | <img src="shaders/shaders_cel_shading.png" alt="shaders_cel_shading" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Gleb A](https://github.com/ggrizzly) |
|
||||
|
||||
### category: audio [9]
|
||||
### category: audio [10]
|
||||
|
||||
Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib.
|
||||
|
||||
@ -268,13 +271,14 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||
| [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐☆☆☆ | 1.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐☆☆☆ | 1.3 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐⭐⭐☆ | 1.6 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐⭐⭐☆ | 1.6 | 6.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐☆☆☆ | 1.1 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [audio_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) |
|
||||
| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | <img src="audio/audio_spectrum_visualizer.png" alt="audio_spectrum_visualizer" width="80"> | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) |
|
||||
| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | <img src="audio/audio_spectrum_visualizer.png" alt="audio_spectrum_visualizer" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [IANN](https://github.com/meisei4) |
|
||||
| [audio_stream_callback](audio/audio_stream_callback.c) | <img src="audio/audio_stream_callback.png" alt="audio_stream_callback" width="80"> | ⭐⭐⭐☆ | 6.0 | 6.0 | [Dan Hoang](https://github.com/dan-hoang) |
|
||||
|
||||
Some example missing? As always, contributions are welcome, feel free to send new examples!
|
||||
Here is an [examples template](examples_template.c) with instructions to start with!
|
||||
|
||||
238
examples/audio/audio_amp_envelope.c
Normal file
238
examples/audio/audio_amp_envelope.c
Normal file
@ -0,0 +1,238 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - amp envelope
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Arbinda Rizki Muhammad (@arbipink) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2026 Arbinda Rizki Muhammad (@arbipink)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h"
|
||||
|
||||
#include <math.h> // Required for: sinf()
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
#define SAMPLE_RATE 44100
|
||||
|
||||
// Wave state
|
||||
typedef enum {
|
||||
IDLE,
|
||||
ATTACK,
|
||||
DECAY,
|
||||
SUSTAIN,
|
||||
RELEASE
|
||||
} ADSRState;
|
||||
|
||||
// Grouping all ADSR parameters and state into a struct
|
||||
typedef struct {
|
||||
float attackTime;
|
||||
float decayTime;
|
||||
float sustainLevel;
|
||||
float releaseTime;
|
||||
float currentValue;
|
||||
ADSRState state;
|
||||
} Envelope;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime);
|
||||
static void UpdateEnvelope(Envelope *env);
|
||||
static void DrawADSRGraph(Envelope *env, Rectangle bounds);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - amp envelope");
|
||||
|
||||
InitAudioDevice();
|
||||
|
||||
// Set the number of samples the stream will keep in memory at a time to BUFFER_SIZE
|
||||
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
|
||||
float buffer[BUFFER_SIZE] = { 0 };
|
||||
|
||||
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
|
||||
AudioStream stream = LoadAudioStream(SAMPLE_RATE, 32, 1);
|
||||
|
||||
// Init Phase
|
||||
float audioTime = 0.0f;
|
||||
|
||||
// Initialize the struct
|
||||
Envelope env = {
|
||||
.attackTime = 1.0f,
|
||||
.decayTime = 1.0f,
|
||||
.sustainLevel = 0.5f,
|
||||
.releaseTime = 1.0f,
|
||||
.currentValue = 0.0f,
|
||||
.state = IDLE
|
||||
};
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_SPACE)) env.state = ATTACK;
|
||||
|
||||
if (IsKeyReleased(KEY_SPACE) && (env.state != IDLE)) env.state = RELEASE;
|
||||
|
||||
if (IsAudioStreamProcessed(stream))
|
||||
{
|
||||
if ((env.state != IDLE) || (env.currentValue > 0.0f))
|
||||
{
|
||||
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||
{
|
||||
UpdateEnvelope(&env);
|
||||
FillAudioBuffer(i, buffer, env.currentValue, &audioTime);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear buffer if silent to avoid looping noise
|
||||
for (int i = 0; i < BUFFER_SIZE; i++) buffer[i] = 0;
|
||||
audioTime = 0.0f;
|
||||
}
|
||||
|
||||
UpdateAudioStream(stream, buffer, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
if (!IsAudioStreamPlaying(stream)) PlayAudioStream(stream);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
GuiSliderBar((Rectangle){ 100, 60, 400, 30 }, "Attack (s)", TextFormat("%2.2fs", env.attackTime), &env.attackTime, 0.1f, 3.0f);
|
||||
GuiSliderBar((Rectangle){ 100, 100, 400, 30 }, "Decay (s)", TextFormat("%2.2fs", env.decayTime), &env.decayTime, 0.1f, 3.0f);
|
||||
GuiSliderBar((Rectangle){ 100, 140, 400, 30 }, "Sustain", TextFormat("%2.2f", env.sustainLevel), &env.sustainLevel, 0.0f, 1.0f);
|
||||
GuiSliderBar((Rectangle){ 100, 180, 400, 30 }, "Release (s)", TextFormat("%2.2fs", env.releaseTime), &env.releaseTime, 0.1f, 3.0f);
|
||||
|
||||
DrawADSRGraph(&env, (Rectangle){ 100, 250, 400, 100 });
|
||||
|
||||
DrawCircleV((Vector2){ 520, 350 - (env.currentValue * 100) }, 5, MAROON);
|
||||
DrawText(TextFormat("Current Gain: %2.2f", env.currentValue), 535, 345 - (env.currentValue * 100), 10, MAROON);
|
||||
|
||||
DrawText("Press SPACE to PLAY the sound!", 200, 400, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadAudioStream(stream);
|
||||
CloseAudioDevice();
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//------------------------------------------------------------------------------------
|
||||
static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime)
|
||||
{
|
||||
int frequency = 440;
|
||||
buffer[i] = envelopeValue*sinf(2.0f*PI*frequency*(*audioTime));
|
||||
*audioTime += (1.0f/SAMPLE_RATE);
|
||||
}
|
||||
|
||||
static void UpdateEnvelope(Envelope *env)
|
||||
{
|
||||
// Calculate the time delta for ONE sample (1/44100)
|
||||
float sampleTime = 1.0f/SAMPLE_RATE;
|
||||
|
||||
switch(env->state)
|
||||
{
|
||||
case ATTACK:
|
||||
{
|
||||
env->currentValue += (1.0f/env->attackTime)*sampleTime;
|
||||
if (env->currentValue >= 1.0f)
|
||||
{
|
||||
env->currentValue = 1.0f;
|
||||
env->state = DECAY;
|
||||
}
|
||||
|
||||
} break;
|
||||
case DECAY:
|
||||
{
|
||||
env->currentValue -= ((1.0f - env->sustainLevel)/env->decayTime)*sampleTime;
|
||||
if (env->currentValue <= env->sustainLevel)
|
||||
{
|
||||
env->currentValue = env->sustainLevel;
|
||||
env->state = SUSTAIN;
|
||||
}
|
||||
|
||||
} break;
|
||||
case SUSTAIN:
|
||||
{
|
||||
env->currentValue = env->sustainLevel;
|
||||
|
||||
} break;
|
||||
case RELEASE:
|
||||
{
|
||||
env->currentValue -= (env->sustainLevel/env->releaseTime)*sampleTime;
|
||||
if (env->currentValue <= 0.001f) // Use a small threshold to avoid infinite tail
|
||||
{
|
||||
env->currentValue = 0.0f;
|
||||
env->state = IDLE;
|
||||
}
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawADSRGraph(Envelope *env, Rectangle bounds)
|
||||
{
|
||||
DrawRectangleRec(bounds, Fade(LIGHTGRAY, 0.3f));
|
||||
DrawRectangleLinesEx(bounds, 1, GRAY);
|
||||
|
||||
// Fixed visual width for sustain stage since it's an amplitude not a time value
|
||||
float sustainWidth = 1.0f;
|
||||
|
||||
// Total time to visualize (sum of A, D, R + a padding for Sustain)
|
||||
float totalTime = env->attackTime + env->decayTime + sustainWidth + env->releaseTime;
|
||||
|
||||
float scaleX = bounds.width/totalTime;
|
||||
float scaleY = bounds.height;
|
||||
|
||||
Vector2 start = { bounds.x, bounds.y + bounds.height };
|
||||
Vector2 peak = { start.x + (env->attackTime*scaleX), bounds.y };
|
||||
Vector2 sustain = { peak.x + (env->decayTime*scaleX), bounds.y + (1.0f - env->sustainLevel)*scaleY };
|
||||
Vector2 rel = { sustain.x + (sustainWidth*scaleX), sustain.y };
|
||||
Vector2 end = { rel.x + (env->releaseTime*scaleX), bounds.y + bounds.height };
|
||||
|
||||
DrawLineV(start, peak, SKYBLUE);
|
||||
DrawLineV(peak, sustain, BLUE);
|
||||
DrawLineV(sustain, rel, DARKBLUE);
|
||||
DrawLineV(rel, end, ORANGE);
|
||||
|
||||
DrawText("ADSR Visualizer", bounds.x, bounds.y - 20, 10, DARKGRAY);
|
||||
}
|
||||
BIN
examples/audio/audio_amp_envelope.png
Normal file
BIN
examples/audio/audio_amp_envelope.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@ -4,53 +4,22 @@
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 1.6, last time updated with raylib 4.2
|
||||
* Example originally created with raylib 1.6, last time updated with raylib 6.0
|
||||
*
|
||||
* Example created by Ramon Santamaria (@raysan5) and reviewed by James Hofmann (@triplefox)
|
||||
*
|
||||
* Example 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-2025 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
|
||||
* Copyright (c) 2015-2026 Ramon Santamaria (@raysan5) and James Hofmann (@triplefox)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include <math.h>
|
||||
|
||||
#include <stdlib.h> // Required for: malloc(), free()
|
||||
#include <math.h> // Required for: sinf()
|
||||
#include <string.h> // Required for: memcpy()
|
||||
|
||||
#define MAX_SAMPLES 512
|
||||
#define MAX_SAMPLES_PER_UPDATE 4096
|
||||
|
||||
// Cycles per second (hz)
|
||||
float frequency = 440.0f;
|
||||
|
||||
// Audio frequency, for smoothing
|
||||
float audioFrequency = 440.0f;
|
||||
|
||||
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
|
||||
float oldFrequency = 1.0f;
|
||||
|
||||
// Index for audio rendering
|
||||
float sineIdx = 0.0f;
|
||||
|
||||
// Audio input processing callback
|
||||
void AudioInputCallback(void *buffer, unsigned int frames)
|
||||
{
|
||||
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
|
||||
|
||||
float incr = audioFrequency/44100.0f;
|
||||
short *d = (short *)buffer;
|
||||
|
||||
for (unsigned int i = 0; i < frames; i++)
|
||||
{
|
||||
d[i] = (short)(32000.0f*sinf(2*PI*sineIdx));
|
||||
sineIdx += incr;
|
||||
if (sineIdx > 1.0f) sineIdx -= 1.0f;
|
||||
}
|
||||
}
|
||||
#define BUFFER_SIZE 4096
|
||||
#define SAMPLE_RATE 44100
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
@ -64,43 +33,24 @@ int main(void)
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw stream");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
InitAudioDevice();
|
||||
|
||||
SetAudioStreamBufferSizeDefault(MAX_SAMPLES_PER_UPDATE);
|
||||
// Set the number of samples the stream will keep in memory at a time to BUFFER_SIZE
|
||||
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
|
||||
float buffer[BUFFER_SIZE] = {};
|
||||
|
||||
// Init raw audio stream (sample rate: 44100, sample size: 16bit-short, channels: 1-mono)
|
||||
AudioStream stream = LoadAudioStream(44100, 16, 1);
|
||||
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
|
||||
AudioStream stream = LoadAudioStream(SAMPLE_RATE, 32, 1);
|
||||
float pan = 0.0f;
|
||||
SetAudioStreamPan(stream, pan);
|
||||
PlayAudioStream(stream);
|
||||
|
||||
SetAudioStreamCallback(stream, AudioInputCallback);
|
||||
int sineFrequency = 440;
|
||||
int newSineFrequency = 440;
|
||||
int sineIndex = 0;
|
||||
double sineStartTime = 0.0;
|
||||
|
||||
// Buffer for the single cycle waveform we are synthesizing
|
||||
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
|
||||
|
||||
// Frame buffer, describing the waveform when repeated over the course of a frame
|
||||
short *writeBuf = (short *)malloc(sizeof(short)*MAX_SAMPLES_PER_UPDATE);
|
||||
|
||||
PlayAudioStream(stream); // Start processing stream buffer (no data loaded currently)
|
||||
|
||||
// Position read in to determine next frequency
|
||||
Vector2 mousePosition = { -100.0f, -100.0f };
|
||||
|
||||
/*
|
||||
// Cycles per second (hz)
|
||||
float frequency = 440.0f;
|
||||
|
||||
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
|
||||
float oldFrequency = 1.0f;
|
||||
|
||||
// Cursor to read and copy the samples of the sine wave buffer
|
||||
int readCursor = 0;
|
||||
*/
|
||||
|
||||
// Computed size in samples of the sine wave
|
||||
int waveLength = 1;
|
||||
|
||||
Vector2 position = { 0, 0 };
|
||||
|
||||
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
|
||||
SetTargetFPS(30);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
@ -108,91 +58,76 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePosition = GetMousePosition();
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
float fp = (float)(mousePosition.y);
|
||||
frequency = 40.0f + (float)(fp);
|
||||
newSineFrequency += 10;
|
||||
if (newSineFrequency > 12500) newSineFrequency = 12500;
|
||||
}
|
||||
|
||||
float pan = (float)(mousePosition.x)/(float)screenWidth;
|
||||
if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
newSineFrequency -= 10;
|
||||
if (newSineFrequency < 20) newSineFrequency = 20;
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_LEFT))
|
||||
{
|
||||
pan -= 0.01f;
|
||||
if (pan < -1.0f) pan = -1.0f;
|
||||
SetAudioStreamPan(stream, pan);
|
||||
}
|
||||
|
||||
// Rewrite the sine wave
|
||||
// Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc.
|
||||
if (frequency != oldFrequency)
|
||||
if (IsKeyDown(KEY_RIGHT))
|
||||
{
|
||||
// Compute wavelength. Limit size in both directions
|
||||
//int oldWavelength = waveLength;
|
||||
waveLength = (int)(22050/frequency);
|
||||
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
|
||||
if (waveLength < 1) waveLength = 1;
|
||||
|
||||
// Write sine wave
|
||||
for (int i = 0; i < waveLength*2; i++)
|
||||
{
|
||||
data[i] = (short)(sinf(((2*PI*(float)i/waveLength)))*32000);
|
||||
}
|
||||
// Make sure the rest of the line is flat
|
||||
for (int j = waveLength*2; j < MAX_SAMPLES; j++)
|
||||
{
|
||||
data[j] = (short)0;
|
||||
}
|
||||
|
||||
// Scale read cursor's position to minimize transition artifacts
|
||||
//readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
|
||||
oldFrequency = frequency;
|
||||
pan += 0.01f;
|
||||
if (pan > 1.0f) pan = 1.0f;
|
||||
SetAudioStreamPan(stream, pan);
|
||||
}
|
||||
|
||||
/*
|
||||
// Refill audio stream if required
|
||||
if (IsAudioStreamProcessed(stream))
|
||||
{
|
||||
// Synthesize a buffer that is exactly the requested size
|
||||
int writeCursor = 0;
|
||||
|
||||
while (writeCursor < MAX_SAMPLES_PER_UPDATE)
|
||||
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||
{
|
||||
// Start by trying to write the whole chunk at once
|
||||
int writeLength = MAX_SAMPLES_PER_UPDATE-writeCursor;
|
||||
int wavelength = SAMPLE_RATE/sineFrequency;
|
||||
buffer[i] = sin(2*PI*sineIndex/wavelength);
|
||||
sineIndex++;
|
||||
|
||||
// Limit to the maximum readable size
|
||||
int readLength = waveLength-readCursor;
|
||||
|
||||
if (writeLength > readLength) writeLength = readLength;
|
||||
|
||||
// Write the slice
|
||||
memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short));
|
||||
|
||||
// Update cursors and loop audio
|
||||
readCursor = (readCursor + writeLength)%waveLength;
|
||||
|
||||
writeCursor += writeLength;
|
||||
if (sineIndex >= wavelength)
|
||||
{
|
||||
sineFrequency = newSineFrequency;
|
||||
sineIndex = 0;
|
||||
sineStartTime = GetTime();
|
||||
}
|
||||
}
|
||||
|
||||
// Copy finished frame to audio stream
|
||||
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
|
||||
UpdateAudioStream(stream, buffer, BUFFER_SIZE);
|
||||
}
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText(TextFormat("sine frequency: %i",(int)frequency), GetScreenWidth() - 220, 10, 20, RED);
|
||||
DrawText("click mouse button to change frequency or pan", 10, 10, 20, DARKGRAY);
|
||||
DrawText(TextFormat("sine frequency: %i", sineFrequency), screenWidth - 220, 10, 20, RED);
|
||||
DrawText(TextFormat("pan: %.2f", pan), screenWidth - 220, 30, 20, RED);
|
||||
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
|
||||
DrawText("Left/right to pan", 10, 30, 20, DARKGRAY);
|
||||
|
||||
// Draw the current buffer state proportionate to the screen
|
||||
int windowStart = (GetTime() - sineStartTime)*SAMPLE_RATE;
|
||||
int windowSize = 0.1f*SAMPLE_RATE;
|
||||
int wavelength = SAMPLE_RATE/sineFrequency;
|
||||
|
||||
// Draw a sine wave with the same frequency as the one being sent to the audio stream
|
||||
for (int i = 0; i < screenWidth; i++)
|
||||
{
|
||||
position.x = (float)i;
|
||||
position.y = 250 + 50*data[i*MAX_SAMPLES/screenWidth]/32000.0f;
|
||||
|
||||
DrawPixelV(position, RED);
|
||||
int t0 = windowStart + i*windowSize/screenWidth;
|
||||
int t1 = windowStart + (i + 1)*windowSize/screenWidth;
|
||||
Vector2 startPos = { i, 250 + 50*sin(2*PI*t0/wavelength) };
|
||||
Vector2 endPos = { i + 1, 250 + 50*sin(2*PI*t1/wavelength) };
|
||||
DrawLineV(startPos, endPos, RED);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
@ -201,9 +136,6 @@ int main(void)
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
free(data); // Unload sine wave data
|
||||
free(writeBuf); // Unload write buffer
|
||||
|
||||
UnloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
|
||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Inspired by Inigo Quilez's https://www.shadertoy.com/
|
||||
* Resources/specification: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8
|
||||
@ -115,7 +115,7 @@ int main(void)
|
||||
.tapbackPos = 0.01f
|
||||
};
|
||||
|
||||
int wavCursor = 0;
|
||||
unsigned int wavCursor = 0;
|
||||
const short *wavPCM16 = wav.data;
|
||||
|
||||
short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 };
|
||||
@ -274,8 +274,8 @@ static void CaptureFrame(FFTData *fftData, const float *audioSamples)
|
||||
|
||||
static void RenderFrame(const FFTData *fftData, Image *fftImage)
|
||||
{
|
||||
double framesSinceTapback = floor(fftData->tapbackPos/WINDOW_TIME);
|
||||
framesSinceTapback = Clamp(framesSinceTapback, 0.0, fftData->fftHistoryLen - 1);
|
||||
float framesSinceTapback = floorf((float)(fftData->tapbackPos/WINDOW_TIME));
|
||||
framesSinceTapback = Clamp(framesSinceTapback, 0.0f, (float)(fftData->fftHistoryLen - 1));
|
||||
|
||||
int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback)%fftData->fftHistoryLen;
|
||||
if (historyPosition < 0) historyPosition += fftData->fftHistoryLen;
|
||||
|
||||
246
examples/audio/audio_stream_callback.c
Normal file
246
examples/audio/audio_stream_callback.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - stream callback
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example created by Dan Hoang (@dan-hoang) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* NOTE: Example sends a wave to the audio device,
|
||||
* user gets the choice of four waves: sine, square, triangle, and sawtooth
|
||||
* A stream is set up to play to the audio device; stream is hooked to a callback that
|
||||
* generates a wave, that is determined by user choice
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2026 Dan Hoang (@dan-hoang)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
#define SAMPLE_RATE 44100
|
||||
|
||||
// Wave type
|
||||
typedef enum {
|
||||
SINE,
|
||||
SQUARE,
|
||||
TRIANGLE,
|
||||
SAWTOOTH
|
||||
} WaveType;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static void SineCallback(void *framesOut, unsigned int frameCount);
|
||||
static void SquareCallback(void *framesOut, unsigned int frameCount);
|
||||
static void TriangleCallback(void *framesOut, unsigned int frameCount);
|
||||
static void SawtoothCallback(void *framesOut, unsigned int frameCount);
|
||||
|
||||
static int waveFrequency = 440;
|
||||
static int newWaveFrequency = 440;
|
||||
static int waveIndex = 0;
|
||||
|
||||
// Buffer to keep the last second of uploaded audio,
|
||||
// part of which will be drawn on the screen
|
||||
static float buffer[SAMPLE_RATE] = { 0 };
|
||||
static AudioCallback waveCallbacks[] = { SineCallback, SquareCallback, TriangleCallback, SawtoothCallback };
|
||||
static char *waveTypesAsString[] = { "sine", "square", "triangle", "sawtooth" };
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - stream callback");
|
||||
|
||||
InitAudioDevice();
|
||||
|
||||
// Set the number of samples the stream will keep in memory at a time to BUFFER_SIZE
|
||||
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
|
||||
|
||||
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
|
||||
AudioStream stream = LoadAudioStream(SAMPLE_RATE, 32, 1);
|
||||
PlayAudioStream(stream);
|
||||
|
||||
// Configure it so that waveCallbacks[waveType] is called whenever stream is out of samples
|
||||
WaveType waveType = SINE;
|
||||
SetAudioStreamCallback(stream, waveCallbacks[waveType]);
|
||||
|
||||
SetTargetFPS(30);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
newWaveFrequency += 10;
|
||||
if (newWaveFrequency > 12500) newWaveFrequency = 12500;
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
newWaveFrequency -= 10;
|
||||
if (newWaveFrequency < 20) newWaveFrequency = 20;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_LEFT))
|
||||
{
|
||||
if (waveType == SINE) waveType = SAWTOOTH;
|
||||
else if (waveType == SQUARE) waveType = SINE;
|
||||
else if (waveType == TRIANGLE) waveType = SQUARE;
|
||||
else waveType = TRIANGLE;
|
||||
|
||||
SetAudioStreamCallback(stream, waveCallbacks[waveType]);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_RIGHT))
|
||||
{
|
||||
if (waveType == SINE) waveType = SQUARE;
|
||||
else if (waveType == SQUARE) waveType = TRIANGLE;
|
||||
else if (waveType == TRIANGLE) waveType = SAWTOOTH;
|
||||
else waveType = SINE;
|
||||
|
||||
SetAudioStreamCallback(stream, waveCallbacks[waveType]);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
DrawText(TextFormat("frequency: %i", newWaveFrequency), screenWidth - 220, 10, 20, RED);
|
||||
DrawText(TextFormat("wave type: %s", waveTypesAsString[waveType]), screenWidth - 220, 30, 20, RED);
|
||||
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
|
||||
DrawText("Left/right to change wave type", 10, 30, 20, DARKGRAY);
|
||||
|
||||
// Draw the last 10 ms of uploaded audio
|
||||
for (int i = 0; i < screenWidth; i++)
|
||||
{
|
||||
Vector2 startPos = { i, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + i*SAMPLE_RATE/100/screenWidth] };
|
||||
Vector2 endPos = { i + 1, 250 - 50*buffer[SAMPLE_RATE - SAMPLE_RATE/100 + (i + 1)*SAMPLE_RATE/100/screenWidth] };
|
||||
DrawLineV(startPos, endPos, RED);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadAudioStream(stream); // Close raw audio stream and delete buffers from RAM
|
||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//------------------------------------------------------------------------------------
|
||||
static void SineCallback(void *framesOut, unsigned int frameCount)
|
||||
{
|
||||
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||
|
||||
// Synthesize the sine wave
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
((float *)framesOut)[i] = sin(2*PI*waveIndex/wavelength);
|
||||
|
||||
waveIndex++;
|
||||
|
||||
if (waveIndex >= wavelength)
|
||||
{
|
||||
waveFrequency = newWaveFrequency;
|
||||
waveIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the synthesized samples for later drawing
|
||||
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
}
|
||||
|
||||
static void SquareCallback(void *framesOut, unsigned int frameCount)
|
||||
{
|
||||
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||
|
||||
// Synthesize the square wave
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
((float *)framesOut)[i] = (waveIndex < wavelength/2)? 1 : -1;
|
||||
waveIndex++;
|
||||
|
||||
if (waveIndex >= wavelength)
|
||||
{
|
||||
waveFrequency = newWaveFrequency;
|
||||
waveIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the synthesized samples for later drawing
|
||||
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
}
|
||||
|
||||
static void TriangleCallback(void *framesOut, unsigned int frameCount)
|
||||
{
|
||||
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||
|
||||
// Synthesize the triangle wave
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
((float *)framesOut)[i] = (waveIndex < wavelength/2)? (-1 + 2.0f*waveIndex/(wavelength/2)) : (1 - 2.0f*(waveIndex - wavelength/2)/(wavelength/2));
|
||||
waveIndex++;
|
||||
|
||||
if (waveIndex >= wavelength)
|
||||
{
|
||||
waveFrequency = newWaveFrequency;
|
||||
waveIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the synthesized samples for later drawing
|
||||
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
}
|
||||
|
||||
static void SawtoothCallback(void *framesOut, unsigned int frameCount)
|
||||
{
|
||||
int wavelength = SAMPLE_RATE/waveFrequency;
|
||||
|
||||
// Synthesize the sawtooth wave
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
((float *)framesOut)[i] = -1 + 2.0f*waveIndex/wavelength;
|
||||
waveIndex++;
|
||||
|
||||
if (waveIndex >= wavelength)
|
||||
{
|
||||
waveFrequency = newWaveFrequency;
|
||||
waveIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the synthesized samples for later drawing
|
||||
for (int i = 0; i < SAMPLE_RATE - frameCount; i++) buffer[i] = buffer[i + frameCount];
|
||||
for (int i = 0; i < frameCount; i++) buffer[SAMPLE_RATE - frameCount + i] = ((float *)framesOut)[i];
|
||||
}
|
||||
BIN
examples/audio/audio_stream_callback.png
Normal file
BIN
examples/audio/audio_stream_callback.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
6051
examples/audio/raygui.h
Normal file
6051
examples/audio/raygui.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,15 +23,15 @@ void main()
|
||||
float localX = mod(fragCoord.x, cellWidth);
|
||||
float barWidth = cellWidth - 1.0;
|
||||
vec4 color = WHITE;
|
||||
|
||||
|
||||
if (localX <= barWidth)
|
||||
{
|
||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||
|
||||
|
||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||
}
|
||||
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
||||
@ -21,15 +21,15 @@ void main()
|
||||
float localX = mod(fragCoord.x, cellWidth);
|
||||
float barWidth = cellWidth - 1.0;
|
||||
vec4 color = WHITE;
|
||||
|
||||
|
||||
if (localX <= barWidth)
|
||||
{
|
||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||
|
||||
|
||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||
}
|
||||
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
||||
@ -21,15 +21,15 @@ void main()
|
||||
float localX = mod(fragCoord.x, cellWidth);
|
||||
float barWidth = cellWidth - 1.0;
|
||||
vec4 color = WHITE;
|
||||
|
||||
|
||||
if (localX <= barWidth)
|
||||
{
|
||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||
float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||
|
||||
|
||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||
}
|
||||
|
||||
|
||||
finalColor = color;
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Ananth S (@Ananth1839) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Ramon Santamaria (@raysan5) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
@ -73,7 +73,7 @@ int main(void)
|
||||
}
|
||||
|
||||
// Draw UI info
|
||||
DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
|
||||
DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
|
||||
GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY);
|
||||
DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY);
|
||||
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by ubkp (@ubkp) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* NOTE: raylib defined keys refer to ENG-US Keyboard layout,
|
||||
* NOTE: raylib defined keys refer to ENG-US Keyboard layout,
|
||||
* mapping to other layouts is up to the user
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
@ -43,20 +43,20 @@ int main(void)
|
||||
int line01KeyWidths[15] = { 0 };
|
||||
for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45;
|
||||
line01KeyWidths[13] = 62; // PRINTSCREEN
|
||||
int line01Keys[15] = {
|
||||
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
|
||||
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
|
||||
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
|
||||
int line01Keys[15] = {
|
||||
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
|
||||
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
|
||||
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
|
||||
};
|
||||
|
||||
|
||||
// Keyboard line 02
|
||||
int line02KeyWidths[15] = { 0 };
|
||||
for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45;
|
||||
line02KeyWidths[0] = 25; // GRAVE
|
||||
line02KeyWidths[13] = 82; // BACKSPACE
|
||||
int line02Keys[15] = {
|
||||
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
|
||||
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
|
||||
int line02Keys[15] = {
|
||||
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
|
||||
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
|
||||
KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE };
|
||||
|
||||
// Keyboard line 03
|
||||
@ -103,7 +103,7 @@ int main(void)
|
||||
KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL,
|
||||
KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT
|
||||
};
|
||||
|
||||
|
||||
Vector2 keyboardOffset = { 26, 80 };
|
||||
|
||||
SetTargetFPS(60);
|
||||
@ -128,28 +128,28 @@ int main(void)
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY);
|
||||
|
||||
|
||||
// Keyboard line 01 - 15 keys
|
||||
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
|
||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||
{
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, line01KeyWidths[i], 30 }, line01Keys[i]);
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, (float)line01KeyWidths[i], 30.0f }, line01Keys[i]);
|
||||
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
|
||||
}
|
||||
|
||||
|
||||
// Keyboard line 02 - 15 keys
|
||||
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
|
||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||
{
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, line02KeyWidths[i], 38 }, line02Keys[i]);
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, (float)line02KeyWidths[i], 38.0f }, line02Keys[i]);
|
||||
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
|
||||
}
|
||||
|
||||
|
||||
// Keyboard line 03 - 15 keys
|
||||
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
|
||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||
{
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38 + KEY_REC_SPACING*2, line03KeyWidths[i], 38 }, line03Keys[i]);
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38 + KEY_REC_SPACING*2, (float)line03KeyWidths[i], 38.0f }, line03Keys[i]);
|
||||
recOffsetX += line03KeyWidths[i] + KEY_REC_SPACING;
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ int main(void)
|
||||
// MAYUS, A, S, D, F, G, H, J, K, L, ;, ', ENTER, REPAG
|
||||
for (int i = 0, recOffsetX = 0; i < 14; i++)
|
||||
{
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*2 + KEY_REC_SPACING*3, line04KeyWidths[i], 38 }, line04Keys[i]);
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*2 + KEY_REC_SPACING*3, (float)line04KeyWidths[i], 38.0f }, line04Keys[i]);
|
||||
recOffsetX += line04KeyWidths[i] + KEY_REC_SPACING;
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ int main(void)
|
||||
// LSHIFT, Z, X, C, V, B, N, M, ,, ., /, RSHIFT, UP, AVPAG
|
||||
for (int i = 0, recOffsetX = 0; i < 14; i++)
|
||||
{
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*3 + KEY_REC_SPACING*4, line05KeyWidths[i], 38 }, line05Keys[i]);
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*3 + KEY_REC_SPACING*4, (float)line05KeyWidths[i], 38.0f }, line05Keys[i]);
|
||||
recOffsetX += line05KeyWidths[i] + KEY_REC_SPACING;
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ int main(void)
|
||||
// LCTRL, WIN, LALT, SPACE, ALTGR, \, FN, RCTRL, LEFT, DOWN, RIGHT
|
||||
for (int i = 0, recOffsetX = 0; i < 11; i++)
|
||||
{
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*4 + KEY_REC_SPACING*5, line06KeyWidths[i], 38 }, line06Keys[i]);
|
||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*4 + KEY_REC_SPACING*5, (float)line06KeyWidths[i], 38.0f }, line06Keys[i]);
|
||||
recOffsetX += line06KeyWidths[i] + KEY_REC_SPACING;
|
||||
}
|
||||
|
||||
@ -316,16 +316,16 @@ static void GuiKeyboardKey(Rectangle bounds, int key)
|
||||
if (IsKeyDown(key))
|
||||
{
|
||||
DrawRectangleLinesEx(bounds, 2.0f, MAROON);
|
||||
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, MAROON);
|
||||
DrawText(GetKeyText(key), (int)(bounds.x + 4), (int)(bounds.y + 4), 10, MAROON);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectangleLinesEx(bounds, 2.0f, DARKGRAY);
|
||||
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, DARKGRAY);
|
||||
DrawText(GetKeyText(key), (int)(bounds.x + 4), (int)(bounds.y + 4), 10, DARKGRAY);
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckCollisionPointRec(GetMousePosition(), bounds))
|
||||
|
||||
if (CheckCollisionPointRec(GetMousePosition(), bounds))
|
||||
{
|
||||
DrawRectangleRec(bounds, Fade(RED, 0.2f));
|
||||
DrawRectangleLinesEx(bounds, 3.0f, RED);
|
||||
|
||||
@ -111,7 +111,7 @@ int main(void)
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
free(rectangles);
|
||||
RL_FREE(rectangles);
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
|
||||
@ -646,6 +646,7 @@ typedef enum {
|
||||
// ProgressBar
|
||||
typedef enum {
|
||||
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
||||
PROGRESS_SIDE, // ProgressBar increment side: 0-left->right, 1-right-left
|
||||
} GuiProgressBarProperty;
|
||||
|
||||
// ScrollBar
|
||||
@ -3522,7 +3523,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
||||
}
|
||||
|
||||
// Draw slider internal progress bar (depends on state)
|
||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||
if (GuiGetStyle(PROGRESSBAR, PROGRESS_SIDE) == 0) // Left-->Right
|
||||
{
|
||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||
}
|
||||
else // Right-->Left
|
||||
{
|
||||
progress.x = bounds.x + bounds.width - progress.width - GuiGetStyle(PROGRESSBAR, BORDER_WIDTH);
|
||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw left/right text if provided
|
||||
@ -5119,11 +5128,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
||||
|
||||
// Get text divided into lines (by line-breaks '\n')
|
||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||
static char **GetTextLines(const char *text, int *count)
|
||||
static const char **GetTextLines(const char *text, int *count)
|
||||
{
|
||||
#define RAYGUI_MAX_TEXT_LINES 128
|
||||
|
||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||
|
||||
int textLength = (int)strlen(text);
|
||||
@ -5193,7 +5202,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||
int lineCount = 0;
|
||||
char **lines = GetTextLines(text, &lineCount);
|
||||
const char **lines = GetTextLines(text, &lineCount);
|
||||
|
||||
// Text style variables
|
||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||
|
||||
@ -10,14 +10,14 @@
|
||||
# This list is used as the main reference by [rexm] tool for examples collection validation and management
|
||||
#
|
||||
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||
core;core_delta_time;★☆☆☆;5.5;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
core;core_input_keys;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_input_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_gestures_testbed;★★★☆;5.0;6.0;2023;2025;"ubkp";@ubkp
|
||||
core;core_input_virtual_controls;★★☆☆;5.0;5.0;2024;2025;"GreenSnakeLinux";@GreenSnakeLinux
|
||||
core;core_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
|
||||
@ -46,16 +46,16 @@ core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessa
|
||||
core;core_random_sequence;★☆☆☆;5.0;5.0;2023;2025;"Dalton Overmyer";@REDl3east
|
||||
core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_highdpi_demo;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
|
||||
core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_render_texture;★☆☆☆;6.0;6.0;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||
core;core_input_actions;★★☆☆;5.5;5.6;2025;2025;"Jett";@JettMonstersGoBoom
|
||||
core;core_directory_files;★☆☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
|
||||
core;core_highdpi_testbed;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_screen_recording;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839
|
||||
core;core_highdpi_testbed;★☆☆☆;6.0;6.0;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_screen_recording;★★☆☆;6.0;6.0;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_clipboard_text;★★☆☆;6.0;6.0;2025;2025;"Ananth S";@Ananth1839
|
||||
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
|
||||
core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_compute_hash;★★☆☆;6.0;6.0;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
|
||||
core;core_window_web;★☆☆☆;1.3;5.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
|
||||
@ -71,7 +71,7 @@ shapes;shapes_following_eyes;★★☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@
|
||||
shapes;shapes_easings_ball;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||
shapes;shapes_easings_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_recursive_tree;★★★☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||
shapes;shapes_recursive_tree;★★★☆;6.0;6.0;2025;2025;"Jopestpe";@jopestpe
|
||||
shapes;shapes_ring_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
||||
shapes;shapes_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
|
||||
@ -81,23 +81,25 @@ shapes;shapes_splines_drawing;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";
|
||||
shapes;shapes_digital_clock;★★★★;5.5;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
||||
shapes;shapes_double_pendulum;★★☆☆;5.5;5.5;2025;2025;"JoeCheong";@Joecheong2006
|
||||
shapes;shapes_dashed_line;★☆☆☆;5.5;5.5;2025;2025;"Luís Almeida";@luis605
|
||||
shapes;shapes_triangle_strip;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||
shapes;shapes_triangle_strip;★★☆☆;6.0;6.0;2025;2025;"Jopestpe";@jopestpe
|
||||
shapes;shapes_vector_angle;★★☆☆;1.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
||||
shapes;shapes_pie_chart;★★★☆;5.5;5.6;2025;2025;"Gideon Serfontein";@GideonSerf
|
||||
shapes;shapes_kaleidoscope;★★☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
|
||||
shapes;shapes_clock_of_clocks;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
shapes;shapes_math_sine_cosine;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||
shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2025;2025;"Balamurugan R";@Bala050814
|
||||
shapes;shapes_clock_of_clocks;★★☆☆;5.5;6.0;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
shapes;shapes_math_sine_cosine;★★☆☆;6.0;6.0;2025;2025;"Jopestpe";@jopestpe
|
||||
shapes;shapes_mouse_trail;★☆☆☆;5.6;6.0;2025;2025;"Balamurugan R";@Bala050814
|
||||
shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
shapes;shapes_lines_drawing;★☆☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_math_angle_rotation;★☆☆☆;5.6-dev;5.6;2025;2025;"Kris";@krispy-snacc
|
||||
shapes;shapes_rlgl_color_wheel;★★★☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||
shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||
shapes;shapes_starfield_effect;★★☆☆;5.5;6.0;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
shapes;shapes_lines_drawing;★☆☆☆;6.0;5.6;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_math_angle_rotation;★☆☆☆;6.0;5.6;2025;2025;"Kris";@krispy-snacc
|
||||
shapes;shapes_rlgl_color_wheel;★★★☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_rlgl_triangle;★★☆☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_ball_physics;★★☆☆;6.0;6.0;2025;2025;"David Buzatto";@davidbuzatto
|
||||
shapes;shapes_penrose_tile;★★★★;5.5;6.0;2025;2025;"David Buzatto";@davidbuzatto
|
||||
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
||||
shapes;shapes_easings_testbed;★★★☆;2.5;2.5;2019;2025;"Juan Miguel López";@flashback-fx
|
||||
textures;textures_clipboard_image;★☆☆☆;6.0;6.0;2026;2026;"Maicon Santana";@maiconpintoabreu
|
||||
textures;textures_magnifying_glass;★★★☆;5.6;5.6;2026;2026;"Luke Vaughan";@badram
|
||||
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
||||
@ -125,7 +127,7 @@ textures;textures_image_channel;★★☆☆;5.5;5.5;2024;2025;"Bruno Cabral";@b
|
||||
textures;textures_image_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||
textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501
|
||||
textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
textures;textures_sprite_stacking;★★☆☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
textures;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes
|
||||
text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5
|
||||
@ -141,9 +143,9 @@ text;text_unicode_emojis;★★★★;2.5;4.0;2019;2025;"Vlad Adrian";@demizdor
|
||||
text;text_unicode_ranges;★★★★;5.5;5.6;2025;2025;"Vadim Gunko";@GuvaCode
|
||||
text;text_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
|
||||
text;text_words_alignment;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
text;text_strings_management;★★★☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||
text;text_inline_styling;★★★☆;6.0;6.0;2025;2025;"Wagner Barongello";@SultansOfCode
|
||||
text;text_words_alignment;★☆☆☆;6.0;6.0;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
text;text_strings_management;★★★☆;6.0;6.0;2025;2025;"David Buzatto";@davidbuzatto
|
||||
models;models_loading_iqm;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant
|
||||
models;models_billboard_rendering;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||
models;models_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||
@ -166,15 +168,15 @@ models;models_skybox_rendering;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria"
|
||||
models;models_textured_cube;★★☆☆;4.5;4.5;2022;2025;"Ramon Santamaria";@raysan5
|
||||
models;models_animation_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Holden";@orangeduck
|
||||
models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur
|
||||
models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz
|
||||
models;models_tesseract_view;★★☆☆;6.0;6.0;2024;2025;"Timothy van der Valk";@arceryz
|
||||
models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle
|
||||
models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||
models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
||||
models;models_animation_blend_custom;★★★★;5.5;5.5;2026;2026;"dmitrii-brand";@dmitrii-brand
|
||||
models;models_animation_blending;☆☆☆☆;5.5;5.6-dev;2024;2024;"Kirandeep";@Kirandeep-Singh-Khehra
|
||||
models;models_animation_timing;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
|
||||
shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
|
||||
models;models_rotating_cube;★☆☆☆;6.0;6.0;2025;2025;"Jopestpe";@jopestpe
|
||||
models;models_decals;★★★★;6.0;6.0;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
models;models_directional_billboard;★★☆☆;6.0;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
models;models_animation_blend_custom;★★★★;5.5;6.0;2026;2026;"dmitrii-brand";@dmitrii-brand
|
||||
models;models_animation_blending;★★★★;5.5;6.0;2024;2026;"Kirandeep";@Kirandeep-Singh-Khehra
|
||||
models;models_animation_timing;★★★☆;6.0;6.0;2026;2026;"Ramon Santamaria";@raysan5
|
||||
shaders;shaders_ascii_rendering;★★☆☆;5.5;6.0;2025;2025;"Maicon Santana";@maiconpintoabreu
|
||||
shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
|
||||
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
|
||||
shaders;shaders_shapes_textures;★★☆☆;1.7;3.7;2015;2025;"Ramon Santamaria";@raysan5
|
||||
@ -186,15 +188,15 @@ shaders;shaders_texture_rendering;★★☆☆;2.0;3.7;2019;2025;"Michał Ciesie
|
||||
shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff";@GoldenThumbs
|
||||
shaders;shaders_texture_waves;★★☆☆;2.5;3.7;2019;2025;"Anata";@anatagawa
|
||||
shaders;shaders_julia_set;★★★☆;2.5;4.0;2019;2025;"Josh Colclough";@joshcol9232
|
||||
shaders;shaders_mandelbrot_set;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
shaders;shaders_color_correction;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
shaders;shaders_mandelbrot_set;★★★☆;6.0;6.0;2025;2025;"Jordi Santonja";@JordSant
|
||||
shaders;shaders_color_correction;★★☆☆;6.0;6.0;2025;2025;"Jordi Santonja";@JordSant
|
||||
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_normalmap_rendering;★★★★;6.0;6.0;2025;2025;"Jeremy Montgomery";@Sir_Irk
|
||||
shaders;shaders_spotlight_rendering;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
||||
shaders;shaders_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
|
||||
@ -205,15 +207,17 @@ shaders;shaders_depth_writing;★★☆☆;4.2;4.2;2022;2025;"Buğra Alptekin Sa
|
||||
shaders;shaders_basic_pbr;★★★★;5.0;5.5;2023;2025;"Afan OLOVCIC";@_DevDad
|
||||
shaders;shaders_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
|
||||
shaders;shaders_game_of_life;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
shaders;shaders_depth_rendering;★★★☆;6.0;6.0;2025;2025;"Luís Almeida";@luis605
|
||||
shaders;shaders_game_of_life;★★★☆;6.0;6.0;2025;2025;"Jordi Santonja";@JordSant
|
||||
shaders;shaders_rlgl_compute;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
||||
shaders;shaders_cel_shading;★★★☆;6.0;6.0;2026;2026;"Gleb A";@ggrizzly
|
||||
audio;audio_module_playing;★☆☆☆;1.5;3.5;2016;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_music_stream;★☆☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_raw_stream;★★★☆;1.6;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_raw_stream;★★★☆;1.6;6.0;2015;2026;"Ramon Santamaria";@raysan5
|
||||
audio;audio_sound_loading;★☆☆☆;1.1;3.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_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
|
||||
audio;audio_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4
|
||||
audio;audio_spectrum_visualizer;★★★☆;6.0;6.0;2025;2025;"IANN";@meisei4
|
||||
audio;audio_stream_callback;★★★☆;6.0;6.0;2026;2026;"Dan Hoang";@dan-hoang
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by dmitrii-brand (@dmitrii-brand) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
@ -43,7 +43,7 @@
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static bool IsUpperBodyBone(const char *boneName);
|
||||
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim1, int frame1,
|
||||
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim1, int frame1,
|
||||
ModelAnimation *anim2, int frame2, float blend, bool upperBodyBlend);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -82,11 +82,11 @@ int main(void)
|
||||
ModelAnimation *anims = LoadModelAnimations("resources/models/gltf/greenman.glb", &animCount);
|
||||
|
||||
// Use specific animation indices: 2-walk/move, 3-attack
|
||||
unsigned int animIndex0 = 2; // Walk/Move animation (index 2)
|
||||
unsigned int animIndex1 = 3; // Attack animation (index 3)
|
||||
unsigned int animCurrentFrame0 = 0;
|
||||
unsigned int animCurrentFrame1 = 0;
|
||||
|
||||
int animIndex0 = 2; // Walk/Move animation (index 2)
|
||||
int animIndex1 = 3; // Attack animation (index 3)
|
||||
int animCurrentFrame0 = 0;
|
||||
int animCurrentFrame1 = 0;
|
||||
|
||||
// Validate indices
|
||||
if (animIndex0 >= animCount) animIndex0 = 0;
|
||||
if (animIndex1 >= animCount) animIndex1 = (animCount > 1) ? 1 : 0;
|
||||
@ -109,7 +109,7 @@ int main(void)
|
||||
// Update animation frames
|
||||
ModelAnimation anim0 = anims[animIndex0];
|
||||
ModelAnimation anim1 = anims[animIndex1];
|
||||
|
||||
|
||||
animCurrentFrame0 = (animCurrentFrame0 + 1)%anim0.keyframeCount;
|
||||
animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.keyframeCount;
|
||||
|
||||
@ -117,11 +117,11 @@ int main(void)
|
||||
// When upperBodyBlend is ON: upper body = attack (1.0), lower body = walk (0.0)
|
||||
// When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack)
|
||||
float blendFactor = (upperBodyBlend? 1.0f : 0.5f);
|
||||
UpdateModelAnimationBones(&model, &anim0, animCurrentFrame0,
|
||||
UpdateModelAnimationBones(&model, &anim0, animCurrentFrame0,
|
||||
&anim1, animCurrentFrame1, blendFactor, upperBodyBlend);
|
||||
|
||||
// raylib provided animation blending function
|
||||
//UpdateModelAnimationEx(model, anim0, (float)animCurrentFrame0,
|
||||
//UpdateModelAnimationEx(model, anim0, (float)animCurrentFrame0,
|
||||
// anim1, (float)animCurrentFrame1, blendFactor);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -142,8 +142,8 @@ int main(void)
|
||||
// Draw UI
|
||||
DrawText(TextFormat("ANIM 0: %s", anim0.name), 10, 10, 20, GRAY);
|
||||
DrawText(TextFormat("ANIM 1: %s", anim1.name), 10, 40, 20, GRAY);
|
||||
DrawText(TextFormat("[SPACE] Toggle blending mode: %s",
|
||||
upperBodyBlend? "Upper/Lower Body Blending" : "Uniform Blending"),
|
||||
DrawText(TextFormat("[SPACE] Toggle blending mode: %s",
|
||||
upperBodyBlend? "Upper/Lower Body Blending" : "Uniform Blending"),
|
||||
10, GetScreenHeight() - 30, 20, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
@ -180,7 +180,7 @@ static bool IsUpperBodyBone(const char *boneName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Check if bone name contains upper body keywords
|
||||
if (strstr(boneName, "spine") != NULL || strstr(boneName, "chest") != NULL ||
|
||||
strstr(boneName, "neck") != NULL || strstr(boneName, "head") != NULL ||
|
||||
@ -189,12 +189,12 @@ static bool IsUpperBodyBone(const char *boneName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Blend two animations per-bone with selective upper/lower body blending
|
||||
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int frame0,
|
||||
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int frame0,
|
||||
ModelAnimation *anim1, int frame1, float blend, bool upperBodyBlend)
|
||||
{
|
||||
// Validate inputs
|
||||
@ -204,59 +204,59 @@ static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int f
|
||||
{
|
||||
// Clamp blend factor to [0, 1]
|
||||
blend = fminf(1.0f, fmaxf(0.0f, blend));
|
||||
|
||||
|
||||
// Ensure frame indices are valid
|
||||
if (frame0 >= anim0->keyframeCount) frame0 = anim0->keyframeCount - 1;
|
||||
if (frame1 >= anim1->keyframeCount) frame1 = anim1->keyframeCount - 1;
|
||||
if (frame0 < 0) frame0 = 0;
|
||||
if (frame1 < 0) frame1 = 0;
|
||||
|
||||
|
||||
// Get bone count (use minimum of all to be safe)
|
||||
int boneCount = model->skeleton.boneCount;
|
||||
if (anim0->boneCount < boneCount) boneCount = anim0->boneCount;
|
||||
if (anim1->boneCount < boneCount) boneCount = anim1->boneCount;
|
||||
|
||||
|
||||
// Blend each bone
|
||||
for (int boneIndex = 0; boneIndex < boneCount; boneIndex++)
|
||||
{
|
||||
// Determine blend factor for this bone
|
||||
float boneBlendFactor = blend;
|
||||
|
||||
|
||||
// If upper body blending is enabled, use different blend factors for upper vs lower body
|
||||
if (upperBodyBlend)
|
||||
{
|
||||
const char *boneName = model->skeleton.bones[boneIndex].name;
|
||||
bool isUpperBody = IsUpperBodyBone(boneName);
|
||||
|
||||
|
||||
// Upper body: use anim1 (attack), Lower body: use anim0 (walk)
|
||||
// blend = 0.0 means full anim0 (walk), 1.0 means full anim1 (attack)
|
||||
if (isUpperBody) boneBlendFactor = blend; // Upper body: blend towards anim1 (attack)
|
||||
else boneBlendFactor = 1.0f - blend; // Lower body: blend towards anim0 (walk) - invert the blend
|
||||
}
|
||||
|
||||
|
||||
// Get transforms from both animations
|
||||
Transform *bindTransform = &model->skeleton.bindPose[boneIndex];
|
||||
Transform *animTransform0 = &anim0->keyframePoses[frame0][boneIndex];
|
||||
Transform *animTransform1 = &anim1->keyframePoses[frame1][boneIndex];
|
||||
|
||||
|
||||
// Blend the transforms
|
||||
Transform blended = { 0 };
|
||||
blended.translation = Vector3Lerp(animTransform0->translation, animTransform1->translation, boneBlendFactor);
|
||||
blended.rotation = QuaternionSlerp(animTransform0->rotation, animTransform1->rotation, boneBlendFactor);
|
||||
blended.scale = Vector3Lerp(animTransform0->scale, animTransform1->scale, boneBlendFactor);
|
||||
|
||||
|
||||
// Convert bind pose to matrix
|
||||
Matrix bindMatrix = MatrixMultiply(MatrixMultiply(
|
||||
MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z),
|
||||
QuaternionToMatrix(bindTransform->rotation)),
|
||||
MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z));
|
||||
|
||||
|
||||
// Convert blended transform to matrix
|
||||
Matrix blendedMatrix = MatrixMultiply(MatrixMultiply(
|
||||
MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z),
|
||||
QuaternionToMatrix(blended.rotation)),
|
||||
MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z));
|
||||
|
||||
|
||||
// Calculate final bone matrix (similar to UpdateModelAnimationBones)
|
||||
model->boneMatrices[boneIndex] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix);
|
||||
}
|
||||
@ -276,7 +276,7 @@ static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int f
|
||||
bool bufferUpdateRequired = false; // Flag to check when anim vertex information is updated
|
||||
|
||||
// Skip if missing bone data or missing anim buffers initialization
|
||||
if ((mesh.boneWeights == NULL) || (mesh.boneIndices == NULL) ||
|
||||
if ((mesh.boneWeights == NULL) || (mesh.boneIndices == NULL) ||
|
||||
(mesh.animVertices == NULL) || (mesh.animNormals == NULL)) continue;
|
||||
|
||||
for (int vCounter = 0; vCounter < vertexValuesCount; vCounter += 3)
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
* raylib [models] example - animation blending
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Kirandeep (@Kirandeep-Singh-Khehra) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
@ -57,7 +57,7 @@ int main(void)
|
||||
// WARNING: It requires SUPPORT_GPU_SKINNING enabled on raylib (disabled by default)
|
||||
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||
|
||||
|
||||
// Assign skinning shader to all materials shaders
|
||||
//for (int i = 0; i < model.materialCount; i++) model.materials[i].shader = skinningShader;
|
||||
|
||||
@ -105,7 +105,7 @@ int main(void)
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
|
||||
if (IsKeyPressed(KEY_P)) animPause = !animPause;
|
||||
|
||||
if (!animPause)
|
||||
@ -127,7 +127,7 @@ int main(void)
|
||||
}
|
||||
|
||||
// Set animation transition
|
||||
animTransition = true;
|
||||
animTransition = true;
|
||||
animBlendTimeCounter = 0.0f;
|
||||
animBlendFactor = 0.0f;
|
||||
}
|
||||
@ -182,7 +182,7 @@ int main(void)
|
||||
animCurrentFrame0 += animFrameSpeed0;
|
||||
if (animCurrentFrame0 >= anims[animIndex0].keyframeCount) animCurrentFrame0 = 0.0f;
|
||||
UpdateModelAnimation(model, anims[animIndex0], animCurrentFrame0);
|
||||
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
|
||||
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
|
||||
// anims[animIndex1], animCurrentFrame1, 0.0f); // Same as above, first animation frame blend
|
||||
}
|
||||
else if (currentAnimPlaying == 1)
|
||||
@ -191,7 +191,7 @@ int main(void)
|
||||
animCurrentFrame1 += animFrameSpeed1;
|
||||
if (animCurrentFrame1 >= anims[animIndex1].keyframeCount) animCurrentFrame1 = 0.0f;
|
||||
UpdateModelAnimation(model, anims[animIndex1], animCurrentFrame1);
|
||||
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
|
||||
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
|
||||
// anims[animIndex1], animCurrentFrame1, 1.0f); // Same as above, second animation frame blend
|
||||
}
|
||||
}
|
||||
@ -213,7 +213,7 @@ int main(void)
|
||||
DrawModel(model, position, 1.0f, WHITE); // Draw animated model
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
|
||||
EndMode3D();
|
||||
|
||||
if (animTransition) DrawText("ANIM TRANSITION BLENDING!", 170, 50, 30, BLUE);
|
||||
@ -221,18 +221,18 @@ int main(void)
|
||||
// Draw UI elements
|
||||
//---------------------------------------------------------------------------------------------
|
||||
if (dropdownEditMode0) GuiDisable();
|
||||
GuiSlider((Rectangle){ 10, 38, 160, 12 },
|
||||
GuiSlider((Rectangle){ 10, 38, 160, 12 },
|
||||
NULL, TextFormat("x%.1f", animFrameSpeed0), &animFrameSpeed0, 0.1f, 2.0f);
|
||||
GuiEnable();
|
||||
if (dropdownEditMode1) GuiDisable();
|
||||
GuiSlider((Rectangle){ GetScreenWidth() - 170.0f, 38, 160, 12 },
|
||||
GuiSlider((Rectangle){ GetScreenWidth() - 170.0f, 38, 160, 12 },
|
||||
TextFormat("%.1fx", animFrameSpeed1), NULL, &animFrameSpeed1, 0.1f, 2.0f);
|
||||
GuiEnable();
|
||||
|
||||
// Draw animation selectors for blending transition
|
||||
// NOTE: Transition does not start until requested
|
||||
// NOTE: Transition does not start until requested
|
||||
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 1);
|
||||
if (GuiDropdownBox((Rectangle){ 10, 10, 160, 24 }, TextJoin(animNames, animCount, ";"),
|
||||
if (GuiDropdownBox((Rectangle){ 10, 10, 160, 24 }, TextJoin(animNames, animCount, ";"),
|
||||
&animIndex0, dropdownEditMode0)) dropdownEditMode0 = !dropdownEditMode0;
|
||||
|
||||
// Blending process progress bar
|
||||
@ -249,7 +249,7 @@ int main(void)
|
||||
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
||||
&animFrameProgress0, 0.0f, (float)anims[animIndex0].keyframeCount);
|
||||
for (int i = 0; i < anims[animIndex0].keyframeCount; i++)
|
||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex0].keyframeCount)*(float)i),
|
||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex0].keyframeCount)*(float)i),
|
||||
GetScreenHeight() - 60, 1, 20, BLUE);
|
||||
|
||||
// Draw playing timeline with keyframes for anim1[]
|
||||
@ -257,7 +257,7 @@ int main(void)
|
||||
TextFormat("FRAME: %.2f / %i", animFrameProgress1, anims[animIndex1].keyframeCount),
|
||||
&animFrameProgress1, 0.0f, (float)anims[animIndex1].keyframeCount);
|
||||
for (int i = 0; i < anims[animIndex1].keyframeCount; i++)
|
||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
|
||||
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
|
||||
GetScreenHeight() - 30, 1, 20, BLUE);
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
||||
@ -270,7 +270,7 @@ int main(void)
|
||||
UnloadModelAnimations(anims, animCount); // Unload model animation
|
||||
UnloadModel(model); // Unload model and meshes/material
|
||||
UnloadShader(skinningShader); // Unload GPU skinning shader
|
||||
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
@ -94,26 +94,26 @@ int main(void)
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawModel(model, position, 1.0f, WHITE);
|
||||
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
|
||||
EndMode3D();
|
||||
|
||||
// Draw UI, select anim and playing speed
|
||||
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 1);
|
||||
if (GuiDropdownBox((Rectangle){ 10, 10, 140, 24 }, TextJoin(animNames, animCount, ";"),
|
||||
if (GuiDropdownBox((Rectangle){ 10, 10, 140, 24 }, TextJoin(animNames, animCount, ";"),
|
||||
&animIndex, dropdownEditMode)) dropdownEditMode = !dropdownEditMode;
|
||||
|
||||
GuiSlider((Rectangle){ 260, 10, 500, 24 }, "FRAME SPEED: ", TextFormat("x%.1f", animFrameSpeed),
|
||||
&animFrameSpeed, 0.1f, 2.0f);
|
||||
|
||||
// Draw playing timeline with keyframes
|
||||
GuiLabel((Rectangle){ 10, GetScreenHeight() - 64.0f, GetScreenWidth() - 20.0f, 24 },
|
||||
GuiLabel((Rectangle){ 10, GetScreenHeight() - 64.0f, GetScreenWidth() - 20.0f, 24 },
|
||||
TextFormat("CURRENT FRAME: %.2f / %i", animFrameProgress, anims[animIndex].keyframeCount));
|
||||
GuiProgressBar((Rectangle){ 10, GetScreenHeight() - 40.0f, GetScreenWidth() - 20.0f, 24 }, NULL, NULL,
|
||||
&animFrameProgress, 0.0f, (float)anims[animIndex].keyframeCount);
|
||||
for (int i = 0; i < anims[animIndex].keyframeCount; i++)
|
||||
DrawRectangle(10 + (int)(((float)(GetScreenWidth() - 20)/(float)anims[animIndex].keyframeCount)*(float)i),
|
||||
DrawRectangle(10 + (int)(((float)(GetScreenWidth() - 20)/(float)anims[animIndex].keyframeCount)*(float)i),
|
||||
GetScreenHeight() - 40, 1, 24, BLUE);
|
||||
|
||||
EndDrawing();
|
||||
|
||||
@ -60,7 +60,7 @@ int main(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -72,6 +72,7 @@ int main(void)
|
||||
UpdateCamera(&camera, CAMERA_FIRST_PERSON);
|
||||
|
||||
// Handle voxel removal with mouse click
|
||||
// This method is quite inefficient. Ray marching through the voxel grid using DDA would be faster, but more complex.
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
// Cast a ray from the screen center (where crosshair would be)
|
||||
@ -79,12 +80,14 @@ int main(void)
|
||||
Ray ray = GetMouseRay(screenCenter, camera);
|
||||
|
||||
// Check ray collision with all voxels
|
||||
bool voxelRemoved = false;
|
||||
for (int x = 0; (x < WORLD_SIZE) && !voxelRemoved; x++)
|
||||
float closestDistance = 99999.0f;
|
||||
Vector3 closestVoxelPosition = { -1, -1, -1 };
|
||||
bool voxelFound = false;
|
||||
for (int x = 0; x < WORLD_SIZE; x++)
|
||||
{
|
||||
for (int y = 0; (y < WORLD_SIZE) && !voxelRemoved; y++)
|
||||
for (int y = 0; y < WORLD_SIZE; y++)
|
||||
{
|
||||
for (int z = 0; (z < WORLD_SIZE) && !voxelRemoved; z++)
|
||||
for (int z = 0; z < WORLD_SIZE; z++)
|
||||
{
|
||||
if (!voxels[x][y][z]) continue; // Skip empty voxels
|
||||
|
||||
@ -97,14 +100,23 @@ int main(void)
|
||||
|
||||
// Check ray-box collision
|
||||
RayCollision collision = GetRayCollisionBox(ray, box);
|
||||
if (collision.hit)
|
||||
if (collision.hit && (collision.distance < closestDistance))
|
||||
{
|
||||
voxels[x][y][z] = false; // Remove this voxel
|
||||
voxelRemoved = true; // Exit all loops
|
||||
closestDistance = collision.distance;
|
||||
closestVoxelPosition = (Vector3){ x, y, z };
|
||||
voxelFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the closest voxel if one was hit
|
||||
if (voxelFound)
|
||||
{
|
||||
voxels[(int)closestVoxelPosition.x]
|
||||
[(int)closestVoxelPosition.y]
|
||||
[(int)closestVoxelPosition.z] = false;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -133,11 +145,11 @@ int main(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EndMode3D();
|
||||
|
||||
|
||||
// Draw reference point for raycasting to delete blocks
|
||||
DrawCircle(GetRenderWidth()/2, GetScreenHeight()/2, 4, RED);
|
||||
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 4, RED);
|
||||
|
||||
DrawText("Left-click a voxel to remove it!", 10, 10, 20, DARKGRAY);
|
||||
DrawText("WASD to move, mouse to look around", 10, 35, 10, GRAY);
|
||||
@ -149,7 +161,7 @@ int main(void)
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModel(cubeModel);
|
||||
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5)
|
||||
* Based on previous work by @mrdoob
|
||||
@ -108,7 +108,7 @@ int main(void)
|
||||
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
||||
|
||||
bool showModel = true;
|
||||
Model decalModels[MAX_DECALS] = { 0 };
|
||||
static Model decalModels[MAX_DECALS] = { 0 };
|
||||
int decalCount = 0;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "rlgl.h"
|
||||
|
||||
#include <stdlib.h> // Required for: rand()
|
||||
#include <math.h> // Required for: cosf(), sinf()
|
||||
@ -26,8 +27,9 @@
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
// Generate mesh using points
|
||||
static Mesh GenMeshPoints(int numPoints);
|
||||
static Mesh GenMeshPoints(int numPoints); // Generate mesh using points
|
||||
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points
|
||||
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
@ -184,3 +186,30 @@ static Mesh GenMeshPoints(int numPoints)
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
||||
// Draw a model points
|
||||
// WARNING: OpenGL ES 2.0 does not support point mode drawing
|
||||
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint)
|
||||
{
|
||||
rlEnablePointMode();
|
||||
rlDisableBackfaceCulling();
|
||||
|
||||
DrawModel(model, position, scale, tint);
|
||||
|
||||
rlEnableBackfaceCulling();
|
||||
rlDisablePointMode();
|
||||
}
|
||||
|
||||
// Draw a model points
|
||||
// WARNING: OpenGL ES 2.0 does not support point mode drawing
|
||||
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||
{
|
||||
rlEnablePointMode();
|
||||
rlDisableBackfaceCulling();
|
||||
|
||||
DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
|
||||
|
||||
rlEnableBackfaceCulling();
|
||||
rlDisablePointMode();
|
||||
}
|
||||
|
||||
@ -66,8 +66,6 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
earthRotation += (5.0f*rotationSpeed);
|
||||
earthOrbitRotation += (365/360.0f*(5.0f*rotationSpeed)*rotationSpeed);
|
||||
moonRotation += (2.0f*rotationSpeed);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Jopestpe (@jopestpe)
|
||||
*
|
||||
|
||||
@ -92,7 +92,7 @@ int main(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: WARNING: On PLATFORM_WEB it requires a big amount of memory to process input image
|
||||
// TODO: WARNING: On PLATFORM_WEB it requires a big amount of memory to process input image
|
||||
// and generate the required cubemap image to be passed to rlLoadTextureCubemap()
|
||||
Image image = LoadImage("resources/skybox.png");
|
||||
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Timothy van der Valk (@arceryz) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
|
||||
@ -41,6 +41,9 @@ int main(void)
|
||||
|
||||
Model model = LoadModel("resources/models/obj/plane.obj"); // Load model
|
||||
Texture2D texture = LoadTexture("resources/models/obj/plane_diffuse.png"); // Load model texture
|
||||
|
||||
SetTextureWrap(texture, TEXTURE_WRAP_REPEAT); // Force Repeat to avoid issue on Web version
|
||||
|
||||
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
|
||||
|
||||
float pitch = 0.0f;
|
||||
|
||||
@ -357,8 +357,10 @@
|
||||
#elif defined(USE_LIBTYPE_SHARED)
|
||||
#define RAYGUIAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll)
|
||||
#endif
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS // Disable unsafe warnings on scanf() functions in MSVC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Function specifiers definition
|
||||
#ifndef RAYGUIAPI
|
||||
|
||||
@ -13,9 +13,9 @@
|
||||
| models/vox/chr_knight.vox | ❔ | ❔ | - |
|
||||
| models/vox/chr_sword.vox | ❔ | ❔ | - |
|
||||
| models/vox/monu9.vox | ❔ | ❔ | - |
|
||||
| billboard.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||
| billboard.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||
| cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||
| cubicmap_atlas.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||
| cubicmap_atlas.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||
| heightmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||
| dresden_square_1k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
|
||||
| dresden_square_2k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
|
||||
|
||||
@ -14,7 +14,7 @@ void main()
|
||||
{
|
||||
// Fetch color from texture sampler
|
||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||
|
||||
|
||||
// Calculate final fragment color
|
||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ void main()
|
||||
int boneIndex1 = int(vertexBoneIndices.y);
|
||||
int boneIndex2 = int(vertexBoneIndices.z);
|
||||
int boneIndex3 = int(vertexBoneIndices.w);
|
||||
|
||||
|
||||
// WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
|
||||
mat4 boneMatrixTransposed0 = mat4(
|
||||
vec4(boneMatrices[boneIndex0][0].x, boneMatrices[boneIndex0][1].x, boneMatrices[boneIndex0][2].x, boneMatrices[boneIndex0][3].x),
|
||||
@ -45,13 +45,13 @@ void main()
|
||||
vec4(boneMatrices[boneIndex3][0].y, boneMatrices[boneIndex3][1].y, boneMatrices[boneIndex3][2].y, boneMatrices[boneIndex3][3].y),
|
||||
vec4(boneMatrices[boneIndex3][0].z, boneMatrices[boneIndex3][1].z, boneMatrices[boneIndex3][2].z, boneMatrices[boneIndex3][3].z),
|
||||
vec4(boneMatrices[boneIndex3][0].w, boneMatrices[boneIndex3][1].w, boneMatrices[boneIndex3][2].w, boneMatrices[boneIndex3][3].w));
|
||||
|
||||
|
||||
vec4 skinnedPosition =
|
||||
vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
|
||||
|
||||
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ void main()
|
||||
{
|
||||
// Fetch color from texture sampler
|
||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||
|
||||
|
||||
// Calculate final fragment color
|
||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ void main()
|
||||
int boneIndex1 = int(vertexBoneIndices.y);
|
||||
int boneIndex2 = int(vertexBoneIndices.z);
|
||||
int boneIndex3 = int(vertexBoneIndices.w);
|
||||
|
||||
|
||||
// WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
|
||||
mat4 boneMatrixTransposed0 = mat4(
|
||||
vec4(boneMatrices[boneIndex0][0].x, boneMatrices[boneIndex0][1].x, boneMatrices[boneIndex0][2].x, boneMatrices[boneIndex0][3].x),
|
||||
@ -45,13 +45,13 @@ void main()
|
||||
vec4(boneMatrices[boneIndex3][0].y, boneMatrices[boneIndex3][1].y, boneMatrices[boneIndex3][2].y, boneMatrices[boneIndex3][3].y),
|
||||
vec4(boneMatrices[boneIndex3][0].z, boneMatrices[boneIndex3][1].z, boneMatrices[boneIndex3][2].z, boneMatrices[boneIndex3][3].z),
|
||||
vec4(boneMatrices[boneIndex3][0].w, boneMatrices[boneIndex3][1].w, boneMatrices[boneIndex3][2].w, boneMatrices[boneIndex3][3].w));
|
||||
|
||||
|
||||
vec4 skinnedPosition =
|
||||
vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
|
||||
|
||||
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
|
||||
@ -26,17 +26,17 @@ void main()
|
||||
int boneIndex1 = int(vertexBoneIndices.y);
|
||||
int boneIndex2 = int(vertexBoneIndices.z);
|
||||
int boneIndex3 = int(vertexBoneIndices.w);
|
||||
|
||||
|
||||
vec4 skinnedPosition =
|
||||
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) +
|
||||
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexPosition, 1.0));
|
||||
|
||||
vec4 skinnedNormal =
|
||||
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexNormal, 0.0)) +
|
||||
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexNormal, 0.0)) +
|
||||
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexNormal, 0.0)) +
|
||||
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexNormal, 0.0)) +
|
||||
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexNormal, 0.0)) +
|
||||
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexNormal, 0.0));
|
||||
skinnedNormal.w = 0.0;
|
||||
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
#define GLAD_GLES2_IMPLEMENTATION
|
||||
#include "glad_gles2.h" // Required for: OpenGL functionality
|
||||
#define glGenVertexArrays glGenVertexArraysOES
|
||||
#define glBindVertexArray glBindVertexArrayOES
|
||||
|
||||
@ -646,6 +646,7 @@ typedef enum {
|
||||
// ProgressBar
|
||||
typedef enum {
|
||||
PROGRESS_PADDING = 16, // ProgressBar internal padding
|
||||
PROGRESS_SIDE, // ProgressBar increment side: 0-left->right, 1-right-left
|
||||
} GuiProgressBarProperty;
|
||||
|
||||
// ScrollBar
|
||||
@ -3522,7 +3523,15 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
|
||||
}
|
||||
|
||||
// Draw slider internal progress bar (depends on state)
|
||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||
if (GuiGetStyle(PROGRESSBAR, PROGRESS_SIDE) == 0) // Left-->Right
|
||||
{
|
||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||
}
|
||||
else // Right-->Left
|
||||
{
|
||||
progress.x = bounds.x + bounds.width - progress.width - GuiGetStyle(PROGRESSBAR, BORDER_WIDTH);
|
||||
GuiDrawRectangle(progress, 0, BLANK, GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw left/right text if provided
|
||||
@ -5119,11 +5128,11 @@ static const char *GetTextIcon(const char *text, int *iconId)
|
||||
|
||||
// Get text divided into lines (by line-breaks '\n')
|
||||
// WARNING: It returns pointers to new lines but it does not add NULL ('\0') terminator!
|
||||
static char **GetTextLines(const char *text, int *count)
|
||||
static const char **GetTextLines(const char *text, int *count)
|
||||
{
|
||||
#define RAYGUI_MAX_TEXT_LINES 128
|
||||
|
||||
static char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
|
||||
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
|
||||
|
||||
int textLength = (int)strlen(text);
|
||||
@ -5193,7 +5202,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
|
||||
// WARNING: GuiTextSplit() function can't be used now because it can have already been used
|
||||
// before the GuiDrawText() call and its buffer is static, it would be overriden :(
|
||||
int lineCount = 0;
|
||||
char **lines = GetTextLines(text, &lineCount);
|
||||
const char **lines = GetTextLines(text, &lineCount);
|
||||
|
||||
// Text style variables
|
||||
//int alignment = GuiGetStyle(DEFAULT, TEXT_ALIGNMENT);
|
||||
|
||||
@ -58,12 +58,12 @@ void main()
|
||||
float gray = GreyScale(cellColor);
|
||||
|
||||
float n = 4096.0;
|
||||
|
||||
|
||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||
if (gray > 0.2) n = 65600.0; // :
|
||||
if (gray > 0.3) n = 18725316.0; // v
|
||||
if (gray > 0.4) n = 15255086.0; // o
|
||||
if (gray > 0.4) n = 15255086.0; // o
|
||||
if (gray > 0.5) n = 13121101.0; // &
|
||||
if (gray > 0.6) n = 15252014.0; // 8
|
||||
if (gray > 0.7) n = 13195790.0; // @
|
||||
|
||||
58
examples/shaders/resources/shaders/glsl100/cel.fs
Normal file
58
examples/shaders/resources/shaders/glsl100/cel.fs
Normal file
@ -0,0 +1,58 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
varying vec3 fragNormal;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
uniform vec3 viewPos;
|
||||
uniform float numBands;
|
||||
|
||||
struct Light {
|
||||
int enabled;
|
||||
int type;
|
||||
vec3 position;
|
||||
vec3 target;
|
||||
vec4 color;
|
||||
};
|
||||
uniform Light lights[4];
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texColor = texture2D(texture0, fragTexCoord);
|
||||
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
|
||||
vec3 norm = normalize(fragNormal);
|
||||
|
||||
float lightAccum = 0.08; // ambient floor
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (lights[i].enabled == 1) // no continue in GLSL ES 1.0
|
||||
{
|
||||
vec3 lightDir;
|
||||
if (lights[i].type == 0)
|
||||
{
|
||||
// Directional: direction is from position toward target.
|
||||
lightDir = normalize(lights[i].position - lights[i].target);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Point: direction from surface to light.
|
||||
lightDir = normalize(lights[i].position - fragPosition);
|
||||
}
|
||||
|
||||
float NdotL = max(dot(norm, lightDir), 0.0);
|
||||
|
||||
// Quantize NdotL into numBands discrete steps.
|
||||
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
|
||||
lightAccum += quantized * lights[i].color.r;
|
||||
}
|
||||
}
|
||||
|
||||
lightAccum = clamp(lightAccum, 0.0, 1.0);
|
||||
gl_FragColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
|
||||
}
|
||||
47
examples/shaders/resources/shaders/glsl100/cel.vs
Normal file
47
examples/shaders/resources/shaders/glsl100/cel.vs
Normal file
@ -0,0 +1,47 @@
|
||||
#version 100
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
varying vec3 fragNormal;
|
||||
|
||||
mat3 inverse(mat3 m)
|
||||
{
|
||||
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||
float b01 = a22*a11 - a12*a21;
|
||||
float b11 = -a22*a10 + a12*a20;
|
||||
float b21 = a21*a10 - a11*a20;
|
||||
float det = a00*b01 + a01*b11 + a02*b21;
|
||||
return mat3(b01, (-a22*a01 + a02*a21), ( a12*a01 - a02*a11),
|
||||
b11, ( a22*a00 - a02*a20), (-a12*a00 + a02*a10),
|
||||
b21, (-a21*a00 + a01*a20), ( a11*a00 - a01*a10)) / det;
|
||||
}
|
||||
|
||||
mat3 transpose(mat3 m)
|
||||
{
|
||||
return mat3(m[0][0], m[1][0], m[2][0],
|
||||
m[0][1], m[1][1], m[2][1],
|
||||
m[0][2], m[1][2], m[2][2]);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
fragNormal = normalize(normalMatrix * vertexNormal);
|
||||
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
||||
@ -12,5 +12,5 @@ void main()
|
||||
fragTexCoord = vertexTexCoord;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = vec4(vertexPosition, 1.0);
|
||||
gl_Position = vec4(vertexPosition, 1.0);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#version 100
|
||||
#extension GL_EXT_frag_depth : enable
|
||||
#extension GL_EXT_frag_depth : enable
|
||||
|
||||
precision mediump float;
|
||||
|
||||
@ -14,7 +14,7 @@ uniform vec4 colDiffuse;
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||
|
||||
|
||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||
gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
|
||||
}
|
||||
|
||||
@ -24,13 +24,13 @@ void main()
|
||||
{
|
||||
// Store the fragment position vector in the first gbuffer texture
|
||||
//gPosition = fragPosition;
|
||||
|
||||
|
||||
// Store the per-fragment normals into the gbuffer
|
||||
//gNormal = normalize(fragNormal);
|
||||
|
||||
|
||||
// Store the diffuse per-fragment color
|
||||
gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
|
||||
|
||||
|
||||
// Store specular intensity in gAlbedoSpec's alpha component
|
||||
gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ void main()
|
||||
{
|
||||
// Calculate vertex attributes for fragment shader
|
||||
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
||||
fragPosition = worldPos.xyz;
|
||||
fragPosition = worldPos.xyz;
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#version 100
|
||||
|
||||
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
||||
|
||||
|
||||
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
@ -32,12 +32,12 @@ float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
|
||||
{
|
||||
p.x = abs(p.x);
|
||||
float l = length(p.xy);
|
||||
p.xy = mat2(-c.x, c.y,
|
||||
p.xy = mat2(-c.x, c.y,
|
||||
c.y, c.x)*p.xy;
|
||||
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
|
||||
(p.x>0.0)?p.y:l);
|
||||
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
|
||||
|
||||
|
||||
vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
|
||||
vec2 d = abs(q) - w;
|
||||
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
|
||||
@ -56,9 +56,9 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
|
||||
}
|
||||
|
||||
vec2 q = vec2(length(ap.yz), ap.x);
|
||||
|
||||
|
||||
float w = sqrt(r*r-h*h);
|
||||
|
||||
|
||||
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : abs(length(q)-r)) - t;
|
||||
}
|
||||
|
||||
@ -110,8 +110,8 @@ vec2 raycast(in vec3 ro, in vec3 rd)
|
||||
if (t>tmax) break;
|
||||
vec2 h = map(ro+rd*t);
|
||||
if (abs(h.x) < (0.0001*t))
|
||||
{
|
||||
res = vec2(t,h.y);
|
||||
{
|
||||
res = vec2(t,h.y);
|
||||
break;
|
||||
}
|
||||
t += h.x;
|
||||
@ -146,9 +146,9 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
|
||||
vec3 calcNormal(in vec3 pos)
|
||||
{
|
||||
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
|
||||
return normalize(e.xyy*map(pos + e.xyy).x +
|
||||
e.yyx*map(pos + e.yyx).x +
|
||||
e.yxy*map(pos + e.yxy).x +
|
||||
return normalize(e.xyy*map(pos + e.xyy).x +
|
||||
e.yyx*map(pos + e.yyx).x +
|
||||
e.yxy*map(pos + e.yxy).x +
|
||||
e.xxx*map(pos + e.xxx).x);
|
||||
}
|
||||
|
||||
@ -176,15 +176,15 @@ float checkersGradBox(in vec2 p)
|
||||
// analytical integral (box filter)
|
||||
vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
|
||||
// xor pattern
|
||||
return 0.5 - 0.5*i.x*i.y;
|
||||
return 0.5 - 0.5*i.x*i.y;
|
||||
}
|
||||
|
||||
// https://www.shadertoy.com/view/tdS3DG
|
||||
vec4 render(in vec3 ro, in vec3 rd)
|
||||
{
|
||||
{
|
||||
// background
|
||||
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
|
||||
|
||||
|
||||
// raycast scene
|
||||
vec2 res = raycast(ro,rd);
|
||||
float t = res.x;
|
||||
@ -194,11 +194,11 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
vec3 pos = ro + t*rd;
|
||||
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
||||
vec3 ref = reflect(rd, nor);
|
||||
|
||||
// material
|
||||
|
||||
// material
|
||||
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
||||
float ks = 1.0;
|
||||
|
||||
|
||||
if (m<1.5)
|
||||
{
|
||||
float f = checkersGradBox(3.0*pos.xz);
|
||||
@ -208,7 +208,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
|
||||
// lighting
|
||||
float occ = calcAO(pos, nor);
|
||||
|
||||
|
||||
vec3 lin = vec3(0.0);
|
||||
|
||||
// sun
|
||||
@ -249,7 +249,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
dif *= occ;
|
||||
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
|
||||
}
|
||||
|
||||
|
||||
col = lin;
|
||||
|
||||
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
|
||||
@ -289,7 +289,7 @@ void main()
|
||||
color = res.xyz;
|
||||
depth = CalcDepth(rd,res.w);
|
||||
}
|
||||
|
||||
|
||||
gl_FragColor = vec4(color , 1.0);
|
||||
gl_FragDepthEXT = depth;
|
||||
}
|
||||
@ -48,7 +48,7 @@ void main()
|
||||
float normR = float(iter - (iter/55)*55)/55.0;
|
||||
float normG = float(iter - (iter/69)*69)/69.0;
|
||||
float normB = float(iter - (iter/40)*40)/40.0;
|
||||
|
||||
|
||||
gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ void main()
|
||||
|
||||
float specCo = 0.0;
|
||||
|
||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
|
||||
|
||||
specular += specCo;
|
||||
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(0.05, 0.05, 0.05, 1.0);
|
||||
}
|
||||
15
examples/shaders/resources/shaders/glsl100/outline_hull.vs
Normal file
15
examples/shaders/resources/shaders/glsl100/outline_hull.vs
Normal file
@ -0,0 +1,15 @@
|
||||
#version 100
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform float outlineThickness;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 extruded = vertexPosition + vertexNormal * outlineThickness;
|
||||
gl_Position = mvp * vec4(extruded, 1.0);
|
||||
}
|
||||
@ -21,7 +21,7 @@ void main()
|
||||
// Convert the (normalized) texel color RED component (GB would work, too)
|
||||
// to the palette index by scaling up from [0..1] to [0..255]
|
||||
int index = int(texelColor.r*255.0);
|
||||
|
||||
|
||||
ivec3 color = ivec3(0);
|
||||
|
||||
// NOTE: On GLSL 100 we are not allowed to index a uniform array by a variable value,
|
||||
@ -34,7 +34,7 @@ void main()
|
||||
else if (index == 5) color = palette[5];
|
||||
else if (index == 6) color = palette[6];
|
||||
else if (index == 7) color = palette[7];
|
||||
|
||||
|
||||
//gl_FragColor = texture2D(palette, texelColor.xy); // Alternative to ivec3
|
||||
|
||||
// Calculate final fragment color. Note that the palette color components
|
||||
|
||||
@ -83,11 +83,11 @@ vec3 ComputePBR()
|
||||
{
|
||||
vec3 albedo = texture2D(albedoMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
|
||||
albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
|
||||
|
||||
|
||||
float metallic = clamp(metallicValue, 0.0, 1.0);
|
||||
float roughness = clamp(roughnessValue, 0.0, 1.0);
|
||||
float ao = clamp(aoValue, 0.0, 1.0);
|
||||
|
||||
|
||||
if (useTexMRA == 1)
|
||||
{
|
||||
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
|
||||
@ -132,18 +132,18 @@ vec3 ComputePBR()
|
||||
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
|
||||
|
||||
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
|
||||
|
||||
|
||||
// Difuse and spec light can't be above 1.0
|
||||
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
||||
vec3 kD = vec3(1.0) - F;
|
||||
|
||||
|
||||
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
|
||||
kD *= 1.0 - metallic;
|
||||
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result
|
||||
}
|
||||
|
||||
|
||||
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
|
||||
|
||||
|
||||
return (ambientFinal + lightAccum*ao + emissive);
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ void main()
|
||||
|
||||
// HDR tonemapping
|
||||
color = pow(color, color + vec3(1.0));
|
||||
|
||||
|
||||
// Gamma correction
|
||||
color = pow(color, vec3(1.0/2.2));
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ void main()
|
||||
float bias = max(0.0008*(1.0 - dot(normal, l)), 0.00008);
|
||||
int shadowCounter = 0;
|
||||
const int numSamples = 9;
|
||||
|
||||
|
||||
// PCF (percentage-closer filtering) algorithm:
|
||||
// Instead of testing if just one point is closer to the current point,
|
||||
// we test the surrounding points as well
|
||||
@ -74,7 +74,7 @@ void main()
|
||||
if (curDepth - bias > sampleDepth) shadowCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
|
||||
|
||||
// Add ambient lighting whether in shadow or not
|
||||
|
||||
@ -56,12 +56,12 @@ void main()
|
||||
float gray = GreyScale(cellColor);
|
||||
|
||||
float n = 4096.0;
|
||||
|
||||
|
||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||
if (gray > 0.2) n = 65600.0; // :
|
||||
if (gray > 0.3) n = 18725316.0; // v
|
||||
if (gray > 0.4) n = 15255086.0; // o
|
||||
if (gray > 0.4) n = 15255086.0; // o
|
||||
if (gray > 0.5) n = 13121101.0; // &
|
||||
if (gray > 0.6) n = 15252014.0; // 8
|
||||
if (gray > 0.7) n = 13195790.0; // @
|
||||
|
||||
56
examples/shaders/resources/shaders/glsl120/cel.fs
Normal file
56
examples/shaders/resources/shaders/glsl120/cel.fs
Normal file
@ -0,0 +1,56 @@
|
||||
#version 120
|
||||
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
varying vec3 fragNormal;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
uniform vec3 viewPos;
|
||||
uniform float numBands;
|
||||
|
||||
struct Light {
|
||||
int enabled;
|
||||
int type;
|
||||
vec3 position;
|
||||
vec3 target;
|
||||
vec4 color;
|
||||
};
|
||||
uniform Light lights[4];
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texColor = texture2D(texture0, fragTexCoord);
|
||||
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
|
||||
vec3 norm = normalize(fragNormal);
|
||||
|
||||
float lightAccum = 0.08; // ambient floor
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (lights[i].enabled == 1)
|
||||
{
|
||||
vec3 lightDir;
|
||||
if (lights[i].type == 0)
|
||||
{
|
||||
// Directional: direction is from position toward target.
|
||||
lightDir = normalize(lights[i].position - lights[i].target);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Point: direction from surface to light.
|
||||
lightDir = normalize(lights[i].position - fragPosition);
|
||||
}
|
||||
|
||||
float NdotL = max(dot(norm, lightDir), 0.0);
|
||||
|
||||
// Quantize NdotL into numBands discrete steps.
|
||||
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
|
||||
lightAccum += quantized * lights[i].color.r;
|
||||
}
|
||||
}
|
||||
|
||||
lightAccum = clamp(lightAccum, 0.0, 1.0);
|
||||
gl_FragColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
|
||||
}
|
||||
48
examples/shaders/resources/shaders/glsl120/cel.vs
Normal file
48
examples/shaders/resources/shaders/glsl120/cel.vs
Normal file
@ -0,0 +1,48 @@
|
||||
#version 120
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
varying vec3 fragNormal;
|
||||
|
||||
// inverse() and transpose() are not built-in until GLSL 1.40
|
||||
mat3 inverse(mat3 m)
|
||||
{
|
||||
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||
float b01 = a22*a11 - a12*a21;
|
||||
float b11 = -a22*a10 + a12*a20;
|
||||
float b21 = a21*a10 - a11*a20;
|
||||
float det = a00*b01 + a01*b11 + a02*b21;
|
||||
return mat3(b01, (-a22*a01 + a02*a21), ( a12*a01 - a02*a11),
|
||||
b11, ( a22*a00 - a02*a20), (-a12*a00 + a02*a10),
|
||||
b21, (-a21*a00 + a01*a20), ( a11*a00 - a01*a10)) / det;
|
||||
}
|
||||
|
||||
mat3 transpose(mat3 m)
|
||||
{
|
||||
return mat3(m[0][0], m[1][0], m[2][0],
|
||||
m[0][1], m[1][1], m[2][1],
|
||||
m[0][2], m[1][2], m[2][2]);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
fragNormal = normalize(normalMatrix * vertexNormal);
|
||||
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
||||
@ -12,5 +12,5 @@ void main()
|
||||
fragTexCoord = vertexTexCoord;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = vec4(vertexPosition, 1.0);
|
||||
gl_Position = vec4(vertexPosition, 1.0);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#version 120
|
||||
|
||||
#extension GL_EXT_frag_depth : enable
|
||||
#extension GL_EXT_frag_depth : enable
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||
|
||||
|
||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||
gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
|
||||
}
|
||||
@ -22,13 +22,13 @@ void main()
|
||||
{
|
||||
// Store the fragment position vector in the first gbuffer texture
|
||||
//gPosition = fragPosition;
|
||||
|
||||
|
||||
// Store the per-fragment normals into the gbuffer
|
||||
//gNormal = normalize(fragNormal);
|
||||
|
||||
|
||||
// Store the diffuse per-fragment color
|
||||
gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
|
||||
|
||||
|
||||
// Store specular intensity in gAlbedoSpec's alpha component
|
||||
gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ void main()
|
||||
{
|
||||
// Calculate vertex attributes for fragment shader
|
||||
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
||||
fragPosition = worldPos.xyz;
|
||||
fragPosition = worldPos.xyz;
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#version 120
|
||||
|
||||
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
||||
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
@ -30,12 +30,12 @@ float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
|
||||
{
|
||||
p.x = abs(p.x);
|
||||
float l = length(p.xy);
|
||||
p.xy = mat2(-c.x, c.y,
|
||||
p.xy = mat2(-c.x, c.y,
|
||||
c.y, c.x)*p.xy;
|
||||
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
|
||||
(p.x>0.0)?p.y:l);
|
||||
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
|
||||
|
||||
|
||||
vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
|
||||
vec2 d = abs(q) - w;
|
||||
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
|
||||
@ -54,9 +54,9 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
|
||||
}
|
||||
|
||||
vec2 q = vec2(length(ap.yz), ap.x);
|
||||
|
||||
|
||||
float w = sqrt(r*r-h*h);
|
||||
|
||||
|
||||
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : abs(length(q)-r)) - t;
|
||||
}
|
||||
|
||||
@ -108,8 +108,8 @@ vec2 raycast(in vec3 ro, in vec3 rd)
|
||||
if (t>tmax) break;
|
||||
vec2 h = map(ro+rd*t);
|
||||
if (abs(h.x) < (0.0001*t))
|
||||
{
|
||||
res = vec2(t,h.y);
|
||||
{
|
||||
res = vec2(t,h.y);
|
||||
break;
|
||||
}
|
||||
t += h.x;
|
||||
@ -144,9 +144,9 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
|
||||
vec3 calcNormal(in vec3 pos)
|
||||
{
|
||||
vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
|
||||
return normalize(e.xyy*map(pos + e.xyy).x +
|
||||
e.yyx*map(pos + e.yyx).x +
|
||||
e.yxy*map(pos + e.yxy).x +
|
||||
return normalize(e.xyy*map(pos + e.xyy).x +
|
||||
e.yyx*map(pos + e.yyx).x +
|
||||
e.yxy*map(pos + e.yxy).x +
|
||||
e.xxx*map(pos + e.xxx).x);
|
||||
}
|
||||
|
||||
@ -174,15 +174,15 @@ float checkersGradBox(in vec2 p)
|
||||
// analytical integral (box filter)
|
||||
vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
|
||||
// xor pattern
|
||||
return 0.5 - 0.5*i.x*i.y;
|
||||
return 0.5 - 0.5*i.x*i.y;
|
||||
}
|
||||
|
||||
// https://www.shadertoy.com/view/tdS3DG
|
||||
vec4 render(in vec3 ro, in vec3 rd)
|
||||
{
|
||||
{
|
||||
// background
|
||||
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
|
||||
|
||||
|
||||
// raycast scene
|
||||
vec2 res = raycast(ro,rd);
|
||||
float t = res.x;
|
||||
@ -192,11 +192,11 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
vec3 pos = ro + t*rd;
|
||||
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
||||
vec3 ref = reflect(rd, nor);
|
||||
|
||||
// material
|
||||
|
||||
// material
|
||||
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
||||
float ks = 1.0;
|
||||
|
||||
|
||||
if (m<1.5)
|
||||
{
|
||||
float f = checkersGradBox(3.0*pos.xz);
|
||||
@ -206,7 +206,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
|
||||
// lighting
|
||||
float occ = calcAO(pos, nor);
|
||||
|
||||
|
||||
vec3 lin = vec3(0.0);
|
||||
|
||||
// sun
|
||||
@ -247,7 +247,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
dif *= occ;
|
||||
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
|
||||
}
|
||||
|
||||
|
||||
col = lin;
|
||||
|
||||
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
|
||||
|
||||
@ -50,7 +50,7 @@ void main()
|
||||
|
||||
float specCo = 0.0;
|
||||
|
||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
|
||||
|
||||
specular += specCo;
|
||||
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
#version 120
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(0.05, 0.05, 0.05, 1.0);
|
||||
}
|
||||
15
examples/shaders/resources/shaders/glsl120/outline_hull.vs
Normal file
15
examples/shaders/resources/shaders/glsl120/outline_hull.vs
Normal file
@ -0,0 +1,15 @@
|
||||
#version 120
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform float outlineThickness;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 extruded = vertexPosition + vertexNormal * outlineThickness;
|
||||
gl_Position = mvp * vec4(extruded, 1.0);
|
||||
}
|
||||
@ -81,11 +81,11 @@ vec3 ComputePBR()
|
||||
{
|
||||
vec3 albedo = texture2D(albedoMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
|
||||
albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
|
||||
|
||||
|
||||
float metallic = clamp(metallicValue, 0.0, 1.0);
|
||||
float roughness = clamp(roughnessValue, 0.0, 1.0);
|
||||
float ao = clamp(aoValue, 0.0, 1.0);
|
||||
|
||||
|
||||
if (useTexMRA == 1)
|
||||
{
|
||||
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
|
||||
@ -130,18 +130,18 @@ vec3 ComputePBR()
|
||||
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
|
||||
|
||||
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
|
||||
|
||||
|
||||
// Difuse and spec light can't be above 1.0
|
||||
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
||||
vec3 kD = vec3(1.0) - F;
|
||||
|
||||
|
||||
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
|
||||
kD *= 1.0 - metallic;
|
||||
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result
|
||||
}
|
||||
|
||||
|
||||
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
|
||||
|
||||
|
||||
return (ambientFinal + lightAccum*ao + emissive);
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ void main()
|
||||
|
||||
// HDR tonemapping
|
||||
color = pow(color, color + vec3(1.0));
|
||||
|
||||
|
||||
// Gamma correction
|
||||
color = pow(color, vec3(1.0/2.2));
|
||||
|
||||
|
||||
@ -58,7 +58,7 @@ void main()
|
||||
float bias = max(0.0008*(1.0 - dot(normal, l)), 0.00008);
|
||||
int shadowCounter = 0;
|
||||
const int numSamples = 9;
|
||||
|
||||
|
||||
// PCF (percentage-closer filtering) algorithm:
|
||||
// Instead of testing if just one point is closer to the current point,
|
||||
// we test the surrounding points as well
|
||||
@ -72,7 +72,7 @@ void main()
|
||||
if (curDepth - bias > sampleDepth) shadowCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
|
||||
|
||||
// Add ambient lighting whether in shadow or not
|
||||
|
||||
@ -52,12 +52,12 @@ void main()
|
||||
float gray = GreyScale(cellColor);
|
||||
|
||||
int n = 4096;
|
||||
|
||||
|
||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||
if (gray > 0.2) n = 65600; // :
|
||||
if (gray > 0.3) n = 18725316; // v
|
||||
if (gray > 0.4) n = 15255086; // o
|
||||
if (gray > 0.4) n = 15255086; // o
|
||||
if (gray > 0.5) n = 13121101; // &
|
||||
if (gray > 0.6) n = 15252014; // 8
|
||||
if (gray > 0.7) n = 13195790; // @
|
||||
|
||||
@ -20,7 +20,7 @@ void main()
|
||||
|
||||
// NOTE: Implement here your fragment shader code
|
||||
|
||||
// final color is the color from the texture
|
||||
// final color is the color from the texture
|
||||
// times the tint color (colDiffuse)
|
||||
// times the fragment color (interpolated vertex color)
|
||||
finalColor = texelColor*colDiffuse*fragColor;
|
||||
|
||||
60
examples/shaders/resources/shaders/glsl330/cel.fs
Normal file
60
examples/shaders/resources/shaders/glsl330/cel.fs
Normal file
@ -0,0 +1,60 @@
|
||||
#version 330
|
||||
|
||||
in vec3 fragPosition;
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
in vec3 fragNormal;
|
||||
|
||||
// Raylib standard uniforms
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// View position for future specular / fresnel use.
|
||||
uniform vec3 viewPos;
|
||||
|
||||
// Number of discrete toon bands (2 = hard binary, 10 = default, 20 = near-smooth).
|
||||
uniform float numBands;
|
||||
|
||||
// rlights.h compatible light block.
|
||||
struct Light {
|
||||
int enabled;
|
||||
int type; // 0 = directional, 1 = point
|
||||
vec3 position;
|
||||
vec3 target;
|
||||
vec4 color;
|
||||
float attenuation;
|
||||
};
|
||||
uniform Light lights[4];
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
void main() {
|
||||
vec4 texColor = texture(texture0, fragTexCoord);
|
||||
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
|
||||
vec3 norm = normalize(fragNormal);
|
||||
|
||||
float lightAccum = 0.08; // ambient floor
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (lights[i].enabled == 0) continue;
|
||||
|
||||
vec3 lightDir;
|
||||
if (lights[i].type == 0) {
|
||||
// Directional: direction is from position toward target.
|
||||
lightDir = normalize(lights[i].position - lights[i].target);
|
||||
} else {
|
||||
// Point: direction from surface to light.
|
||||
lightDir = normalize(lights[i].position - fragPosition);
|
||||
}
|
||||
|
||||
float NdotL = max(dot(norm, lightDir), 0.0);
|
||||
|
||||
// Quantize NdotL into numBands discrete steps.
|
||||
// min() guards against NdotL == 1.0 producing an out-of-range index.
|
||||
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
|
||||
lightAccum += quantized * lights[i].color.r;
|
||||
}
|
||||
|
||||
lightAccum = clamp(lightAccum, 0.0, 1.0);
|
||||
finalColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
|
||||
}
|
||||
25
examples/shaders/resources/shaders/glsl330/cel.vs
Normal file
25
examples/shaders/resources/shaders/glsl330/cel.vs
Normal file
@ -0,0 +1,25 @@
|
||||
#version 330
|
||||
|
||||
// Raylib standard attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
in vec4 vertexColor;
|
||||
|
||||
// Raylib standard uniforms
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
uniform mat4 matNormal;
|
||||
|
||||
out vec3 fragPosition;
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
out vec3 fragNormal;
|
||||
|
||||
void main() {
|
||||
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 0.0)));
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
||||
@ -14,7 +14,7 @@ out vec4 finalColor;
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
|
||||
finalColor = texelColor*colDiffuse*fragColor;
|
||||
gl_FragDepth = 1.0 - finalColor.z;
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ struct Light {
|
||||
uniform Light lights[MAX_LIGHTS];
|
||||
uniform vec4 ambient;
|
||||
uniform vec3 viewPos;
|
||||
uniform vec4 fogColor;
|
||||
uniform float fogDensity;
|
||||
|
||||
void main()
|
||||
@ -77,10 +78,6 @@ void main()
|
||||
// Fog calculation
|
||||
float dist = length(viewPos - fragPosition);
|
||||
|
||||
// these could be parameters...
|
||||
const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);
|
||||
//const float fogDensity = 0.16;
|
||||
|
||||
// Exponential fog
|
||||
float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity));
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ uniform mat4 matProjection;
|
||||
void main()
|
||||
{
|
||||
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
||||
fragPosition = worldPos.xyz;
|
||||
fragPosition = worldPos.xyz;
|
||||
fragTexCoord = vertexTexCoord;
|
||||
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
|
||||
@ -16,7 +16,7 @@ out vec4 finalColor;
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
|
||||
finalColor = texelColor*colDiffuse*fragColor;
|
||||
gl_FragDepth = finalColor.z;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user