mirror of
https://github.com/raysan5/raylib.git
synced 2026-04-14 02:59:09 -04:00
Compare commits
92 Commits
8783e66e21
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 019cc889fc | |||
| 034ffda887 | |||
| 970531d112 | |||
| 99eaf72362 | |||
| 1339ec637e | |||
| 44e5126d08 | |||
| 51d693607e | |||
| a5427bc38f | |||
| 605303f62b | |||
| b3592631b0 | |||
| ddfbe973d4 | |||
| fe5271c568 | |||
| de95b3aa70 | |||
| fbcc8cdb55 | |||
| ca6f188233 | |||
| 8e54b19d9f | |||
| e24b01bb28 | |||
| 68d519910a | |||
| 53915d77e6 | |||
| b202421e08 | |||
| 05a14456ae | |||
| c5fc771622 | |||
| d3c6f426b4 | |||
| c4bd4faab5 | |||
| 4a6ceb9c76 | |||
| 6ef0044381 | |||
| 1122add3ee | |||
| 92f82b4add | |||
| cdff3d7bea | |||
| 138ef838d9 | |||
| 6ff51d3a2a | |||
| ea6292e27a | |||
| bb7b8d70e9 | |||
| f36533cbd8 | |||
| 5c2dee0862 | |||
| 12140cd444 | |||
| 3f7f040c7e | |||
| 4799cab772 | |||
| eb4f1a6da0 | |||
| 449182bb51 | |||
| 4ca9170f5b | |||
| 78797757f0 | |||
| a6dc9f9e92 | |||
| c7df641aa2 | |||
| 63beefd0de | |||
| b3bf537fab | |||
| 8743e11285 | |||
| 04f81538b7 | |||
| 8d70f1007b | |||
| 6c0134bb5c | |||
| e9231bc4f1 | |||
| 4c79c6837b | |||
| e5f0c9f8b1 | |||
| d5326fe880 | |||
| adc4c9b875 | |||
| b09da8fce8 | |||
| 0b87a35e5a | |||
| a1bf8d9c75 | |||
| d3cc78d9d7 | |||
| e3dcb144bc | |||
| da93ec4a21 | |||
| fb0f83bc91 | |||
| 29ded51ea4 | |||
| bb78e98a71 | |||
| 5915584cd6 | |||
| 8c44ea5032 | |||
| 5fad835ff1 | |||
| 4142c89baa | |||
| 990a5e0cb4 | |||
| 8a7aff509d | |||
| ba83bd33f3 | |||
| 98d6e24c44 | |||
| 51f4741912 | |||
| d7bd56ef1b | |||
| a693365bf2 | |||
| bd3a35ca21 | |||
| 0f0983c065 | |||
| 5dd4036ed0 | |||
| cb05ef7f03 | |||
| 52d2158f49 | |||
| 0f1e14a600 | |||
| 6cf71f565c | |||
| e71633a0be | |||
| ca1baca7c2 | |||
| 7e8aca00b6 | |||
| c1dbfc87f3 | |||
| 644e4adbe2 | |||
| 1e74aba7c3 | |||
| 83e35ba170 | |||
| 22cc2554b1 | |||
| 1b084ff9f2 | |||
| 8a685877eb |
18
.github/workflows/build_android.yml
vendored
18
.github/workflows/build_android.yml
vendored
@ -28,20 +28,20 @@ jobs:
|
|||||||
max-parallel: 1
|
max-parallel: 1
|
||||||
matrix:
|
matrix:
|
||||||
ARCH: ["arm64", "x86_64"]
|
ARCH: ["arm64", "x86_64"]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
RELEASE_NAME: raylib-dev_android_api29_${{ matrix.ARCH }}
|
RELEASE_NAME: raylib-dev_android_api29_${{ matrix.ARCH }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
|
|
||||||
- name: Setup Release Version
|
- name: Setup Release Version
|
||||||
run: |
|
run: |
|
||||||
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_android_api29_${{ matrix.ARCH }}" >> $GITHUB_ENV
|
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_android_api29_${{ matrix.ARCH }}" >> $GITHUB_ENV
|
||||||
shell: bash
|
shell: bash
|
||||||
if: github.event_name == 'release' && github.event.action == 'published'
|
if: github.event_name == 'release' && github.event.action == 'published'
|
||||||
|
|
||||||
- name: Setup Android NDK
|
- name: Setup Android NDK
|
||||||
id: setup-ndk
|
id: setup-ndk
|
||||||
uses: nttld/setup-ndk@v1
|
uses: nttld/setup-ndk@v1
|
||||||
@ -52,7 +52,7 @@ jobs:
|
|||||||
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||||
|
|
||||||
- name: Setup Environment
|
- name: Setup Environment
|
||||||
run: |
|
run: |
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
mkdir ${{ env.RELEASE_NAME }}
|
mkdir ${{ env.RELEASE_NAME }}
|
||||||
@ -60,7 +60,7 @@ jobs:
|
|||||||
mkdir include
|
mkdir include
|
||||||
mkdir lib
|
mkdir lib
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
# Generating static + shared library for 64bit arquitectures and API version 29
|
# Generating static + shared library for 64bit arquitectures and API version 29
|
||||||
- name: Build Library
|
- name: Build Library
|
||||||
run: |
|
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
|
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 ..
|
cd ..
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
||||||
- name: Generate Artifacts
|
- name: Generate Artifacts
|
||||||
run: |
|
run: |
|
||||||
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
||||||
@ -80,7 +80,7 @@ jobs:
|
|||||||
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
||||||
cd build
|
cd build
|
||||||
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
||||||
|
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@ -88,7 +88,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
./build/${{ env.RELEASE_NAME }}
|
./build/${{ env.RELEASE_NAME }}
|
||||||
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||||
|
|
||||||
- name: Upload Artifact to Release
|
- name: Upload Artifact to Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
8
.github/workflows/build_examples_linux.yml
vendored
8
.github/workflows/build_examples_linux.yml
vendored
@ -23,18 +23,18 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Environment
|
- name: Setup Environment
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update -qq
|
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
|
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
|
- name: Build Library
|
||||||
run: |
|
run: |
|
||||||
cd src
|
cd src
|
||||||
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC
|
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
- name: Build Examples
|
- name: Build Examples
|
||||||
run: |
|
run: |
|
||||||
cd examples
|
cd examples
|
||||||
|
|||||||
2
.github/workflows/build_examples_windows.yml
vendored
2
.github/workflows/build_examples_windows.yml
vendored
@ -13,7 +13,7 @@ on:
|
|||||||
- 'src/**'
|
- 'src/**'
|
||||||
- 'examples/**'
|
- 'examples/**'
|
||||||
- '.github/workflows/windows_examples.yml'
|
- '.github/workflows/windows_examples.yml'
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
|
|||||||
20
.github/workflows/build_linux.yml
vendored
20
.github/workflows/build_linux.yml
vendored
@ -42,23 +42,23 @@ jobs:
|
|||||||
ARCH_NAME: "arm64"
|
ARCH_NAME: "arm64"
|
||||||
COMPILER_PATH: "/usr/bin"
|
COMPILER_PATH: "/usr/bin"
|
||||||
runner: "ubuntu-24.04-arm"
|
runner: "ubuntu-24.04-arm"
|
||||||
|
|
||||||
runs-on: ${{ matrix.runner }}
|
runs-on: ${{ matrix.runner }}
|
||||||
env:
|
env:
|
||||||
RELEASE_NAME: raylib-dev_linux_${{ matrix.ARCH_NAME }}
|
RELEASE_NAME: raylib-dev_linux_${{ matrix.ARCH_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
|
|
||||||
- name: Setup Release Version
|
- name: Setup Release Version
|
||||||
run: |
|
run: |
|
||||||
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_linux_${{ matrix.ARCH_NAME }}" >> $GITHUB_ENV
|
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_linux_${{ matrix.ARCH_NAME }}" >> $GITHUB_ENV
|
||||||
shell: bash
|
shell: bash
|
||||||
if: github.event_name == 'release' && github.event.action == 'published'
|
if: github.event_name == 'release' && github.event.action == 'published'
|
||||||
|
|
||||||
- name: Setup Environment
|
- name: Setup Environment
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update -qq
|
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
|
sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxext-dev libxfixes-dev libwayland-dev libxkbcommon-dev
|
||||||
mkdir build
|
mkdir build
|
||||||
@ -74,7 +74,7 @@ jobs:
|
|||||||
run : |
|
run : |
|
||||||
sudo apt-get install gcc-multilib
|
sudo apt-get install gcc-multilib
|
||||||
if: matrix.bits == 32 && matrix.ARCH == 'i386'
|
if: matrix.bits == 32 && matrix.ARCH == 'i386'
|
||||||
|
|
||||||
# TODO: Support 32bit (i386) static/shared library building
|
# TODO: Support 32bit (i386) static/shared library building
|
||||||
- name: Build Library (32-bit)
|
- name: Build Library (32-bit)
|
||||||
run: |
|
run: |
|
||||||
@ -91,7 +91,7 @@ jobs:
|
|||||||
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
|
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
|
||||||
cd ..
|
cd ..
|
||||||
if: matrix.bits == 64 && matrix.ARCH == 'x86_64'
|
if: matrix.bits == 64 && matrix.ARCH == 'x86_64'
|
||||||
|
|
||||||
- name: Build Library (64-bit ARM)
|
- name: Build Library (64-bit ARM)
|
||||||
run: |
|
run: |
|
||||||
cd src
|
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
|
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
|
||||||
cd ..
|
cd ..
|
||||||
if: matrix.bits == 64 && matrix.ARCH == 'aarch64'
|
if: matrix.bits == 64 && matrix.ARCH == 'aarch64'
|
||||||
|
|
||||||
- name: Generate Artifacts
|
- name: Generate Artifacts
|
||||||
run: |
|
run: |
|
||||||
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
||||||
@ -110,7 +110,7 @@ jobs:
|
|||||||
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
||||||
cd build
|
cd build
|
||||||
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
||||||
|
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@ -118,7 +118,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
./build/${{ env.RELEASE_NAME }}
|
./build/${{ env.RELEASE_NAME }}
|
||||||
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||||
|
|
||||||
- name: Upload Artifact to Release
|
- name: Upload Artifact to Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
30
.github/workflows/build_macos.yml
vendored
30
.github/workflows/build_macos.yml
vendored
@ -23,14 +23,14 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write # for actions/upload-release-asset to upload release asset
|
contents: write # for actions/upload-release-asset to upload release asset
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
RELEASE_NAME: raylib-dev_macos
|
RELEASE_NAME: raylib-dev_macos
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
|
|
||||||
- name: Setup Release Version
|
- name: Setup Release Version
|
||||||
run: |
|
run: |
|
||||||
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_macos" >> $GITHUB_ENV
|
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'
|
if: github.event_name == 'release' && github.event.action == 'published'
|
||||||
|
|
||||||
- name: Setup Environment
|
- name: Setup Environment
|
||||||
run: |
|
run: |
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
mkdir ${{ env.RELEASE_NAME }}
|
mkdir ${{ env.RELEASE_NAME }}
|
||||||
@ -46,47 +46,47 @@ jobs:
|
|||||||
mkdir include
|
mkdir include
|
||||||
mkdir lib
|
mkdir lib
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
# Generating static + shared library, note that i386 architecture is deprecated
|
# Generating static + shared library, note that i386 architecture is deprecated
|
||||||
# Defining GL_SILENCE_DEPRECATION because OpenGL is deprecated on macOS
|
# Defining GL_SILENCE_DEPRECATION because OpenGL is deprecated on macOS
|
||||||
- name: Build Library
|
- name: Build Library
|
||||||
run: |
|
run: |
|
||||||
cd src
|
cd src
|
||||||
clang --version
|
clang --version
|
||||||
|
|
||||||
# Extract version numbers from Makefile
|
# Extract version numbers from Makefile
|
||||||
brew install grep
|
brew install grep
|
||||||
RAYLIB_API_VERSION=`ggrep -Po 'RAYLIB_API_VERSION\s*=\s\K(.*)' Makefile`
|
RAYLIB_API_VERSION=`ggrep -Po 'RAYLIB_API_VERSION\s*=\s\K(.*)' Makefile`
|
||||||
RAYLIB_VERSION=`ggrep -Po 'RAYLIB_VERSION\s*=\s\K(.*)' Makefile`
|
RAYLIB_VERSION=`ggrep -Po 'RAYLIB_VERSION\s*=\s\K(.*)' Makefile`
|
||||||
|
|
||||||
# Build raylib x86_64 static
|
# Build raylib x86_64 static
|
||||||
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=STATIC CUSTOM_CFLAGS="-target x86_64-apple-macos10.12 -DGL_SILENCE_DEPRECATION"
|
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
|
mv libraylib.a /tmp/libraylib_x86_64.a
|
||||||
make clean
|
make clean
|
||||||
|
|
||||||
# Build raylib arm64 static
|
# Build raylib arm64 static
|
||||||
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=STATIC CUSTOM_CFLAGS="-target arm64-apple-macos11 -DGL_SILENCE_DEPRECATION" -B
|
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=STATIC CUSTOM_CFLAGS="-target arm64-apple-macos11 -DGL_SILENCE_DEPRECATION" -B
|
||||||
mv libraylib.a /tmp/libraylib_arm64.a
|
mv libraylib.a /tmp/libraylib_arm64.a
|
||||||
make clean
|
make clean
|
||||||
|
|
||||||
# Join x86_64 and arm64 static
|
# 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
|
lipo -create -output ../build/${{ env.RELEASE_NAME }}/lib/libraylib.a /tmp/libraylib_x86_64.a /tmp/libraylib_arm64.a
|
||||||
|
|
||||||
# Build raylib x86_64 dynamic
|
# 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
|
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
|
mv libraylib.${RAYLIB_VERSION}.dylib /tmp/libraylib_x86_64.${RAYLIB_VERSION}.dylib
|
||||||
make clean
|
make clean
|
||||||
|
|
||||||
# Build raylib arm64 dynamic
|
# 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
|
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
|
mv libraylib.${RAYLIB_VERSION}.dylib /tmp/libraylib_arm64.${RAYLIB_VERSION}.dylib
|
||||||
|
|
||||||
# Join x86_64 and arm64 dynamic
|
# 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
|
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.dylib
|
||||||
ln -sv libraylib.${RAYLIB_VERSION}.dylib ../build/${{ env.RELEASE_NAME }}/lib/libraylib.${RAYLIB_API_VERSION}.dylib
|
ln -sv libraylib.${RAYLIB_VERSION}.dylib ../build/${{ env.RELEASE_NAME }}/lib/libraylib.${RAYLIB_API_VERSION}.dylib
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
- name: Generate Artifacts
|
- name: Generate Artifacts
|
||||||
run: |
|
run: |
|
||||||
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
|
||||||
@ -97,7 +97,7 @@ jobs:
|
|||||||
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
|
||||||
cd build
|
cd build
|
||||||
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
|
||||||
|
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@ -105,7 +105,7 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
./build/${{ env.RELEASE_NAME }}
|
./build/${{ env.RELEASE_NAME }}
|
||||||
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
!./build/${{ env.RELEASE_NAME }}.tar.gz
|
||||||
|
|
||||||
- name: Upload Artifact to Release
|
- name: Upload Artifact to Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
4
.github/workflows/update_examples.yml
vendored
4
.github/workflows/update_examples.yml
vendored
@ -12,11 +12,11 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup emsdk
|
- name: Setup emsdk
|
||||||
uses: mymindstorm/setup-emsdk@v14
|
uses: mymindstorm/setup-emsdk@v14
|
||||||
with:
|
with:
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -118,6 +118,7 @@ GTAGS
|
|||||||
# Zig programming language
|
# Zig programming language
|
||||||
.zig-cache/
|
.zig-cache/
|
||||||
zig-cache/
|
zig-cache/
|
||||||
|
zig-pkg/
|
||||||
zig-out/
|
zig-out/
|
||||||
build/
|
build/
|
||||||
build-*/
|
build-*/
|
||||||
|
|||||||
@ -6,7 +6,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||||||
|
|
||||||
| Name | raylib Version | Language | License |
|
| Name | raylib Version | Language | License |
|
||||||
| :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: |
|
| :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: |
|
||||||
| [raylib](https://github.com/raysan5/raylib) | **5.5** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
| [raylib](https://github.com/raysan5/raylib) | **6.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
||||||
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **5.5** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
|
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **5.5** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
|
||||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
|
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
|
||||||
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||||
@ -33,6 +33,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||||||
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||||
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
||||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 5.5 | [Factor](https://factorcode.org) | BSD |
|
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 5.5 | [Factor](https://factorcode.org) | BSD |
|
||||||
|
| [raylib4fb](https://github.com/mudhairless/raylib4fb) | **5.5** | [FreeBASIC](https://www.freebasic.net) | Zlib |
|
||||||
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
||||||
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
||||||
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
|
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
|
||||||
|
|||||||
62
CHANGELOG
62
CHANGELOG
@ -1,10 +1,10 @@
|
|||||||
changelog
|
changelog
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Current Release: raylib 5.5 (18 November 2024)
|
Current Release: raylib 6.0 (23 April 2026)
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
Release: raylib 6.0 (?? March 2026)
|
Release: raylib 6.0 (23 April 2026)
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
KEY CHANGES:
|
KEY CHANGES:
|
||||||
- New Software Renderer backend [rlsw]
|
- New Software Renderer backend [rlsw]
|
||||||
@ -21,11 +21,17 @@ KEY CHANGES:
|
|||||||
|
|
||||||
Detailed changes:
|
Detailed changes:
|
||||||
|
|
||||||
|
[rcore] ADDED: `FileRename()`, by @raysan5
|
||||||
|
[rcore] ADDED: `FileRemove()`, by @raysan5
|
||||||
|
[rcore] ADDED: `FileCopy()`, by @raysan5
|
||||||
|
[rcore] ADDED: `FileMove()`, by @raysan5
|
||||||
|
[rcore] ADDED: `FileTextReplace()`, by @raysan5
|
||||||
|
[rcore] ADDED: `FileTextFindIndex()`, by @raysan5
|
||||||
|
[rcore] ADDED: `ComputeSHA256()` (#5264) by @iamahuman1395
|
||||||
|
[rcore] ADDED: `GetKeyName()` (#4544) by @lecongsebastien
|
||||||
[rcore] ADDED: Logging and file-system functionality from `utils` (#4551) by @raysan5 -WARNING-
|
[rcore] ADDED: Logging and file-system functionality from `utils` (#4551) by @raysan5 -WARNING-
|
||||||
[rcore] ADDED: Flags set/clear macros: FLAG_SET, FLAG_CLEAR, FLAG_IS_SET (#5169) by @raysan5
|
[rcore] ADDED: Flags set/clear macros: FLAG_SET, FLAG_CLEAR, FLAG_IS_SET (#5169) by @raysan5
|
||||||
[rcore] ADDED: Warnings in case of no platform backend defined by @raysan5
|
[rcore] ADDED: Warnings in case of no platform backend defined by @raysan5
|
||||||
[rcore] ADDED: `ComputeSHA256()` (#5264) by @iamahuman1395
|
|
||||||
[rcore] ADDED: `GetKeyName()` (#4544) by @lecongsebastien
|
|
||||||
[rcore] REMOVED: GIF recording option, added example by @raysan5 -WARNING-
|
[rcore] REMOVED: GIF recording option, added example by @raysan5 -WARNING-
|
||||||
[rcore] REMOVED: `CORE.Window.fullscreen` variable, using available flag instead by @raysan5
|
[rcore] REMOVED: `CORE.Window.fullscreen` variable, using available flag instead by @raysan5
|
||||||
[rcore] REMOVED: `SetupFramebuffer()`, most platforms do not need it any more by @raysan5
|
[rcore] REMOVED: `SetupFramebuffer()`, most platforms do not need it any more by @raysan5
|
||||||
@ -111,7 +117,7 @@ Detailed changes:
|
|||||||
[rcore][RGFW] ADDED: New backend option: `PLATFORM_WEB_RGFW` and update RGFW (#4480) by @colleagueRiley
|
[rcore][RGFW] ADDED: New backend option: `PLATFORM_WEB_RGFW` and update RGFW (#4480) by @colleagueRiley
|
||||||
[rcore][RGFW] REVIEWED: Added missing Right Control key by @M374LX
|
[rcore][RGFW] REVIEWED: Added missing Right Control key by @M374LX
|
||||||
[rcore][RGFW] REVIEWED: Changed `RGFW_window_eventWait` timeout to -1 by @doggymangc
|
[rcore][RGFW] REVIEWED: Changed `RGFW_window_eventWait` timeout to -1 by @doggymangc
|
||||||
[rcore][RGFW] REVIEWED: Duplicate entries reemoved from `keyMappingRGFW` (#5242) by @iamahuman1395
|
[rcore][RGFW] REVIEWED: Duplicate entries removed from `keyMappingRGFW` (#5242) by @iamahuman1395
|
||||||
[rcore][RGFW] REVIEWED: Fix Escape always closing the window by @M374LX
|
[rcore][RGFW] REVIEWED: Fix Escape always closing the window by @M374LX
|
||||||
[rcore][RGFW] REVIEWED: Forward declare the windows stuff, prevents failures in GCC (#5269) by @Jeffm2501
|
[rcore][RGFW] REVIEWED: Forward declare the windows stuff, prevents failures in GCC (#5269) by @Jeffm2501
|
||||||
[rcore][RGFW] REVIEWED: Requires RGBA8 images as window icons (#5431) by @crisserpl2
|
[rcore][RGFW] REVIEWED: Requires RGBA8 images as window icons (#5431) by @crisserpl2
|
||||||
@ -198,7 +204,7 @@ Detailed changes:
|
|||||||
[rlgl] REVIEWED: `rlActiveDrawBuffers`, fix for OpenGL ES 3.0 (#4605) by @Bigfoot71
|
[rlgl] REVIEWED: `rlActiveDrawBuffers`, fix for OpenGL ES 3.0 (#4605) by @Bigfoot71
|
||||||
[rlgl] REVIEWED: `rlGetPixelDataSize()`, correct compressed data size calculation per blocks #5416 by @raysan5
|
[rlgl] REVIEWED: `rlGetPixelDataSize()`, correct compressed data size calculation per blocks #5416 by @raysan5
|
||||||
[rlgl] REVIEWED: `instranceTransform` shader location index #4538 (#4579) by @meadiode
|
[rlgl] REVIEWED: `instranceTransform` shader location index #4538 (#4579) by @meadiode
|
||||||
[rlgl] REVIEWED: `SetShaderValueTexture()`, updatee comments (#4703) by @pejorativefox
|
[rlgl] REVIEWED: `SetShaderValueTexture()`, update comments (#4703) by @pejorativefox
|
||||||
[rlgl] REDESIGNED: Avoid program crash if GPU data is tried to be loaded before `InitWindow()` #4751 by @raysan5 -WARNING-
|
[rlgl] REDESIGNED: Avoid program crash if GPU data is tried to be loaded before `InitWindow()` #4751 by @raysan5 -WARNING-
|
||||||
[rlgl] REDESIGNED: Shader loading API function names for more consistency #5631 by @raysan5 -WARNING-
|
[rlgl] REDESIGNED: Shader loading API function names for more consistency #5631 by @raysan5 -WARNING-
|
||||||
[rlsw] ADDED: `swGetColorBuffer()` for convenience by @raysan5
|
[rlsw] ADDED: `swGetColorBuffer()` for convenience by @raysan5
|
||||||
@ -215,6 +221,7 @@ Detailed changes:
|
|||||||
[rlsw] REVIEWED: C++ support (#5291) by @alexgb0
|
[rlsw] REVIEWED: C++ support (#5291) by @alexgb0
|
||||||
[rshapes] ADDED: `DrawLineDashed()` (#5222) by @luis605
|
[rshapes] ADDED: `DrawLineDashed()` (#5222) by @luis605
|
||||||
[rshapes] ADDED: `DrawEllipseV()` and `DrawEllipseLinesV()` (#4963) by @meowstr
|
[rshapes] ADDED: `DrawEllipseV()` and `DrawEllipseLinesV()` (#4963) by @meowstr
|
||||||
|
[rshapes] REDESIGNED: `DrawCircleGradient()` to use Vector2 as center parameter by @raysan5 -WARNING-
|
||||||
[rshapes] REVIEWED: `DrawLine()`, fix pixel offset issue on drawing (#4666) by @Bigfoot71
|
[rshapes] REVIEWED: `DrawLine()`, fix pixel offset issue on drawing (#4666) by @Bigfoot71
|
||||||
[rshapes] REVIEWED: `DrawRectangleGradientEx()`, incorrect parameter names (#4980) by @vincent
|
[rshapes] REVIEWED: `DrawRectangleGradientEx()`, incorrect parameter names (#4980) by @vincent
|
||||||
[rshapes] REVIEWED: `DrawRectangleLines`, fix pixel offset issue (#4669) by @Bigfoot71
|
[rshapes] REVIEWED: `DrawRectangleLines`, fix pixel offset issue (#4669) by @Bigfoot71
|
||||||
@ -239,6 +246,13 @@ Detailed changes:
|
|||||||
[rtextures] REVIEWED: `ImageDrawLineEx(), to be able to draw even numbered thicknesses (#5042) by @Sir-Irk
|
[rtextures] REVIEWED: `ImageDrawLineEx(), to be able to draw even numbered thicknesses (#5042) by @Sir-Irk
|
||||||
[rtextures] REVIEWED: `ImageBlurGaussian()`, fix integer overflow in cast (#5037) by @garrisonhh
|
[rtextures] REVIEWED: `ImageBlurGaussian()`, fix integer overflow in cast (#5037) by @garrisonhh
|
||||||
[rtext] ADDED: `LoadTextLines()`/`UnloadTextLines()` by @raysan5
|
[rtext] ADDED: `LoadTextLines()`/`UnloadTextLines()` by @raysan5
|
||||||
|
[rtext] ADDED: `TextInsertAlloc()`, returns memory allocated string by @raysan5
|
||||||
|
[rtext] ADDED: `TextReplace()`, using static buffer by @raysan5
|
||||||
|
[rtext] ADDED: `TextReplaceAlloc()`, returns memory allocated string by @raysan5
|
||||||
|
[rtext] ADDED: `TextReplaceBetween()`, using static buffer by @raysan5
|
||||||
|
[rtext] ADDED: `TextReplaceBetweenAlloc()`, returns memory allocated string by @raysan5
|
||||||
|
[rtext] ADDED: `GetTextBetween()`, using static buffer by @raysan5
|
||||||
|
[rtext] ADDED: `TextRemoveSpaces()`, using static buffer by @raysan5
|
||||||
[rtext] ADDED: `MeasureTextCodepoints()` for direct measurement of codepoints (#5623) by @creeperblin
|
[rtext] ADDED: `MeasureTextCodepoints()` for direct measurement of codepoints (#5623) by @creeperblin
|
||||||
[rtext] RENAMED: Variable names for consistency, `textLength` (length in bytes) vs `textSize` (measure in pixels) by @raysan5
|
[rtext] RENAMED: Variable names for consistency, `textLength` (length in bytes) vs `textSize` (measure in pixels) by @raysan5
|
||||||
[rtext] REVIEWED: Support default font loading with no GPU enabled, to be used with Image API
|
[rtext] REVIEWED: Support default font loading with no GPU enabled, to be used with Image API
|
||||||
@ -263,16 +277,16 @@ Detailed changes:
|
|||||||
[rtext] REVIEWED: `GetCodepointCount()`, misuse of cast (#4741) by @sleeptightAnsiC
|
[rtext] REVIEWED: `GetCodepointCount()`, misuse of cast (#4741) by @sleeptightAnsiC
|
||||||
[rtext] REVIEWED: `GenImageFontAtlas()`, memory corruption and invalid size calculation (#5602) by @konakona418
|
[rtext] REVIEWED: `GenImageFontAtlas()`, memory corruption and invalid size calculation (#5602) by @konakona418
|
||||||
[rtext] REVIEWED: `TextInsert()`, fix bug on insertion (#5644) by @CrackedPixel
|
[rtext] REVIEWED: `TextInsert()`, fix bug on insertion (#5644) by @CrackedPixel
|
||||||
|
[rtext] REVIEWED: `TextInsert()`, use static buffer, easier to use by @raysan5 -WARNING-
|
||||||
[rtext] REVIEWED: `TextJoin()`, convert `const char **` to `char**` by @raysan5
|
[rtext] REVIEWED: `TextJoin()`, convert `const char **` to `char**` by @raysan5
|
||||||
[rtext] REVIEWED: `TextReplace()` and `TextLength()`, avoid using `strcpy()` by @raysan5
|
|
||||||
[rtext] REVIEWED: `TextReplace()` by @raysan5
|
|
||||||
[rtext] REVIEWED: `TextReplace()`, improvements (#5511) by @belan2470
|
[rtext] REVIEWED: `TextReplace()`, improvements (#5511) by @belan2470
|
||||||
[rtext] REVIEWED: `TextReplaceBetween()` by @raysan5
|
[rtext] REVIEWED: `TextReplace()` and `TextLength()`, avoid using `strcpy()` by @raysan5
|
||||||
[rtext] REVIEWED: `TextSubtext(), fixes (#4759) by @veins1
|
[rtext] REVIEWED: `TextSubtext(), fixes (#4759) by @veins1
|
||||||
[rtext] REVIEWED: `TextToPascal()`, fix issue by @raysan5
|
[rtext] REVIEWED: `TextToPascal()`, fix issue by @raysan5
|
||||||
[rtext] REVIEWED: `TextToFloat()`, remove removed inaccurate comment (#4596) by @hexmaster111
|
[rtext] REVIEWED: `TextToFloat()`, remove removed inaccurate comment (#4596) by @hexmaster111
|
||||||
[rtext] REDESIGNED: `LoadFontData()`, added input parameter by @raysan5 -WARNING-
|
[rtext] REDESIGNED: `LoadFontData()`, added input parameter by @raysan5 -WARNING-
|
||||||
[rmodels] ADDED: Support CPU animation in OpenGL 1.1 (#4925) by @JeffM2501
|
[rmodels] ADDED: Support CPU animation in OpenGL 1.1 (#4925) by @JeffM2501
|
||||||
|
[rmodels] REMOVED: `DrawModelPoints()` and `DrawModelPointsEx()`, moved to an example (#5697) by @maiconpintoabreu -WARNING-
|
||||||
[rmodels] RENAMED: Skinning shader variables (new default naming) by @raysan5
|
[rmodels] RENAMED: Skinning shader variables (new default naming) by @raysan5
|
||||||
[rmodels] REVIEWED: glTF animation framerate calculation (#4472, #5445) by @TheLazyIndianTechie
|
[rmodels] REVIEWED: glTF animation framerate calculation (#4472, #5445) by @TheLazyIndianTechie
|
||||||
[rmodels] REVIEWED: Assign meshes without bone weights to the bone they are attached to so they animate by @Jeffm2501
|
[rmodels] REVIEWED: Assign meshes without bone weights to the bone they are attached to so they animate by @Jeffm2501
|
||||||
@ -299,6 +313,7 @@ Detailed changes:
|
|||||||
[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, properly load 1 frame animations (#5561) by @arlez80
|
[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, properly load 1 frame animations (#5561) by @arlez80
|
||||||
[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, anim correctly inherits world transform (#5206) by @ArmanOmmid
|
[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, anim correctly inherits world transform (#5206) by @ArmanOmmid
|
||||||
[rmodels] REVIEWED: `UploadMesh()`, improve default normal and tangent values (#4763) by @Bigfoot71
|
[rmodels] REVIEWED: `UploadMesh()`, improve default normal and tangent values (#4763) by @Bigfoot71
|
||||||
|
[rmodels] REVIEWED: `UplaodMesh()`, fix for devices without VAO support (#5692) by @psxdev
|
||||||
[rmodels] REVIEWED: `GenMeshTangents()`, improvements (#4937) by @Bigfoot71
|
[rmodels] REVIEWED: `GenMeshTangents()`, improvements (#4937) by @Bigfoot71
|
||||||
[rmodels] REVIEWED: `UpdateModelAnimation()` optimization (#5244) by @Arrangemonk
|
[rmodels] REVIEWED: `UpdateModelAnimation()` optimization (#5244) by @Arrangemonk
|
||||||
[rmodels] REVIEWED: `UpdateModelAnimationBones()`, break on first mesh found and formating by @raysan5
|
[rmodels] REVIEWED: `UpdateModelAnimationBones()`, break on first mesh found and formating by @raysan5
|
||||||
@ -310,6 +325,7 @@ Detailed changes:
|
|||||||
[rmodels] REVIEWED: `DrawMeshInstanced()`, breaking if instanceTransform was unused (#5469) by @al13n321
|
[rmodels] REVIEWED: `DrawMeshInstanced()`, breaking if instanceTransform was unused (#5469) by @al13n321
|
||||||
[rmodels] REVIEWED: `DrawSphereEx()`, normals support (#4926) by @karl-zylinski
|
[rmodels] REVIEWED: `DrawSphereEx()`, normals support (#4926) by @karl-zylinski
|
||||||
[rmodels] REVIEWED: `ExportMesh()`, improve OBJ vertex data precision and lower memory usage (#4496) by @mikeemm
|
[rmodels] REVIEWED: `ExportMesh()`, improve OBJ vertex data precision and lower memory usage (#4496) by @mikeemm
|
||||||
|
[rmodels] REVIEWED: `CheckCollisionSpheres()`, simplified using `Vector3DistanceSqr()` (#5695) by @Bigfoot71
|
||||||
[raudio] REVIEWED: Fix a glitch at the end of a sound (#5578) by @mackron
|
[raudio] REVIEWED: Fix a glitch at the end of a sound (#5578) by @mackron
|
||||||
[raudio] REVIEWED: Improvements to device configuration (#5577) by @mackron
|
[raudio] REVIEWED: Improvements to device configuration (#5577) by @mackron
|
||||||
[raudio] REVIEWED: Initialize sound alias properties as if it was a new sound (#5123) by @JeffM2501
|
[raudio] REVIEWED: Initialize sound alias properties as if it was a new sound (#5123) by @JeffM2501
|
||||||
@ -735,7 +751,7 @@ Detailed changes:
|
|||||||
[rexm] REVIEWED: `ScanExampleResources()` avoid resources to be saved by the program by @raysan5
|
[rexm] REVIEWED: `ScanExampleResources()` avoid resources to be saved by the program by @raysan5
|
||||||
[rexm] REVIEWED: `UpdateSourceMetadata()` and `TextReplaceBetween()` by @raysan5
|
[rexm] REVIEWED: `UpdateSourceMetadata()` and `TextReplaceBetween()` by @raysan5
|
||||||
[rexm] REVIEWED: `examples.js` example addition working by @raysan5
|
[rexm] REVIEWED: `examples.js` example addition working by @raysan5
|
||||||
[rexm] REVIEWED: `add` command logic for existing examplee addition by @raysan5
|
[rexm] REVIEWED: `add` command logic for existing example addition by @raysan5
|
||||||
[rexm] REVIEWED: Replace example name on project file by @raysan5
|
[rexm] REVIEWED: Replace example name on project file by @raysan5
|
||||||
[rexm] REVIEWED: Report issues if logs can not be loaded by @raysan5
|
[rexm] REVIEWED: Report issues if logs can not be loaded by @raysan5
|
||||||
[rexm] REVIEWED: VS project adding to solution by @raysan5
|
[rexm] REVIEWED: VS project adding to solution by @raysan5
|
||||||
@ -747,6 +763,7 @@ Detailed changes:
|
|||||||
[rexm] REVIEWED: `Makefile.Web` before trying to rebuild new example for web by @raysan5
|
[rexm] REVIEWED: `Makefile.Web` before trying to rebuild new example for web by @raysan5
|
||||||
[rexm] REVIEWED: Using `Makefile.Web` for specific web versions generation by @raysan5
|
[rexm] REVIEWED: Using `Makefile.Web` for specific web versions generation by @raysan5
|
||||||
|
|
||||||
|
[external] ADDED: `cgltf_write` 1.15, to support glTF models export in the future, by @raysan5
|
||||||
[external] RENAMED: `rl_gputex.h` to `rltexgpu.h`, compressed textures loading
|
[external] RENAMED: `rl_gputex.h` to `rltexgpu.h`, compressed textures loading
|
||||||
[external] REVIEWED: `rltexgpu.h`, make it usable standalone by @raysan5
|
[external] REVIEWED: `rltexgpu.h`, make it usable standalone by @raysan5
|
||||||
[external] REVIEWED: `rltexgpu.h, fix the swizzling in `rl_load_dds_from_memory()` (#5422) by @msmith-codes
|
[external] REVIEWED: `rltexgpu.h, fix the swizzling in `rl_load_dds_from_memory()` (#5422) by @msmith-codes
|
||||||
@ -755,16 +772,23 @@ Detailed changes:
|
|||||||
[external] REVIEWED: `sdefl` and `sinfl` issues (#5367) by @raysan5
|
[external] REVIEWED: `sdefl` and `sinfl` issues (#5367) by @raysan5
|
||||||
[external] REVIEWED: `sinfl_bsr()`, improvements by @RicoP
|
[external] REVIEWED: `sinfl_bsr()`, improvements by @RicoP
|
||||||
[external] REVIEWED: `stb_truetype`, fix composite glyph scaling logic (#4811) by @ashishbhattarai
|
[external] REVIEWED: `stb_truetype`, fix composite glyph scaling logic (#4811) by @ashishbhattarai
|
||||||
|
[external] UPDATED: `raygui` to 5.0-dev for examples by @raysan5
|
||||||
[external] UPDATED: dr_libs (#5020) by @Emil2010
|
[external] UPDATED: dr_libs (#5020) by @Emil2010
|
||||||
[external] UPDATED: miniaudio to v0.11.22 (#4983) by @M374LX
|
[external] UPDATED: `miniaudio` to v0.11.22 (#4983) by @M374LX
|
||||||
[external] UPDATED: miniaudio to v0.11.23 (#5234) by @pyrokn8
|
[external] UPDATED: `miniaudio` to v0.11.23 (#5234) by @pyrokn8
|
||||||
[external] UPDATED: miniaudio to v0.11.24 (#5506) by @vdemcak
|
[external] UPDATED: `miniaudio` to v0.11.24 (#5506) by @vdemcak
|
||||||
[external] UPDATED: raygui to 5.0-dev for examples by @raysan5
|
[external] UPDATED: `RGFW` to 1.5 (#4688) by @ColleagueRiley
|
||||||
[external] UPDATED: RGFW to 1.5 (#4688) by @ColleagueRiley
|
[external] UPDATED: `RGFW` to 1.6 (#4795) by @colleagueRiley
|
||||||
[external] UPDATED: RGFW to 1.6 (#4795) by @colleagueRiley
|
[external] UPDATED: `RGFW` to 1.7 (#4965) by @M374LX
|
||||||
[external] UPDATED: RGFW to 1.7 (#4965) by @M374LX
|
[external] UPDATED: `RGFW` to 1.7.5-dev (#4976) by @M374LX
|
||||||
[external] UPDATED: RGFW to 1.7.5-dev (#4976) by @M374LX
|
[external] UPDATED: `RGFW` to 2.0.0 (#5582) by @CrackedPixel
|
||||||
[external] UPDATED: RGFW to 2.0.0 (#5582) by @CrackedPixel
|
[external] UPDATED: `cgltf` 1.14 to 1.15 by @raysan5
|
||||||
|
[external] UPDATED: `dr_flac` v0.13.0 to v0.13.3 by @raysan5
|
||||||
|
[external] UPDATED: `dr_mp3` v0.7.0 to v0.7.4 by @raysan5
|
||||||
|
[external] UPDATED: `m3d` to latest master by @raysan5
|
||||||
|
[external] UPDATED: `qoi` to latest master by @raysan5
|
||||||
|
[external] UPDATED: `qoa` to latest master by @raysan5
|
||||||
|
[external] UPDATED: `stb_image_resize2` v2.12 to v2.18 by @raysan5
|
||||||
|
|
||||||
[misc] ADDED: SECURITY.md for security reporting policies by @raysan5
|
[misc] ADDED: SECURITY.md for security reporting policies by @raysan5
|
||||||
[misc] ADDED: `examples/examples_list`, to be used by `rexm` or other tools by @raysan5
|
[misc] ADDED: `examples/examples_list`, to be used by `rexm` or other tools by @raysan5
|
||||||
|
|||||||
@ -6,7 +6,7 @@ if(EMSCRIPTEN)
|
|||||||
# When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default
|
# When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default
|
||||||
SET(PLATFORM Web CACHE STRING "Platform to build for.")
|
SET(PLATFORM Web CACHE STRING "Platform to build for.")
|
||||||
endif()
|
endif()
|
||||||
enum_option(PLATFORM "Desktop;Web;WebRGFW;Android;Raspberry Pi;DRM;SDL;RGFW" "Platform to build for.")
|
enum_option(PLATFORM "Desktop;Web;WebRGFW;Android;Raspberry Pi;DRM;SDL;RGFW;Memory" "Platform to build for.")
|
||||||
|
|
||||||
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")
|
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")
|
||||||
|
|
||||||
|
|||||||
85
HISTORY.md
85
HISTORY.md
@ -526,26 +526,79 @@ Last but not least, I want to thank **raylib sponsors and all the raylib communi
|
|||||||
notes on raylib 6.0
|
notes on raylib 6.0
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
A new raylib release is finally ready, after almost 1.5 years since last release. This is the biggest release ever with many improvements to the library, thanks to the support of many amazing contributors and also thanks to the financial support of NLnet/NGI0 funds.
|
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:
|
Some astonishing numbers for this release:
|
||||||
|
|
||||||
- **+320** closed issues (for a TOTAL of **+2130**!)
|
- **+320** closed issues (for a TOTAL of **+2140**!)
|
||||||
- **+1800** commits since previous RELEASE (for a TOTAL of **+9600**!)
|
- **+1950** commits since previous RELEASE (for a TOTAL of **+9700**!)
|
||||||
- **18** functions ADDED to raylib API (for a TOTAL of **599**!)
|
- **+20** new functions ADDED to raylib API (for a TOTAL of **600**!)
|
||||||
- **+50** new examples to learn from (for a TOTAL of **212**!)
|
- **+50** new examples to learn from (for a TOTAL of **+210**!)
|
||||||
- **+200** new contributors (for a TOTAL of **+840**!)
|
- **+210** new contributors (for a TOTAL of **+850**!)
|
||||||
|
|
||||||
Highlights for `raylib 6.0`:
|
Highlights for `raylib 6.0`:
|
||||||
|
|
||||||
- New Software Renderer backend [rlsw]
|
- **`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 rcore platform backend: Memory (memory buffer)
|
|
||||||
- New rcore platform backend: Win32 (experimental)
|
|
||||||
- New rcore platform backend: Emscripten (experimental)
|
|
||||||
- Redesigned Skeletal Animation System
|
|
||||||
- Redesigned fullscreen modes and high-dpi content scaling
|
|
||||||
- Redesigned Build Config System [config.h]
|
|
||||||
- New File System API
|
|
||||||
- New Text Management API
|
|
||||||
- New tool: [rexm] raylib examples manager
|
|
||||||
|
|
||||||
|
- **`NEW` Platform backend: Memory - [`rcore_memory`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_memory.c)**: This new platform has been added along the **software renderer** backend, allowing 2d and 3d rendering over a **platform-agnostic memory framebuffer**, it can run headless and output frames can be directly exported to images. This new backend could also be useful for graphics rendering on servers or process images directly using the memory buffer.
|
||||||
|
|
||||||
|
- **`NEW` Platform backend: Win32 - [`rcore_desktop_win32`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_win32.c)**: A new **Windows platform backend** and the first step towards a potential replacement/alternative to the platform libraries currently used by raylib (GLFW/SDL/RGFW). This backend follows same API template structure than the other raylib backends, but directly implementing Win32 API calls. It allows initializing OpenGL GPU-accelerated windows and also GDI based windows, useful for the software renderer backend. This new backend approach, following a common template-structure and separating the platform logic by specific OS/Windowing system, will simplify code, improve maintenance, readability and portability for raylib, setting some bases for the future. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
|
||||||
|
|
||||||
|
- **`NEW` Platform backend: Emscripten - [`rcore_web_emscripten`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_web_emscripten.c)**: In the same line as Win32 backend, this new web backend moves away from `libglfw.js` and **directly implements Emscripten/JS functionality**, with **no other dependencies**, adding support for the new software renderer to draw directly on a **non-accelerated 2d canvas** but also supporting a WebGL-hardware-accelerated canvas when required. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
|
||||||
|
|
||||||
|
- **`REDESIGNED` Fullscreen modes and High-DPI content scaling**: After many years and many related issues, the full-screen and high-dpi content scaling support has been **completely redesigned** from scratch. New design prioritizes **borderless fullscreen modes** and automatically detects current monitor content scaling configuration to scale window and framebuffer accordingly when required. Still, High-DPI support must be requested by user if desired enabling `FLAG_WINDOW_HIGHDPI` on window creation. This new system has been carefully tested on Windows, Linux (X11, Wayland), macOS with multiple monitors and multiple resolutions, including 4K monitors.
|
||||||
|
|
||||||
|
- **`REDESIGNED` Skeletal Animation System**: A new animation system for 3d models has been created to support animation blending, between single frames but also between differents frames on different animations, to allow easy **timed transitions** between animations. This redesign implied reviewing several raylib structures to better accomodate animation data: `Model`, `ModelSkeleton`, `ModelAnimation`, but the API was simplified and support for GPU-skinning was improved with multiple optimizations.
|
||||||
|
|
||||||
|
- **`REDESIGNED` Build Config System - [`config.h`](https://github.com/raysan5/raylib/blob/master/src/config.h)**: raylib allows lot of customization for specific needs (i.e. disabling modules not needed for specific applications like rmodels or raudio) but previous implementation did not allow easely disabling some features from **custom build systems**. New design not only allows disabling features with simple `-DSUPPORT_FILEFORMAT_OBJ=0` on building command-line but also the full system has been reviewed, removing useless flags and exposing new ones.
|
||||||
|
|
||||||
|
- **`NEW` File System API**: Along the years, multiple filesystem functions have been added to raylib API as required but it felt somewhat inconsistent with some pieces missing. In this new release, the full filesystem API has beeen reviewed and reorganized, compiling all the functionality single module: [rcore](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1126), consequently `utils` module has been removed and build system has been simplified even more; **only 6-7 modules (.c) need to be compiled containing the full raylib library**. This new filesystem API will allow raylib to be used on the creation of custom build systems, as already demostrated with the new `rexm` tool for examples management. At the moment raylib includes **+40 file system management functions**, here a list with the new functions added:
|
||||||
|
```c
|
||||||
|
int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists)
|
||||||
|
int FileRemove(const char *fileName); // Remove file (if exists)
|
||||||
|
int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist
|
||||||
|
int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist
|
||||||
|
int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file
|
||||||
|
int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`NEW` Text Management API**: Along with the new file system functionality, a new set of text management functions has been added, also very useful for text procesing and also used in custom build systems creation using raylib. At the moment raylib includes **+30 text management functions**, here a list with the new functions added:
|
||||||
|
```c
|
||||||
|
char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
|
||||||
|
void UnloadTextLines(char **text, int lineCount); // Unload text lines
|
||||||
|
const char *TextRemoveSpaces(const char *text); // Remove text spaces, concat words
|
||||||
|
char *GetTextBetween(const char *text, const char *begin, const char *end); // Get text between two strings
|
||||||
|
char *TextReplace(const char *text, const char *search, const char *replacement); // Replace text string with new string
|
||||||
|
char *TextReplaceAlloc(const char *text, const char *search, const char *replacement); // Replace text string with new string, memory must be MemFree()
|
||||||
|
char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings
|
||||||
|
char *TextReplaceBetweenAlloc(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings, memory must be MemFree()
|
||||||
|
char *TextInsertAlloc(const char *text, const char *insert, int position); // Insert text in a defined byte position, memory must be MemFree()
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`NEW` tool: raylib examples manager - [rexm](https://github.com/raysan5/raylib/tree/master/tools/rexm)**: raylib examples collection is huge, with **more than 200 examples** it was quite difficult to manage: adding, removing, renaming examples was a very costly process involving many files to be modified (including build systems), also the examples did not follow a common header convention neither a structure conventions. For that reason, a new support tool has been created: **rexm**, a raylib examples manager that allows to easely add/remove/rename examples, automatically fix inconsistencies and even **building and automated testing** on multiple platforms.
|
||||||
|
```
|
||||||
|
USAGE:
|
||||||
|
> rexm <command> <example_name> [<example_rename>]
|
||||||
|
|
||||||
|
COMMANDS:
|
||||||
|
create <new_example_name> : Creates an empty example, from internal template
|
||||||
|
add <example_name> : Add existing example to collection
|
||||||
|
rename <old_examples_name> <new_example_name> : Rename an existing example
|
||||||
|
remove <example_name> : Remove an existing example from collection
|
||||||
|
build <example_name> : Build example for Desktop and Web platforms
|
||||||
|
test <example_name> : Build and Test example for Desktop and Web platforms
|
||||||
|
validate : Validate examples collection, generates report
|
||||||
|
update : Validate and update examples collection, generates report
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`NEW` +50 new examples**: Thanks to `rexm` and the simplification on examples management, this new raylib release includes +50 new examples to leearn from, most of them contributed by community.
|
||||||
|
|
||||||
|
Make sure to check raylib [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) for a detailed list of changes!
|
||||||
|
|
||||||
|
I want to **thank all the contributors (+850!**) that along the years have **greatly improved raylib** and pushed it further and better day after day. And **many thanks to raylib community and all raylib users** for supporting the library along those many years.
|
||||||
|
|
||||||
|
Finally, I want to thank [puffer.ai](https://puffer.ai/) and [comma.ai](https://comma.ai/) for **supporting and sponsoring the project** as platinum sponsors, along many others individuals that have been sponsoring raylib along the years. Thanks to all of you for allowing me to keep working on this library!
|
||||||
|
|
||||||
|
**After +12 years of development, `raylib 6.0` is today one of the bests libraries to enjoy games/tools/graphic programming!**
|
||||||
|
|
||||||
|
**Enjoy graphics programming with raylib!** :)
|
||||||
|
|||||||
@ -40,6 +40,7 @@ features
|
|||||||
- Written in plain C code (C99) using PascalCase/camelCase notation
|
- Written in plain C code (C99) using PascalCase/camelCase notation
|
||||||
- Hardware accelerated with OpenGL: **1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**
|
- Hardware accelerated with OpenGL: **1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**
|
||||||
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
|
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
|
||||||
|
- **Software Renderer** backend (no OpenGL required!): [rlsw](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h)
|
||||||
- Multiple **Fonts** formats supported (TTF, OTF, FNT, BDF, sprite fonts)
|
- Multiple **Fonts** formats supported (TTF, OTF, FNT, BDF, sprite fonts)
|
||||||
- Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC)
|
- Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC)
|
||||||
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
|
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
|
||||||
@ -61,7 +62,7 @@ This is a basic raylib example, it creates a window and draws the text `"Congrat
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
InitWindow(800, 450, "raylib [core] example - basic window");
|
InitWindow(800, 450, "raylib example - basic window");
|
||||||
|
|
||||||
while (!WindowShouldClose())
|
while (!WindowShouldClose())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,6 +6,7 @@ Here is a wishlist with features and ideas to improve the library. Note that fea
|
|||||||
- [GitHub PRs](https://github.com/raysan5/raylib/pulls) open with improvements to be reviewed.
|
- [GitHub PRs](https://github.com/raysan5/raylib/pulls) open with improvements to be reviewed.
|
||||||
- [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve.
|
- [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve.
|
||||||
- raylib wishlists discussions are open to everyone to ask for improvements, feel free to check and comment:
|
- raylib wishlists discussions are open to everyone to ask for improvements, feel free to check and comment:
|
||||||
|
- [raylib 7.0 wishlist](https://github.com/raysan5/raylib/discussions/5710)
|
||||||
- [raylib 6.0 wishlist](https://github.com/raysan5/raylib/discussions/4660)
|
- [raylib 6.0 wishlist](https://github.com/raysan5/raylib/discussions/4660)
|
||||||
- [raylib 5.0 wishlist](https://github.com/raysan5/raylib/discussions/2952)
|
- [raylib 5.0 wishlist](https://github.com/raysan5/raylib/discussions/2952)
|
||||||
- [raylib wishlist 2022](https://github.com/raysan5/raylib/discussions/2272)
|
- [raylib wishlist 2022](https://github.com/raysan5/raylib/discussions/2272)
|
||||||
@ -21,8 +22,9 @@ _Current version of raylib is complete and functional but there is always room f
|
|||||||
- [ ] `rcore_desktop_wayland`: Create additional platform backend: Linux/Wayland
|
- [ ] `rcore_desktop_wayland`: Create additional platform backend: Linux/Wayland
|
||||||
- [ ] `rcore`: Investigate alternative embedded platforms and realtime OSs
|
- [ ] `rcore`: Investigate alternative embedded platforms and realtime OSs
|
||||||
- [ ] `rlsw`: Software renderer optimizations: mipmaps, platform-specific SIMD
|
- [ ] `rlsw`: Software renderer optimizations: mipmaps, platform-specific SIMD
|
||||||
- [ ] `rtextures`: Consider moving N-patch system to separate example
|
- [ ] `rtextures`: Consider removing N-patch system, provide as separate example
|
||||||
- [ ] `rtextures`: Review blending modes system, provide more options or better samples
|
- [ ] `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
|
- [ ] `raudio`: Support microphone input, basic API to read microphone
|
||||||
- [ ] `rltexgpu`: Improve compressed textures support, loading and saving, improve KTX 2.0
|
- [ ] `rltexgpu`: Improve compressed textures support, loading and saving, improve KTX 2.0
|
||||||
- [ ] `rlobj`: Create OBJ loader, supporting material file separately (low priority)
|
- [ ] `rlobj`: Create OBJ loader, supporting material file separately (low priority)
|
||||||
|
|||||||
16
build.zig
16
build.zig
@ -2,7 +2,7 @@ const std = @import("std");
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
/// Minimum supported version of Zig
|
/// Minimum supported version of Zig
|
||||||
const min_ver = "0.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 emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
|
||||||
const emccOutputFile = "index.html";
|
const emccOutputFile = "index.html";
|
||||||
@ -202,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.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
raylib.root_module.linkSystemLibrary("EGL", .{});
|
if (options.opengl_version != .gl_soft) {
|
||||||
raylib.root_module.linkSystemLibrary("gbm", .{});
|
raylib.root_module.linkSystemLibrary("EGL", .{});
|
||||||
|
raylib.root_module.linkSystemLibrary("gbm", .{});
|
||||||
|
}
|
||||||
raylib.root_module.linkSystemLibrary("libdrm", .{ .use_pkg_config = .force });
|
raylib.root_module.linkSystemLibrary("libdrm", .{ .use_pkg_config = .force });
|
||||||
|
|
||||||
raylib.root_module.addCMacro("PLATFORM_DRM", "");
|
raylib.root_module.addCMacro("PLATFORM_DRM", "");
|
||||||
@ -264,7 +266,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
|||||||
|
|
||||||
setDesktopPlatform(raylib, .android);
|
setDesktopPlatform(raylib, .android);
|
||||||
} else {
|
} else {
|
||||||
try c_source_files.append(b.allocator, "src/rglfw.c");
|
switch (options.platform) {
|
||||||
|
.glfw => try c_source_files.append(b.allocator, "src/rglfw.c"),
|
||||||
|
.rgfw, .sdl, .drm, .android => {},
|
||||||
|
}
|
||||||
|
|
||||||
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
||||||
raylib.root_module.addCMacro("_GLFW_X11", "");
|
raylib.root_module.addCMacro("_GLFW_X11", "");
|
||||||
@ -413,6 +418,7 @@ pub const Options = struct {
|
|||||||
|
|
||||||
pub const OpenglVersion = enum {
|
pub const OpenglVersion = enum {
|
||||||
auto,
|
auto,
|
||||||
|
gl_soft,
|
||||||
gl_1_1,
|
gl_1_1,
|
||||||
gl_2_1,
|
gl_2_1,
|
||||||
gl_3_3,
|
gl_3_3,
|
||||||
@ -423,6 +429,7 @@ pub const OpenglVersion = enum {
|
|||||||
pub fn toCMacroStr(self: @This()) []const u8 {
|
pub fn toCMacroStr(self: @This()) []const u8 {
|
||||||
switch (self) {
|
switch (self) {
|
||||||
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
|
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
|
||||||
|
.gl_soft => return "GRAPHICS_API_OPENGL_SOFTWARE",
|
||||||
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
|
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
|
||||||
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
|
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
|
||||||
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
|
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
|
||||||
@ -434,6 +441,7 @@ pub const OpenglVersion = enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const LinuxDisplayBackend = enum {
|
pub const LinuxDisplayBackend = enum {
|
||||||
|
None,
|
||||||
X11,
|
X11,
|
||||||
Wayland,
|
Wayland,
|
||||||
Both,
|
Both,
|
||||||
|
|||||||
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.xcode_frameworks = .{
|
.xcode_frameworks = .{
|
||||||
.url = "git+https://github.com/hexops/xcode-frameworks#9a45f3ac977fd25dff77e58c6de1870b6808c4a7",
|
.url = "https://pkg.machengine.org/xcode-frameworks/8a1cfb373587ea4c9bb1468b7c986462d8d4e10e.tar.gz",
|
||||||
.hash = "N-V-__8AABHMqAWYuRdIlflwi8gksPnlUMQBiSxAqQAAZFms",
|
.hash = "N-V-__8AALShqgXkvqYU6f__FrA22SMWmi2TXCJjNTO1m8XJ",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.emsdk = .{
|
.emsdk = .{
|
||||||
|
|||||||
@ -96,21 +96,30 @@ elseif (${PLATFORM} STREQUAL "Android")
|
|||||||
|
|
||||||
elseif ("${PLATFORM}" STREQUAL "DRM")
|
elseif ("${PLATFORM}" STREQUAL "DRM")
|
||||||
set(PLATFORM_CPP "PLATFORM_DRM")
|
set(PLATFORM_CPP "PLATFORM_DRM")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
|
||||||
|
|
||||||
add_definitions(-D_DEFAULT_SOURCE)
|
add_definitions(-D_DEFAULT_SOURCE)
|
||||||
add_definitions(-DEGL_NO_X11)
|
|
||||||
add_definitions(-DPLATFORM_DRM)
|
add_definitions(-DPLATFORM_DRM)
|
||||||
|
|
||||||
find_library(GLESV2 GLESv2)
|
|
||||||
find_library(EGL EGL)
|
|
||||||
find_library(DRM drm)
|
find_library(DRM drm)
|
||||||
find_library(GBM gbm)
|
|
||||||
|
|
||||||
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
|
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
|
||||||
include_directories(/usr/include/libdrm)
|
include_directories(/usr/include/libdrm)
|
||||||
endif ()
|
endif ()
|
||||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
|
||||||
|
if ("${OPENGL_VERSION}" STREQUAL "Software")
|
||||||
|
# software rendering does not require EGL/GBM.
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||||
|
set(LIBS_PRIVATE ${DRM} atomic pthread dl)
|
||||||
|
else ()
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
|
add_definitions(-DEGL_NO_X11)
|
||||||
|
|
||||||
|
find_library(GLESV2 GLESv2)
|
||||||
|
find_library(EGL EGL)
|
||||||
|
find_library(GBM gbm)
|
||||||
|
|
||||||
|
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
||||||
|
endif ()
|
||||||
set(LIBS_PUBLIC m)
|
set(LIBS_PUBLIC m)
|
||||||
|
|
||||||
elseif ("${PLATFORM}" STREQUAL "SDL")
|
elseif ("${PLATFORM}" STREQUAL "SDL")
|
||||||
@ -147,6 +156,7 @@ elseif ("${PLATFORM}" STREQUAL "SDL")
|
|||||||
add_compile_definitions(USING_SDL2_PACKAGE)
|
add_compile_definitions(USING_SDL2_PACKAGE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
elseif ("${PLATFORM}" STREQUAL "RGFW")
|
elseif ("${PLATFORM}" STREQUAL "RGFW")
|
||||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW")
|
set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW")
|
||||||
|
|
||||||
@ -172,6 +182,15 @@ elseif ("${PLATFORM}" STREQUAL "WebRGFW")
|
|||||||
set(PLATFORM_CPP "PLATFORM_WEB_RGFW")
|
set(PLATFORM_CPP "PLATFORM_WEB_RGFW")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
|
||||||
|
|
||||||
|
elseif ("${PLATFORM}" STREQUAL "Memory")
|
||||||
|
set(PLATFORM_CPP "PLATFORM_MEMORY")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||||
|
set(OPENGL_VERSION "Software")
|
||||||
|
|
||||||
|
if(WIN32 OR CMAKE_C_COMPILER MATCHES "mingw|mingw32|mingw64")
|
||||||
|
set(LIBS_PRIVATE winmm)
|
||||||
|
endif()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||||
|
|||||||
@ -105,6 +105,9 @@ elseif ("${PLATFORM}" STREQUAL "DRM")
|
|||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||||
|
|
||||||
|
elseif ("${PLATFORM}" MATCHES "Memory")
|
||||||
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||||
|
|
||||||
elseif ("${OPENGL_VERSION}" STREQUAL "Software")
|
elseif ("${OPENGL_VERSION}" STREQUAL "Software")
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# raylib makefile for Android project (APK building)
|
# raylib makefile for Android project (APK building)
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
|
# Copyright (c) 2017-2026 Ramon Santamaria (@raysan5)
|
||||||
#
|
#
|
||||||
# This software is provided "as-is", without any express or implied warranty. In no event
|
# This software is provided "as-is", without any express or implied warranty. In no event
|
||||||
# will the authors be held liable for any damages arising from the use of this software.
|
# will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
|||||||
@ -1153,7 +1153,10 @@ text/text_font_filters: text/text_font_filters.c
|
|||||||
--preload-file text/resources/KAISG.ttf@resources/KAISG.ttf
|
--preload-file text/resources/KAISG.ttf@resources/KAISG.ttf
|
||||||
|
|
||||||
text/text_font_loading: text/text_font_loading.c
|
text/text_font_loading: text/text_font_loading.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file text/resources/pixantiqua.fnt@resources/pixantiqua.fnt \
|
||||||
|
--preload-file text/resources/pixantiqua.png@resources/pixantiqua.png \
|
||||||
|
--preload-file text/resources/pixantiqua.ttf@resources/pixantiqua.ttf
|
||||||
|
|
||||||
text/text_font_sdf: text/text_font_sdf.c
|
text/text_font_sdf: text/text_font_sdf.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
|||||||
@ -223,7 +223,7 @@ Examples using raylib models functionality, including models loading/generation
|
|||||||
|
|
||||||
### category: shaders [35]
|
### category: shaders [35]
|
||||||
|
|
||||||
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module.
|
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.h) module.
|
||||||
|
|
||||||
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
|
|||||||
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 |
@ -110,16 +110,16 @@ int main(void)
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
DrawText(TextFormat("sine frequency: %i", sineFrequency), screenWidth - 220, 10, 20, RED);
|
DrawText(TextFormat("sine frequency: %i", sineFrequency), screenWidth - 220, 10, 20, RED);
|
||||||
DrawText(TextFormat("pan: %.2f", pan), screenWidth - 220, 30, 20, RED);
|
DrawText(TextFormat("pan: %.2f", pan), screenWidth - 220, 30, 20, RED);
|
||||||
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
|
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
|
||||||
DrawText("Left/right to pan", 10, 30, 20, DARKGRAY);
|
DrawText("Left/right to pan", 10, 30, 20, DARKGRAY);
|
||||||
|
|
||||||
int windowStart = (GetTime() - sineStartTime)*SAMPLE_RATE;
|
int windowStart = (GetTime() - sineStartTime)*SAMPLE_RATE;
|
||||||
int windowSize = 0.1f*SAMPLE_RATE;
|
int windowSize = 0.1f*SAMPLE_RATE;
|
||||||
int wavelength = SAMPLE_RATE/sineFrequency;
|
int wavelength = SAMPLE_RATE/sineFrequency;
|
||||||
|
|
||||||
// Draw a sine wave with the same frequency as the one being sent to the audio stream
|
// Draw a sine wave with the same frequency as the one being sent to the audio stream
|
||||||
for (int i = 0; i < screenWidth; i++)
|
for (int i = 0; i < screenWidth; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
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 localX = mod(fragCoord.x, cellWidth);
|
||||||
float barWidth = cellWidth - 1.0;
|
float barWidth = cellWidth - 1.0;
|
||||||
vec4 color = WHITE;
|
vec4 color = WHITE;
|
||||||
|
|
||||||
if (localX <= barWidth)
|
if (localX <= barWidth)
|
||||||
{
|
{
|
||||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||||
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||||
|
|
||||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,15 +21,15 @@ void main()
|
|||||||
float localX = mod(fragCoord.x, cellWidth);
|
float localX = mod(fragCoord.x, cellWidth);
|
||||||
float barWidth = cellWidth - 1.0;
|
float barWidth = cellWidth - 1.0;
|
||||||
vec4 color = WHITE;
|
vec4 color = WHITE;
|
||||||
|
|
||||||
if (localX <= barWidth)
|
if (localX <= barWidth)
|
||||||
{
|
{
|
||||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||||
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||||
|
|
||||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,15 +21,15 @@ void main()
|
|||||||
float localX = mod(fragCoord.x, cellWidth);
|
float localX = mod(fragCoord.x, cellWidth);
|
||||||
float barWidth = cellWidth - 1.0;
|
float barWidth = cellWidth - 1.0;
|
||||||
vec4 color = WHITE;
|
vec4 color = WHITE;
|
||||||
|
|
||||||
if (localX <= barWidth)
|
if (localX <= barWidth)
|
||||||
{
|
{
|
||||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||||
float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||||
|
|
||||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
finalColor = color;
|
finalColor = color;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,7 +73,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw UI info
|
// 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);
|
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("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY);
|
||||||
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);
|
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Example complexity rating: [★★☆☆] 2/4
|
* 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
|
* mapping to other layouts is up to the user
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
* 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 };
|
int line01KeyWidths[15] = { 0 };
|
||||||
for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45;
|
for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45;
|
||||||
line01KeyWidths[13] = 62; // PRINTSCREEN
|
line01KeyWidths[13] = 62; // PRINTSCREEN
|
||||||
int line01Keys[15] = {
|
int line01Keys[15] = {
|
||||||
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
|
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_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
|
||||||
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
|
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
|
||||||
};
|
};
|
||||||
|
|
||||||
// Keyboard line 02
|
// Keyboard line 02
|
||||||
int line02KeyWidths[15] = { 0 };
|
int line02KeyWidths[15] = { 0 };
|
||||||
for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45;
|
for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45;
|
||||||
line02KeyWidths[0] = 25; // GRAVE
|
line02KeyWidths[0] = 25; // GRAVE
|
||||||
line02KeyWidths[13] = 82; // BACKSPACE
|
line02KeyWidths[13] = 82; // BACKSPACE
|
||||||
int line02Keys[15] = {
|
int line02Keys[15] = {
|
||||||
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
|
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
|
||||||
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
|
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
|
||||||
KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE };
|
KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE };
|
||||||
|
|
||||||
// Keyboard line 03
|
// Keyboard line 03
|
||||||
@ -103,7 +103,7 @@ int main(void)
|
|||||||
KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL,
|
KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL,
|
||||||
KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT
|
KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector2 keyboardOffset = { 26, 80 };
|
Vector2 keyboardOffset = { 26, 80 };
|
||||||
|
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
@ -128,23 +128,23 @@ int main(void)
|
|||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY);
|
DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY);
|
||||||
|
|
||||||
// Keyboard line 01 - 15 keys
|
// Keyboard line 01 - 15 keys
|
||||||
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
|
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
|
||||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, (float)line01KeyWidths[i], 30.0f }, line01Keys[i]);
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, (float)line01KeyWidths[i], 30.0f }, line01Keys[i]);
|
||||||
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
|
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard line 02 - 15 keys
|
// Keyboard line 02 - 15 keys
|
||||||
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
|
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
|
||||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, (float)line02KeyWidths[i], 38.0f }, line02Keys[i]);
|
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, (float)line02KeyWidths[i], 38.0f }, line02Keys[i]);
|
||||||
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
|
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard line 03 - 15 keys
|
// Keyboard line 03 - 15 keys
|
||||||
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
|
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
|
||||||
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
for (int i = 0, recOffsetX = 0; i < 15; i++)
|
||||||
@ -324,8 +324,8 @@ static void GuiKeyboardKey(Rectangle bounds, int key)
|
|||||||
DrawText(GetKeyText(key), (int)(bounds.x + 4), (int)(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));
|
DrawRectangleRec(bounds, Fade(RED, 0.2f));
|
||||||
DrawRectangleLinesEx(bounds, 3.0f, RED);
|
DrawRectangleLinesEx(bounds, 3.0f, RED);
|
||||||
|
|||||||
@ -111,7 +111,7 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
free(rectangles);
|
RL_FREE(rectangles);
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
GLFW_ICON ICON "raylib.ico"
|
GLFW_ICON ICON "raylib.ico"
|
||||||
|
|
||||||
1 VERSIONINFO
|
1 VERSIONINFO
|
||||||
FILEVERSION 5,5,0,0
|
FILEVERSION 6,0,0,0
|
||||||
PRODUCTVERSION 5,5,0,0
|
PRODUCTVERSION 6,0,0,0
|
||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "StringFileInfo"
|
BLOCK "StringFileInfo"
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -11,12 +11,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "raylib technologies"
|
VALUE "CompanyName", "raylib technologies"
|
||||||
VALUE "FileDescription", "raylib application (www.raylib.com)"
|
VALUE "FileDescription", "raylib application (www.raylib.com)"
|
||||||
VALUE "FileVersion", "5.5.0"
|
VALUE "FileVersion", "6.0.0"
|
||||||
VALUE "InternalName", "raylib-example"
|
VALUE "InternalName", "raylib-example"
|
||||||
VALUE "LegalCopyright", "(c) 2025 Ramon Santamaria (@raysan5)"
|
VALUE "LegalCopyright", "(c) 2026 Ramon Santamaria (@raysan5)"
|
||||||
VALUE "OriginalFilename", "raylib-example"
|
VALUE "OriginalFilename", "raylib-example"
|
||||||
VALUE "ProductName", "raylib-example"
|
VALUE "ProductName", "raylib-example"
|
||||||
VALUE "ProductVersion", "5.5.0"
|
VALUE "ProductVersion", "6.0.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
// Module Functions Declaration
|
// Module Functions Declaration
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
static bool IsUpperBodyBone(const char *boneName);
|
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);
|
ModelAnimation *anim2, int frame2, float blend, bool upperBodyBlend);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
@ -86,7 +86,7 @@ int main(void)
|
|||||||
int animIndex1 = 3; // Attack animation (index 3)
|
int animIndex1 = 3; // Attack animation (index 3)
|
||||||
int animCurrentFrame0 = 0;
|
int animCurrentFrame0 = 0;
|
||||||
int animCurrentFrame1 = 0;
|
int animCurrentFrame1 = 0;
|
||||||
|
|
||||||
// Validate indices
|
// Validate indices
|
||||||
if (animIndex0 >= animCount) animIndex0 = 0;
|
if (animIndex0 >= animCount) animIndex0 = 0;
|
||||||
if (animIndex1 >= animCount) animIndex1 = (animCount > 1) ? 1 : 0;
|
if (animIndex1 >= animCount) animIndex1 = (animCount > 1) ? 1 : 0;
|
||||||
@ -109,7 +109,7 @@ int main(void)
|
|||||||
// Update animation frames
|
// Update animation frames
|
||||||
ModelAnimation anim0 = anims[animIndex0];
|
ModelAnimation anim0 = anims[animIndex0];
|
||||||
ModelAnimation anim1 = anims[animIndex1];
|
ModelAnimation anim1 = anims[animIndex1];
|
||||||
|
|
||||||
animCurrentFrame0 = (animCurrentFrame0 + 1)%anim0.keyframeCount;
|
animCurrentFrame0 = (animCurrentFrame0 + 1)%anim0.keyframeCount;
|
||||||
animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.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 ON: upper body = attack (1.0), lower body = walk (0.0)
|
||||||
// When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack)
|
// When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack)
|
||||||
float blendFactor = (upperBodyBlend? 1.0f : 0.5f);
|
float blendFactor = (upperBodyBlend? 1.0f : 0.5f);
|
||||||
UpdateModelAnimationBones(&model, &anim0, animCurrentFrame0,
|
UpdateModelAnimationBones(&model, &anim0, animCurrentFrame0,
|
||||||
&anim1, animCurrentFrame1, blendFactor, upperBodyBlend);
|
&anim1, animCurrentFrame1, blendFactor, upperBodyBlend);
|
||||||
|
|
||||||
// raylib provided animation blending function
|
// raylib provided animation blending function
|
||||||
//UpdateModelAnimationEx(model, anim0, (float)animCurrentFrame0,
|
//UpdateModelAnimationEx(model, anim0, (float)animCurrentFrame0,
|
||||||
// anim1, (float)animCurrentFrame1, blendFactor);
|
// anim1, (float)animCurrentFrame1, blendFactor);
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -142,8 +142,8 @@ int main(void)
|
|||||||
// Draw UI
|
// Draw UI
|
||||||
DrawText(TextFormat("ANIM 0: %s", anim0.name), 10, 10, 20, GRAY);
|
DrawText(TextFormat("ANIM 0: %s", anim0.name), 10, 10, 20, GRAY);
|
||||||
DrawText(TextFormat("ANIM 1: %s", anim1.name), 10, 40, 20, GRAY);
|
DrawText(TextFormat("ANIM 1: %s", anim1.name), 10, 40, 20, GRAY);
|
||||||
DrawText(TextFormat("[SPACE] Toggle blending mode: %s",
|
DrawText(TextFormat("[SPACE] Toggle blending mode: %s",
|
||||||
upperBodyBlend? "Upper/Lower Body Blending" : "Uniform Blending"),
|
upperBodyBlend? "Upper/Lower Body Blending" : "Uniform Blending"),
|
||||||
10, GetScreenHeight() - 30, 20, DARKGRAY);
|
10, GetScreenHeight() - 30, 20, DARKGRAY);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
@ -180,7 +180,7 @@ static bool IsUpperBodyBone(const char *boneName)
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if bone name contains upper body keywords
|
// Check if bone name contains upper body keywords
|
||||||
if (strstr(boneName, "spine") != NULL || strstr(boneName, "chest") != NULL ||
|
if (strstr(boneName, "spine") != NULL || strstr(boneName, "chest") != NULL ||
|
||||||
strstr(boneName, "neck") != NULL || strstr(boneName, "head") != NULL ||
|
strstr(boneName, "neck") != NULL || strstr(boneName, "head") != NULL ||
|
||||||
@ -189,12 +189,12 @@ static bool IsUpperBodyBone(const char *boneName)
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blend two animations per-bone with selective upper/lower body blending
|
// 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)
|
ModelAnimation *anim1, int frame1, float blend, bool upperBodyBlend)
|
||||||
{
|
{
|
||||||
// Validate inputs
|
// Validate inputs
|
||||||
@ -204,59 +204,59 @@ static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int f
|
|||||||
{
|
{
|
||||||
// Clamp blend factor to [0, 1]
|
// Clamp blend factor to [0, 1]
|
||||||
blend = fminf(1.0f, fmaxf(0.0f, blend));
|
blend = fminf(1.0f, fmaxf(0.0f, blend));
|
||||||
|
|
||||||
// Ensure frame indices are valid
|
// Ensure frame indices are valid
|
||||||
if (frame0 >= anim0->keyframeCount) frame0 = anim0->keyframeCount - 1;
|
if (frame0 >= anim0->keyframeCount) frame0 = anim0->keyframeCount - 1;
|
||||||
if (frame1 >= anim1->keyframeCount) frame1 = anim1->keyframeCount - 1;
|
if (frame1 >= anim1->keyframeCount) frame1 = anim1->keyframeCount - 1;
|
||||||
if (frame0 < 0) frame0 = 0;
|
if (frame0 < 0) frame0 = 0;
|
||||||
if (frame1 < 0) frame1 = 0;
|
if (frame1 < 0) frame1 = 0;
|
||||||
|
|
||||||
// Get bone count (use minimum of all to be safe)
|
// Get bone count (use minimum of all to be safe)
|
||||||
int boneCount = model->skeleton.boneCount;
|
int boneCount = model->skeleton.boneCount;
|
||||||
if (anim0->boneCount < boneCount) boneCount = anim0->boneCount;
|
if (anim0->boneCount < boneCount) boneCount = anim0->boneCount;
|
||||||
if (anim1->boneCount < boneCount) boneCount = anim1->boneCount;
|
if (anim1->boneCount < boneCount) boneCount = anim1->boneCount;
|
||||||
|
|
||||||
// Blend each bone
|
// Blend each bone
|
||||||
for (int boneIndex = 0; boneIndex < boneCount; boneIndex++)
|
for (int boneIndex = 0; boneIndex < boneCount; boneIndex++)
|
||||||
{
|
{
|
||||||
// Determine blend factor for this bone
|
// Determine blend factor for this bone
|
||||||
float boneBlendFactor = blend;
|
float boneBlendFactor = blend;
|
||||||
|
|
||||||
// If upper body blending is enabled, use different blend factors for upper vs lower body
|
// If upper body blending is enabled, use different blend factors for upper vs lower body
|
||||||
if (upperBodyBlend)
|
if (upperBodyBlend)
|
||||||
{
|
{
|
||||||
const char *boneName = model->skeleton.bones[boneIndex].name;
|
const char *boneName = model->skeleton.bones[boneIndex].name;
|
||||||
bool isUpperBody = IsUpperBodyBone(boneName);
|
bool isUpperBody = IsUpperBodyBone(boneName);
|
||||||
|
|
||||||
// Upper body: use anim1 (attack), Lower body: use anim0 (walk)
|
// Upper body: use anim1 (attack), Lower body: use anim0 (walk)
|
||||||
// blend = 0.0 means full anim0 (walk), 1.0 means full anim1 (attack)
|
// blend = 0.0 means full anim0 (walk), 1.0 means full anim1 (attack)
|
||||||
if (isUpperBody) boneBlendFactor = blend; // Upper body: blend towards 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
|
else boneBlendFactor = 1.0f - blend; // Lower body: blend towards anim0 (walk) - invert the blend
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get transforms from both animations
|
// Get transforms from both animations
|
||||||
Transform *bindTransform = &model->skeleton.bindPose[boneIndex];
|
Transform *bindTransform = &model->skeleton.bindPose[boneIndex];
|
||||||
Transform *animTransform0 = &anim0->keyframePoses[frame0][boneIndex];
|
Transform *animTransform0 = &anim0->keyframePoses[frame0][boneIndex];
|
||||||
Transform *animTransform1 = &anim1->keyframePoses[frame1][boneIndex];
|
Transform *animTransform1 = &anim1->keyframePoses[frame1][boneIndex];
|
||||||
|
|
||||||
// Blend the transforms
|
// Blend the transforms
|
||||||
Transform blended = { 0 };
|
Transform blended = { 0 };
|
||||||
blended.translation = Vector3Lerp(animTransform0->translation, animTransform1->translation, boneBlendFactor);
|
blended.translation = Vector3Lerp(animTransform0->translation, animTransform1->translation, boneBlendFactor);
|
||||||
blended.rotation = QuaternionSlerp(animTransform0->rotation, animTransform1->rotation, boneBlendFactor);
|
blended.rotation = QuaternionSlerp(animTransform0->rotation, animTransform1->rotation, boneBlendFactor);
|
||||||
blended.scale = Vector3Lerp(animTransform0->scale, animTransform1->scale, boneBlendFactor);
|
blended.scale = Vector3Lerp(animTransform0->scale, animTransform1->scale, boneBlendFactor);
|
||||||
|
|
||||||
// Convert bind pose to matrix
|
// Convert bind pose to matrix
|
||||||
Matrix bindMatrix = MatrixMultiply(MatrixMultiply(
|
Matrix bindMatrix = MatrixMultiply(MatrixMultiply(
|
||||||
MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z),
|
MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z),
|
||||||
QuaternionToMatrix(bindTransform->rotation)),
|
QuaternionToMatrix(bindTransform->rotation)),
|
||||||
MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z));
|
MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z));
|
||||||
|
|
||||||
// Convert blended transform to matrix
|
// Convert blended transform to matrix
|
||||||
Matrix blendedMatrix = MatrixMultiply(MatrixMultiply(
|
Matrix blendedMatrix = MatrixMultiply(MatrixMultiply(
|
||||||
MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z),
|
MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z),
|
||||||
QuaternionToMatrix(blended.rotation)),
|
QuaternionToMatrix(blended.rotation)),
|
||||||
MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z));
|
MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z));
|
||||||
|
|
||||||
// Calculate final bone matrix (similar to UpdateModelAnimationBones)
|
// Calculate final bone matrix (similar to UpdateModelAnimationBones)
|
||||||
model->boneMatrices[boneIndex] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix);
|
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
|
bool bufferUpdateRequired = false; // Flag to check when anim vertex information is updated
|
||||||
|
|
||||||
// Skip if missing bone data or missing anim buffers initialization
|
// 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;
|
(mesh.animVertices == NULL) || (mesh.animNormals == NULL)) continue;
|
||||||
|
|
||||||
for (int vCounter = 0; vCounter < vertexValuesCount; vCounter += 3)
|
for (int vCounter = 0; vCounter < vertexValuesCount; vCounter += 3)
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
* raylib [models] example - animation blending
|
* raylib [models] example - animation blending
|
||||||
*
|
*
|
||||||
* Example complexity rating: [★★★★] 4/4
|
* Example complexity rating: [★★★★] 4/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
* 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)
|
* 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)
|
// WARNING: It requires SUPPORT_GPU_SKINNING enabled on raylib (disabled by default)
|
||||||
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||||
|
|
||||||
// Assign skinning shader to all materials shaders
|
// Assign skinning shader to all materials shaders
|
||||||
//for (int i = 0; i < model.materialCount; i++) model.materials[i].shader = skinningShader;
|
//for (int i = 0; i < model.materialCount; i++) model.materials[i].shader = skinningShader;
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ int main(void)
|
|||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_P)) animPause = !animPause;
|
if (IsKeyPressed(KEY_P)) animPause = !animPause;
|
||||||
|
|
||||||
if (!animPause)
|
if (!animPause)
|
||||||
@ -127,7 +127,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set animation transition
|
// Set animation transition
|
||||||
animTransition = true;
|
animTransition = true;
|
||||||
animBlendTimeCounter = 0.0f;
|
animBlendTimeCounter = 0.0f;
|
||||||
animBlendFactor = 0.0f;
|
animBlendFactor = 0.0f;
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ int main(void)
|
|||||||
animCurrentFrame0 += animFrameSpeed0;
|
animCurrentFrame0 += animFrameSpeed0;
|
||||||
if (animCurrentFrame0 >= anims[animIndex0].keyframeCount) animCurrentFrame0 = 0.0f;
|
if (animCurrentFrame0 >= anims[animIndex0].keyframeCount) animCurrentFrame0 = 0.0f;
|
||||||
UpdateModelAnimation(model, anims[animIndex0], animCurrentFrame0);
|
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
|
// anims[animIndex1], animCurrentFrame1, 0.0f); // Same as above, first animation frame blend
|
||||||
}
|
}
|
||||||
else if (currentAnimPlaying == 1)
|
else if (currentAnimPlaying == 1)
|
||||||
@ -191,7 +191,7 @@ int main(void)
|
|||||||
animCurrentFrame1 += animFrameSpeed1;
|
animCurrentFrame1 += animFrameSpeed1;
|
||||||
if (animCurrentFrame1 >= anims[animIndex1].keyframeCount) animCurrentFrame1 = 0.0f;
|
if (animCurrentFrame1 >= anims[animIndex1].keyframeCount) animCurrentFrame1 = 0.0f;
|
||||||
UpdateModelAnimation(model, anims[animIndex1], animCurrentFrame1);
|
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
|
// 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
|
DrawModel(model, position, 1.0f, WHITE); // Draw animated model
|
||||||
|
|
||||||
DrawGrid(10, 1.0f);
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
if (animTransition) DrawText("ANIM TRANSITION BLENDING!", 170, 50, 30, BLUE);
|
if (animTransition) DrawText("ANIM TRANSITION BLENDING!", 170, 50, 30, BLUE);
|
||||||
@ -221,18 +221,18 @@ int main(void)
|
|||||||
// Draw UI elements
|
// Draw UI elements
|
||||||
//---------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------
|
||||||
if (dropdownEditMode0) GuiDisable();
|
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);
|
NULL, TextFormat("x%.1f", animFrameSpeed0), &animFrameSpeed0, 0.1f, 2.0f);
|
||||||
GuiEnable();
|
GuiEnable();
|
||||||
if (dropdownEditMode1) GuiDisable();
|
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);
|
TextFormat("%.1fx", animFrameSpeed1), NULL, &animFrameSpeed1, 0.1f, 2.0f);
|
||||||
GuiEnable();
|
GuiEnable();
|
||||||
|
|
||||||
// Draw animation selectors for blending transition
|
// 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);
|
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;
|
&animIndex0, dropdownEditMode0)) dropdownEditMode0 = !dropdownEditMode0;
|
||||||
|
|
||||||
// Blending process progress bar
|
// Blending process progress bar
|
||||||
@ -249,7 +249,7 @@ int main(void)
|
|||||||
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
|
||||||
&animFrameProgress0, 0.0f, (float)anims[animIndex0].keyframeCount);
|
&animFrameProgress0, 0.0f, (float)anims[animIndex0].keyframeCount);
|
||||||
for (int i = 0; i < anims[animIndex0].keyframeCount; i++)
|
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);
|
GetScreenHeight() - 60, 1, 20, BLUE);
|
||||||
|
|
||||||
// Draw playing timeline with keyframes for anim1[]
|
// Draw playing timeline with keyframes for anim1[]
|
||||||
@ -257,7 +257,7 @@ int main(void)
|
|||||||
TextFormat("FRAME: %.2f / %i", animFrameProgress1, anims[animIndex1].keyframeCount),
|
TextFormat("FRAME: %.2f / %i", animFrameProgress1, anims[animIndex1].keyframeCount),
|
||||||
&animFrameProgress1, 0.0f, (float)anims[animIndex1].keyframeCount);
|
&animFrameProgress1, 0.0f, (float)anims[animIndex1].keyframeCount);
|
||||||
for (int i = 0; i < anims[animIndex1].keyframeCount; i++)
|
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);
|
GetScreenHeight() - 30, 1, 20, BLUE);
|
||||||
//---------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -270,7 +270,7 @@ int main(void)
|
|||||||
UnloadModelAnimations(anims, animCount); // Unload model animation
|
UnloadModelAnimations(anims, animCount); // Unload model animation
|
||||||
UnloadModel(model); // Unload model and meshes/material
|
UnloadModel(model); // Unload model and meshes/material
|
||||||
UnloadShader(skinningShader); // Unload GPU skinning shader
|
UnloadShader(skinningShader); // Unload GPU skinning shader
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -94,26 +94,26 @@ int main(void)
|
|||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
|
|
||||||
DrawModel(model, position, 1.0f, WHITE);
|
DrawModel(model, position, 1.0f, WHITE);
|
||||||
|
|
||||||
DrawGrid(10, 1.0f);
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
// Draw UI, select anim and playing speed
|
// Draw UI, select anim and playing speed
|
||||||
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 1);
|
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;
|
&animIndex, dropdownEditMode)) dropdownEditMode = !dropdownEditMode;
|
||||||
|
|
||||||
GuiSlider((Rectangle){ 260, 10, 500, 24 }, "FRAME SPEED: ", TextFormat("x%.1f", animFrameSpeed),
|
GuiSlider((Rectangle){ 260, 10, 500, 24 }, "FRAME SPEED: ", TextFormat("x%.1f", animFrameSpeed),
|
||||||
&animFrameSpeed, 0.1f, 2.0f);
|
&animFrameSpeed, 0.1f, 2.0f);
|
||||||
|
|
||||||
// Draw playing timeline with keyframes
|
// 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));
|
TextFormat("CURRENT FRAME: %.2f / %i", animFrameProgress, anims[animIndex].keyframeCount));
|
||||||
GuiProgressBar((Rectangle){ 10, GetScreenHeight() - 40.0f, GetScreenWidth() - 20.0f, 24 }, NULL, NULL,
|
GuiProgressBar((Rectangle){ 10, GetScreenHeight() - 40.0f, GetScreenWidth() - 20.0f, 24 }, NULL, NULL,
|
||||||
&animFrameProgress, 0.0f, (float)anims[animIndex].keyframeCount);
|
&animFrameProgress, 0.0f, (float)anims[animIndex].keyframeCount);
|
||||||
for (int i = 0; i < anims[animIndex].keyframeCount; i++)
|
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);
|
GetScreenHeight() - 40, 1, 24, BLUE);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|||||||
@ -60,7 +60,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the closest voxel if one was hit
|
// Remove the closest voxel if one was hit
|
||||||
if (voxelFound)
|
if (voxelFound)
|
||||||
{
|
{
|
||||||
@ -145,9 +145,9 @@ int main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
// Draw reference point for raycasting to delete blocks
|
// Draw reference point for raycasting to delete blocks
|
||||||
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 4, RED);
|
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 4, RED);
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ int main(void)
|
|||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadModel(cubeModel);
|
UnloadModel(cubeModel);
|
||||||
|
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,7 @@ int main(void)
|
|||||||
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
||||||
|
|
||||||
bool showModel = true;
|
bool showModel = true;
|
||||||
Model decalModels[MAX_DECALS] = { 0 };
|
static Model decalModels[MAX_DECALS] = { 0 };
|
||||||
int decalCount = 0;
|
int decalCount = 0;
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
#include "rlgl.h"
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: rand()
|
#include <stdlib.h> // Required for: rand()
|
||||||
#include <math.h> // Required for: cosf(), sinf()
|
#include <math.h> // Required for: cosf(), sinf()
|
||||||
@ -26,8 +27,9 @@
|
|||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module Functions Declaration
|
// Module Functions Declaration
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Generate mesh using points
|
static Mesh GenMeshPoints(int numPoints); // Generate mesh using points
|
||||||
static Mesh GenMeshPoints(int numPoints);
|
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points
|
||||||
|
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
@ -184,3 +186,30 @@ static Mesh GenMeshPoints(int numPoints)
|
|||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Draw a model points
|
||||||
|
// WARNING: OpenGL ES 2.0 does not support point mode drawing
|
||||||
|
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint)
|
||||||
|
{
|
||||||
|
rlEnablePointMode();
|
||||||
|
rlDisableBackfaceCulling();
|
||||||
|
|
||||||
|
DrawModel(model, position, scale, tint);
|
||||||
|
|
||||||
|
rlEnableBackfaceCulling();
|
||||||
|
rlDisablePointMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a model points
|
||||||
|
// WARNING: OpenGL ES 2.0 does not support point mode drawing
|
||||||
|
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||||
|
{
|
||||||
|
rlEnablePointMode();
|
||||||
|
rlDisableBackfaceCulling();
|
||||||
|
|
||||||
|
DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
|
||||||
|
|
||||||
|
rlEnableBackfaceCulling();
|
||||||
|
rlDisablePointMode();
|
||||||
|
}
|
||||||
|
|||||||
@ -92,7 +92,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
else
|
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()
|
// and generate the required cubemap image to be passed to rlLoadTextureCubemap()
|
||||||
Image image = LoadImage("resources/skybox.png");
|
Image image = LoadImage("resources/skybox.png");
|
||||||
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
|
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
|
||||||
|
|||||||
@ -41,6 +41,9 @@ int main(void)
|
|||||||
|
|
||||||
Model model = LoadModel("resources/models/obj/plane.obj"); // Load model
|
Model model = LoadModel("resources/models/obj/plane.obj"); // Load model
|
||||||
Texture2D texture = LoadTexture("resources/models/obj/plane_diffuse.png"); // Load model texture
|
Texture2D texture = LoadTexture("resources/models/obj/plane_diffuse.png"); // Load model texture
|
||||||
|
|
||||||
|
SetTextureWrap(texture, TEXTURE_WRAP_REPEAT); // Force Repeat to avoid issue on Web version
|
||||||
|
|
||||||
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
|
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
|
||||||
|
|
||||||
float pitch = 0.0f;
|
float pitch = 0.0f;
|
||||||
|
|||||||
@ -13,9 +13,9 @@
|
|||||||
| models/vox/chr_knight.vox | ❔ | ❔ | - |
|
| models/vox/chr_knight.vox | ❔ | ❔ | - |
|
||||||
| models/vox/chr_sword.vox | ❔ | ❔ | - |
|
| models/vox/chr_sword.vox | ❔ | ❔ | - |
|
||||||
| models/vox/monu9.vox | ❔ | ❔ | - |
|
| models/vox/monu9.vox | ❔ | ❔ | - |
|
||||||
| billboard.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
| billboard.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||||
| cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
| cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||||
| cubicmap_atlas.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
| cubicmap_atlas.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||||
| heightmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
| heightmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||||
| dresden_square_1k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
|
| dresden_square_1k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
|
||||||
| dresden_square_2k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
|
| dresden_square_2k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
|
||||||
|
|||||||
@ -14,7 +14,7 @@ void main()
|
|||||||
{
|
{
|
||||||
// Fetch color from texture sampler
|
// Fetch color from texture sampler
|
||||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||||
|
|
||||||
// Calculate final fragment color
|
// Calculate final fragment color
|
||||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ void main()
|
|||||||
int boneIndex1 = int(vertexBoneIndices.y);
|
int boneIndex1 = int(vertexBoneIndices.y);
|
||||||
int boneIndex2 = int(vertexBoneIndices.z);
|
int boneIndex2 = int(vertexBoneIndices.z);
|
||||||
int boneIndex3 = int(vertexBoneIndices.w);
|
int boneIndex3 = int(vertexBoneIndices.w);
|
||||||
|
|
||||||
// WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
|
// WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
|
||||||
mat4 boneMatrixTransposed0 = mat4(
|
mat4 boneMatrixTransposed0 = mat4(
|
||||||
vec4(boneMatrices[boneIndex0][0].x, boneMatrices[boneIndex0][1].x, boneMatrices[boneIndex0][2].x, boneMatrices[boneIndex0][3].x),
|
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].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].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(boneMatrices[boneIndex3][0].w, boneMatrices[boneIndex3][1].w, boneMatrices[boneIndex3][2].w, boneMatrices[boneIndex3][3].w));
|
||||||
|
|
||||||
vec4 skinnedPosition =
|
vec4 skinnedPosition =
|
||||||
vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
|
vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
|
||||||
|
|
||||||
fragTexCoord = vertexTexCoord;
|
fragTexCoord = vertexTexCoord;
|
||||||
fragColor = vertexColor;
|
fragColor = vertexColor;
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ void main()
|
|||||||
{
|
{
|
||||||
// Fetch color from texture sampler
|
// Fetch color from texture sampler
|
||||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||||
|
|
||||||
// Calculate final fragment color
|
// Calculate final fragment color
|
||||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ void main()
|
|||||||
int boneIndex1 = int(vertexBoneIndices.y);
|
int boneIndex1 = int(vertexBoneIndices.y);
|
||||||
int boneIndex2 = int(vertexBoneIndices.z);
|
int boneIndex2 = int(vertexBoneIndices.z);
|
||||||
int boneIndex3 = int(vertexBoneIndices.w);
|
int boneIndex3 = int(vertexBoneIndices.w);
|
||||||
|
|
||||||
// WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
|
// WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
|
||||||
mat4 boneMatrixTransposed0 = mat4(
|
mat4 boneMatrixTransposed0 = mat4(
|
||||||
vec4(boneMatrices[boneIndex0][0].x, boneMatrices[boneIndex0][1].x, boneMatrices[boneIndex0][2].x, boneMatrices[boneIndex0][3].x),
|
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].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].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(boneMatrices[boneIndex3][0].w, boneMatrices[boneIndex3][1].w, boneMatrices[boneIndex3][2].w, boneMatrices[boneIndex3][3].w));
|
||||||
|
|
||||||
vec4 skinnedPosition =
|
vec4 skinnedPosition =
|
||||||
vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
|
vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
|
||||||
|
|
||||||
fragTexCoord = vertexTexCoord;
|
fragTexCoord = vertexTexCoord;
|
||||||
fragColor = vertexColor;
|
fragColor = vertexColor;
|
||||||
|
|
||||||
|
|||||||
@ -26,17 +26,17 @@ void main()
|
|||||||
int boneIndex1 = int(vertexBoneIndices.y);
|
int boneIndex1 = int(vertexBoneIndices.y);
|
||||||
int boneIndex2 = int(vertexBoneIndices.z);
|
int boneIndex2 = int(vertexBoneIndices.z);
|
||||||
int boneIndex3 = int(vertexBoneIndices.w);
|
int boneIndex3 = int(vertexBoneIndices.w);
|
||||||
|
|
||||||
vec4 skinnedPosition =
|
vec4 skinnedPosition =
|
||||||
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) +
|
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) +
|
||||||
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexPosition, 1.0));
|
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexPosition, 1.0));
|
||||||
|
|
||||||
vec4 skinnedNormal =
|
vec4 skinnedNormal =
|
||||||
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexNormal, 0.0)) +
|
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexNormal, 0.0)) +
|
||||||
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexNormal, 0.0)) +
|
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexNormal, 0.0)) +
|
||||||
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexNormal, 0.0)) +
|
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexNormal, 0.0)) +
|
||||||
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexNormal, 0.0));
|
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexNormal, 0.0));
|
||||||
skinnedNormal.w = 0.0;
|
skinnedNormal.w = 0.0;
|
||||||
|
|
||||||
|
|||||||
@ -58,12 +58,12 @@ void main()
|
|||||||
float gray = GreyScale(cellColor);
|
float gray = GreyScale(cellColor);
|
||||||
|
|
||||||
float n = 4096.0;
|
float n = 4096.0;
|
||||||
|
|
||||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||||
if (gray > 0.2) n = 65600.0; // :
|
if (gray > 0.2) n = 65600.0; // :
|
||||||
if (gray > 0.3) n = 18725316.0; // v
|
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.5) n = 13121101.0; // &
|
||||||
if (gray > 0.6) n = 15252014.0; // 8
|
if (gray > 0.6) n = 15252014.0; // 8
|
||||||
if (gray > 0.7) n = 13195790.0; // @
|
if (gray > 0.7) n = 13195790.0; // @
|
||||||
|
|||||||
@ -12,5 +12,5 @@ void main()
|
|||||||
fragTexCoord = vertexTexCoord;
|
fragTexCoord = vertexTexCoord;
|
||||||
|
|
||||||
// Calculate final vertex position
|
// Calculate final vertex position
|
||||||
gl_Position = vec4(vertexPosition, 1.0);
|
gl_Position = vec4(vertexPosition, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#version 100
|
#version 100
|
||||||
#extension GL_EXT_frag_depth : enable
|
#extension GL_EXT_frag_depth : enable
|
||||||
|
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ uniform vec4 colDiffuse;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||||
|
|
||||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||||
gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
|
gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,13 +24,13 @@ void main()
|
|||||||
{
|
{
|
||||||
// Store the fragment position vector in the first gbuffer texture
|
// Store the fragment position vector in the first gbuffer texture
|
||||||
//gPosition = fragPosition;
|
//gPosition = fragPosition;
|
||||||
|
|
||||||
// Store the per-fragment normals into the gbuffer
|
// Store the per-fragment normals into the gbuffer
|
||||||
//gNormal = normalize(fragNormal);
|
//gNormal = normalize(fragNormal);
|
||||||
|
|
||||||
// Store the diffuse per-fragment color
|
// Store the diffuse per-fragment color
|
||||||
gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
|
gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
|
||||||
|
|
||||||
// Store specular intensity in gAlbedoSpec's alpha component
|
// Store specular intensity in gAlbedoSpec's alpha component
|
||||||
gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
|
gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ void main()
|
|||||||
{
|
{
|
||||||
// Calculate vertex attributes for fragment shader
|
// Calculate vertex attributes for fragment shader
|
||||||
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
||||||
fragPosition = worldPos.xyz;
|
fragPosition = worldPos.xyz;
|
||||||
fragTexCoord = vertexTexCoord;
|
fragTexCoord = vertexTexCoord;
|
||||||
fragColor = vertexColor;
|
fragColor = vertexColor;
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#version 100
|
#version 100
|
||||||
|
|
||||||
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
||||||
|
|
||||||
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
||||||
|
|
||||||
varying vec2 fragTexCoord;
|
varying vec2 fragTexCoord;
|
||||||
|
|||||||
@ -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);
|
p.x = abs(p.x);
|
||||||
float l = length(p.xy);
|
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;
|
c.y, c.x)*p.xy;
|
||||||
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
|
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.x>0.0)?p.y:l);
|
||||||
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
|
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 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
|
||||||
vec2 d = abs(q) - w;
|
vec2 d = abs(q) - w;
|
||||||
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
|
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);
|
vec2 q = vec2(length(ap.yz), ap.x);
|
||||||
|
|
||||||
float w = sqrt(r*r-h*h);
|
float w = sqrt(r*r-h*h);
|
||||||
|
|
||||||
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : abs(length(q)-r)) - t;
|
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;
|
if (t>tmax) break;
|
||||||
vec2 h = map(ro+rd*t);
|
vec2 h = map(ro+rd*t);
|
||||||
if (abs(h.x) < (0.0001*t))
|
if (abs(h.x) < (0.0001*t))
|
||||||
{
|
{
|
||||||
res = vec2(t,h.y);
|
res = vec2(t,h.y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t += h.x;
|
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)
|
vec3 calcNormal(in vec3 pos)
|
||||||
{
|
{
|
||||||
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
|
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
|
||||||
return normalize(e.xyy*map(pos + e.xyy).x +
|
return normalize(e.xyy*map(pos + e.xyy).x +
|
||||||
e.yyx*map(pos + e.yyx).x +
|
e.yyx*map(pos + e.yyx).x +
|
||||||
e.yxy*map(pos + e.yxy).x +
|
e.yxy*map(pos + e.yxy).x +
|
||||||
e.xxx*map(pos + e.xxx).x);
|
e.xxx*map(pos + e.xxx).x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,15 +176,15 @@ float checkersGradBox(in vec2 p)
|
|||||||
// analytical integral (box filter)
|
// 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;
|
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
|
// 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
|
// https://www.shadertoy.com/view/tdS3DG
|
||||||
vec4 render(in vec3 ro, in vec3 rd)
|
vec4 render(in vec3 ro, in vec3 rd)
|
||||||
{
|
{
|
||||||
// background
|
// background
|
||||||
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
|
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
|
||||||
|
|
||||||
// raycast scene
|
// raycast scene
|
||||||
vec2 res = raycast(ro,rd);
|
vec2 res = raycast(ro,rd);
|
||||||
float t = res.x;
|
float t = res.x;
|
||||||
@ -194,11 +194,11 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
vec3 pos = ro + t*rd;
|
vec3 pos = ro + t*rd;
|
||||||
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
||||||
vec3 ref = reflect(rd, nor);
|
vec3 ref = reflect(rd, nor);
|
||||||
|
|
||||||
// material
|
// material
|
||||||
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
||||||
float ks = 1.0;
|
float ks = 1.0;
|
||||||
|
|
||||||
if (m<1.5)
|
if (m<1.5)
|
||||||
{
|
{
|
||||||
float f = checkersGradBox(3.0*pos.xz);
|
float f = checkersGradBox(3.0*pos.xz);
|
||||||
@ -208,7 +208,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
|
|
||||||
// lighting
|
// lighting
|
||||||
float occ = calcAO(pos, nor);
|
float occ = calcAO(pos, nor);
|
||||||
|
|
||||||
vec3 lin = vec3(0.0);
|
vec3 lin = vec3(0.0);
|
||||||
|
|
||||||
// sun
|
// sun
|
||||||
@ -249,7 +249,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
dif *= occ;
|
dif *= occ;
|
||||||
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
|
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
|
||||||
}
|
}
|
||||||
|
|
||||||
col = lin;
|
col = lin;
|
||||||
|
|
||||||
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
|
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;
|
color = res.xyz;
|
||||||
depth = CalcDepth(rd,res.w);
|
depth = CalcDepth(rd,res.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_FragColor = vec4(color , 1.0);
|
gl_FragColor = vec4(color , 1.0);
|
||||||
gl_FragDepthEXT = depth;
|
gl_FragDepthEXT = depth;
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ void main()
|
|||||||
float normR = float(iter - (iter/55)*55)/55.0;
|
float normR = float(iter - (iter/55)*55)/55.0;
|
||||||
float normG = float(iter - (iter/69)*69)/69.0;
|
float normG = float(iter - (iter/69)*69)/69.0;
|
||||||
float normB = float(iter - (iter/40)*40)/40.0;
|
float normB = float(iter - (iter/40)*40)/40.0;
|
||||||
|
|
||||||
gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
|
gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,7 +52,7 @@ void main()
|
|||||||
|
|
||||||
float specCo = 0.0;
|
float specCo = 0.0;
|
||||||
|
|
||||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
|
||||||
|
|
||||||
specular += specCo;
|
specular += specCo;
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ void main()
|
|||||||
// Convert the (normalized) texel color RED component (GB would work, too)
|
// Convert the (normalized) texel color RED component (GB would work, too)
|
||||||
// to the palette index by scaling up from [0..1] to [0..255]
|
// to the palette index by scaling up from [0..1] to [0..255]
|
||||||
int index = int(texelColor.r*255.0);
|
int index = int(texelColor.r*255.0);
|
||||||
|
|
||||||
ivec3 color = ivec3(0);
|
ivec3 color = ivec3(0);
|
||||||
|
|
||||||
// NOTE: On GLSL 100 we are not allowed to index a uniform array by a variable value,
|
// 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 == 5) color = palette[5];
|
||||||
else if (index == 6) color = palette[6];
|
else if (index == 6) color = palette[6];
|
||||||
else if (index == 7) color = palette[7];
|
else if (index == 7) color = palette[7];
|
||||||
|
|
||||||
//gl_FragColor = texture2D(palette, texelColor.xy); // Alternative to ivec3
|
//gl_FragColor = texture2D(palette, texelColor.xy); // Alternative to ivec3
|
||||||
|
|
||||||
// Calculate final fragment color. Note that the palette color components
|
// 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;
|
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);
|
albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
|
||||||
|
|
||||||
float metallic = clamp(metallicValue, 0.0, 1.0);
|
float metallic = clamp(metallicValue, 0.0, 1.0);
|
||||||
float roughness = clamp(roughnessValue, 0.0, 1.0);
|
float roughness = clamp(roughnessValue, 0.0, 1.0);
|
||||||
float ao = clamp(aoValue, 0.0, 1.0);
|
float ao = clamp(aoValue, 0.0, 1.0);
|
||||||
|
|
||||||
if (useTexMRA == 1)
|
if (useTexMRA == 1)
|
||||||
{
|
{
|
||||||
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
|
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 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
|
||||||
|
|
||||||
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
|
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
|
||||||
|
|
||||||
// Difuse and spec light can't be above 1.0
|
// Difuse and spec light can't be above 1.0
|
||||||
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
||||||
vec3 kD = vec3(1.0) - F;
|
vec3 kD = vec3(1.0) - F;
|
||||||
|
|
||||||
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
|
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
|
||||||
kD *= 1.0 - metallic;
|
kD *= 1.0 - metallic;
|
||||||
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result
|
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;
|
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
|
||||||
|
|
||||||
return (ambientFinal + lightAccum*ao + emissive);
|
return (ambientFinal + lightAccum*ao + emissive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ void main()
|
|||||||
|
|
||||||
// HDR tonemapping
|
// HDR tonemapping
|
||||||
color = pow(color, color + vec3(1.0));
|
color = pow(color, color + vec3(1.0));
|
||||||
|
|
||||||
// Gamma correction
|
// Gamma correction
|
||||||
color = pow(color, vec3(1.0/2.2));
|
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);
|
float bias = max(0.0008*(1.0 - dot(normal, l)), 0.00008);
|
||||||
int shadowCounter = 0;
|
int shadowCounter = 0;
|
||||||
const int numSamples = 9;
|
const int numSamples = 9;
|
||||||
|
|
||||||
// PCF (percentage-closer filtering) algorithm:
|
// PCF (percentage-closer filtering) algorithm:
|
||||||
// Instead of testing if just one point is closer to the current point,
|
// Instead of testing if just one point is closer to the current point,
|
||||||
// we test the surrounding points as well
|
// we test the surrounding points as well
|
||||||
@ -74,7 +74,7 @@ void main()
|
|||||||
if (curDepth - bias > sampleDepth) shadowCounter++;
|
if (curDepth - bias > sampleDepth) shadowCounter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
|
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
|
||||||
|
|
||||||
// Add ambient lighting whether in shadow or not
|
// Add ambient lighting whether in shadow or not
|
||||||
|
|||||||
@ -56,12 +56,12 @@ void main()
|
|||||||
float gray = GreyScale(cellColor);
|
float gray = GreyScale(cellColor);
|
||||||
|
|
||||||
float n = 4096.0;
|
float n = 4096.0;
|
||||||
|
|
||||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||||
if (gray > 0.2) n = 65600.0; // :
|
if (gray > 0.2) n = 65600.0; // :
|
||||||
if (gray > 0.3) n = 18725316.0; // v
|
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.5) n = 13121101.0; // &
|
||||||
if (gray > 0.6) n = 15252014.0; // 8
|
if (gray > 0.6) n = 15252014.0; // 8
|
||||||
if (gray > 0.7) n = 13195790.0; // @
|
if (gray > 0.7) n = 13195790.0; // @
|
||||||
|
|||||||
@ -12,5 +12,5 @@ void main()
|
|||||||
fragTexCoord = vertexTexCoord;
|
fragTexCoord = vertexTexCoord;
|
||||||
|
|
||||||
// Calculate final vertex position
|
// Calculate final vertex position
|
||||||
gl_Position = vec4(vertexPosition, 1.0);
|
gl_Position = vec4(vertexPosition, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
#extension GL_EXT_frag_depth : enable
|
#extension GL_EXT_frag_depth : enable
|
||||||
|
|
||||||
varying vec2 fragTexCoord;
|
varying vec2 fragTexCoord;
|
||||||
varying vec4 fragColor;
|
varying vec4 fragColor;
|
||||||
@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||||
|
|
||||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||||
gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
|
gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
|
||||||
}
|
}
|
||||||
@ -22,13 +22,13 @@ void main()
|
|||||||
{
|
{
|
||||||
// Store the fragment position vector in the first gbuffer texture
|
// Store the fragment position vector in the first gbuffer texture
|
||||||
//gPosition = fragPosition;
|
//gPosition = fragPosition;
|
||||||
|
|
||||||
// Store the per-fragment normals into the gbuffer
|
// Store the per-fragment normals into the gbuffer
|
||||||
//gNormal = normalize(fragNormal);
|
//gNormal = normalize(fragNormal);
|
||||||
|
|
||||||
// Store the diffuse per-fragment color
|
// Store the diffuse per-fragment color
|
||||||
gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
|
gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
|
||||||
|
|
||||||
// Store specular intensity in gAlbedoSpec's alpha component
|
// Store specular intensity in gAlbedoSpec's alpha component
|
||||||
gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
|
gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ void main()
|
|||||||
{
|
{
|
||||||
// Calculate vertex attributes for fragment shader
|
// Calculate vertex attributes for fragment shader
|
||||||
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
||||||
fragPosition = worldPos.xyz;
|
fragPosition = worldPos.xyz;
|
||||||
fragTexCoord = vertexTexCoord;
|
fragTexCoord = vertexTexCoord;
|
||||||
fragColor = vertexColor;
|
fragColor = vertexColor;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#version 120
|
#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 vec2 fragTexCoord;
|
||||||
varying vec4 fragColor;
|
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);
|
p.x = abs(p.x);
|
||||||
float l = length(p.xy);
|
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;
|
c.y, c.x)*p.xy;
|
||||||
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
|
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.x>0.0)?p.y:l);
|
||||||
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
|
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 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
|
||||||
vec2 d = abs(q) - w;
|
vec2 d = abs(q) - w;
|
||||||
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
|
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);
|
vec2 q = vec2(length(ap.yz), ap.x);
|
||||||
|
|
||||||
float w = sqrt(r*r-h*h);
|
float w = sqrt(r*r-h*h);
|
||||||
|
|
||||||
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : abs(length(q)-r)) - t;
|
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;
|
if (t>tmax) break;
|
||||||
vec2 h = map(ro+rd*t);
|
vec2 h = map(ro+rd*t);
|
||||||
if (abs(h.x) < (0.0001*t))
|
if (abs(h.x) < (0.0001*t))
|
||||||
{
|
{
|
||||||
res = vec2(t,h.y);
|
res = vec2(t,h.y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t += h.x;
|
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)
|
vec3 calcNormal(in vec3 pos)
|
||||||
{
|
{
|
||||||
vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
|
vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
|
||||||
return normalize(e.xyy*map(pos + e.xyy).x +
|
return normalize(e.xyy*map(pos + e.xyy).x +
|
||||||
e.yyx*map(pos + e.yyx).x +
|
e.yyx*map(pos + e.yyx).x +
|
||||||
e.yxy*map(pos + e.yxy).x +
|
e.yxy*map(pos + e.yxy).x +
|
||||||
e.xxx*map(pos + e.xxx).x);
|
e.xxx*map(pos + e.xxx).x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,15 +174,15 @@ float checkersGradBox(in vec2 p)
|
|||||||
// analytical integral (box filter)
|
// 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;
|
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
|
// 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
|
// https://www.shadertoy.com/view/tdS3DG
|
||||||
vec4 render(in vec3 ro, in vec3 rd)
|
vec4 render(in vec3 ro, in vec3 rd)
|
||||||
{
|
{
|
||||||
// background
|
// background
|
||||||
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
|
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
|
||||||
|
|
||||||
// raycast scene
|
// raycast scene
|
||||||
vec2 res = raycast(ro,rd);
|
vec2 res = raycast(ro,rd);
|
||||||
float t = res.x;
|
float t = res.x;
|
||||||
@ -192,11 +192,11 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
vec3 pos = ro + t*rd;
|
vec3 pos = ro + t*rd;
|
||||||
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
||||||
vec3 ref = reflect(rd, nor);
|
vec3 ref = reflect(rd, nor);
|
||||||
|
|
||||||
// material
|
// material
|
||||||
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
||||||
float ks = 1.0;
|
float ks = 1.0;
|
||||||
|
|
||||||
if (m<1.5)
|
if (m<1.5)
|
||||||
{
|
{
|
||||||
float f = checkersGradBox(3.0*pos.xz);
|
float f = checkersGradBox(3.0*pos.xz);
|
||||||
@ -206,7 +206,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
|
|
||||||
// lighting
|
// lighting
|
||||||
float occ = calcAO(pos, nor);
|
float occ = calcAO(pos, nor);
|
||||||
|
|
||||||
vec3 lin = vec3(0.0);
|
vec3 lin = vec3(0.0);
|
||||||
|
|
||||||
// sun
|
// sun
|
||||||
@ -247,7 +247,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
dif *= occ;
|
dif *= occ;
|
||||||
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
|
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
|
||||||
}
|
}
|
||||||
|
|
||||||
col = lin;
|
col = lin;
|
||||||
|
|
||||||
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
|
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;
|
float specCo = 0.0;
|
||||||
|
|
||||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
|
||||||
|
|
||||||
specular += specCo;
|
specular += specCo;
|
||||||
|
|
||||||
|
|||||||
@ -81,11 +81,11 @@ vec3 ComputePBR()
|
|||||||
{
|
{
|
||||||
vec3 albedo = texture2D(albedoMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
|
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);
|
albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
|
||||||
|
|
||||||
float metallic = clamp(metallicValue, 0.0, 1.0);
|
float metallic = clamp(metallicValue, 0.0, 1.0);
|
||||||
float roughness = clamp(roughnessValue, 0.0, 1.0);
|
float roughness = clamp(roughnessValue, 0.0, 1.0);
|
||||||
float ao = clamp(aoValue, 0.0, 1.0);
|
float ao = clamp(aoValue, 0.0, 1.0);
|
||||||
|
|
||||||
if (useTexMRA == 1)
|
if (useTexMRA == 1)
|
||||||
{
|
{
|
||||||
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
|
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 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
|
||||||
|
|
||||||
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
|
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
|
||||||
|
|
||||||
// Difuse and spec light can't be above 1.0
|
// Difuse and spec light can't be above 1.0
|
||||||
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
||||||
vec3 kD = vec3(1.0) - F;
|
vec3 kD = vec3(1.0) - F;
|
||||||
|
|
||||||
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
|
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
|
||||||
kD *= 1.0 - metallic;
|
kD *= 1.0 - metallic;
|
||||||
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result
|
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;
|
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
|
||||||
|
|
||||||
return (ambientFinal + lightAccum*ao + emissive);
|
return (ambientFinal + lightAccum*ao + emissive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ void main()
|
|||||||
|
|
||||||
// HDR tonemapping
|
// HDR tonemapping
|
||||||
color = pow(color, color + vec3(1.0));
|
color = pow(color, color + vec3(1.0));
|
||||||
|
|
||||||
// Gamma correction
|
// Gamma correction
|
||||||
color = pow(color, vec3(1.0/2.2));
|
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);
|
float bias = max(0.0008*(1.0 - dot(normal, l)), 0.00008);
|
||||||
int shadowCounter = 0;
|
int shadowCounter = 0;
|
||||||
const int numSamples = 9;
|
const int numSamples = 9;
|
||||||
|
|
||||||
// PCF (percentage-closer filtering) algorithm:
|
// PCF (percentage-closer filtering) algorithm:
|
||||||
// Instead of testing if just one point is closer to the current point,
|
// Instead of testing if just one point is closer to the current point,
|
||||||
// we test the surrounding points as well
|
// we test the surrounding points as well
|
||||||
@ -72,7 +72,7 @@ void main()
|
|||||||
if (curDepth - bias > sampleDepth) shadowCounter++;
|
if (curDepth - bias > sampleDepth) shadowCounter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
|
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
|
||||||
|
|
||||||
// Add ambient lighting whether in shadow or not
|
// Add ambient lighting whether in shadow or not
|
||||||
|
|||||||
@ -52,12 +52,12 @@ void main()
|
|||||||
float gray = GreyScale(cellColor);
|
float gray = GreyScale(cellColor);
|
||||||
|
|
||||||
int n = 4096;
|
int n = 4096;
|
||||||
|
|
||||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||||
if (gray > 0.2) n = 65600; // :
|
if (gray > 0.2) n = 65600; // :
|
||||||
if (gray > 0.3) n = 18725316; // v
|
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.5) n = 13121101; // &
|
||||||
if (gray > 0.6) n = 15252014; // 8
|
if (gray > 0.6) n = 15252014; // 8
|
||||||
if (gray > 0.7) n = 13195790; // @
|
if (gray > 0.7) n = 13195790; // @
|
||||||
|
|||||||
@ -20,7 +20,7 @@ void main()
|
|||||||
|
|
||||||
// NOTE: Implement here your fragment shader code
|
// 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 tint color (colDiffuse)
|
||||||
// times the fragment color (interpolated vertex color)
|
// times the fragment color (interpolated vertex color)
|
||||||
finalColor = texelColor*colDiffuse*fragColor;
|
finalColor = texelColor*colDiffuse*fragColor;
|
||||||
|
|||||||
@ -14,7 +14,7 @@ out vec4 finalColor;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||||
|
|
||||||
finalColor = texelColor*colDiffuse*fragColor;
|
finalColor = texelColor*colDiffuse*fragColor;
|
||||||
gl_FragDepth = 1.0 - finalColor.z;
|
gl_FragDepth = 1.0 - finalColor.z;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ uniform mat4 matProjection;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
|
||||||
fragPosition = worldPos.xyz;
|
fragPosition = worldPos.xyz;
|
||||||
fragTexCoord = vertexTexCoord;
|
fragTexCoord = vertexTexCoord;
|
||||||
|
|
||||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||||
|
|||||||
@ -16,7 +16,7 @@ out vec4 finalColor;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||||
|
|
||||||
finalColor = texelColor*colDiffuse*fragColor;
|
finalColor = texelColor*colDiffuse*fragColor;
|
||||||
gl_FragDepth = finalColor.z;
|
gl_FragDepth = finalColor.z;
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
|
|||||||
p.xy = mat2(-c.x, c.y, c.y, c.x)*p.xy;
|
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.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);
|
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 q = vec2(length(max(p.xy, 0.0)) + min(0.0, max(p.x, p.y)), p.z);
|
||||||
vec2 d = abs(q) - w;
|
vec2 d = abs(q) - w;
|
||||||
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
|
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
|
||||||
@ -54,7 +54,7 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
|
|||||||
|
|
||||||
vec2 q = vec2(length(ap.yz), ap.x);
|
vec2 q = vec2(length(ap.yz), ap.x);
|
||||||
float w = sqrt(r*r-h*h);
|
float w = sqrt(r*r-h*h);
|
||||||
|
|
||||||
return ((h*q.x < w*q.y)? length(q - vec2(w, h)) : abs(length(q) - r)) - t;
|
return ((h*q.x < w*q.y)? length(q - vec2(w, h)) : abs(length(q) - r)) - t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ vec2 map(in vec3 pos)
|
|||||||
{
|
{
|
||||||
vec2 res = vec2(sdHorseshoe(pos - vec3(-1.0, 0.08, 1.0), vec2(cos(1.3), sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5);
|
vec2 res = vec2(sdHorseshoe(pos - vec3(-1.0, 0.08, 1.0), vec2(cos(1.3), sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5);
|
||||||
res = opU(res, vec2(sdSixWayCutHollowSphere(pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5));
|
res = opU(res, vec2(sdSixWayCutHollowSphere(pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,8 +105,8 @@ vec2 raycast(in vec3 ro, in vec3 rd)
|
|||||||
if (t > tmax) break;
|
if (t > tmax) break;
|
||||||
vec2 h = map(ro + rd*t);
|
vec2 h = map(ro + rd*t);
|
||||||
if (abs(h.x )< (0.0001*t))
|
if (abs(h.x )< (0.0001*t))
|
||||||
{
|
{
|
||||||
res = vec2(t, h.y);
|
res = vec2(t, h.y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t += h.x;
|
t += h.x;
|
||||||
@ -131,9 +131,9 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
|
|||||||
t += clamp(h, 0.01, 0.2);
|
t += clamp(h, 0.01, 0.2);
|
||||||
if ((res < 0.004) || (t > tmax)) break;
|
if ((res < 0.004) || (t > tmax)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = clamp(res, 0.0, 1.0);
|
res = clamp(res, 0.0, 1.0);
|
||||||
|
|
||||||
return res*res*(3.0-2.0*res);
|
return res*res*(3.0-2.0*res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,9 +141,9 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
|
|||||||
vec3 calcNormal(in vec3 pos)
|
vec3 calcNormal(in vec3 pos)
|
||||||
{
|
{
|
||||||
vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
|
vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
|
||||||
return normalize(e.xyy*map(pos + e.xyy).x +
|
return normalize(e.xyy*map(pos + e.xyy).x +
|
||||||
e.yyx*map(pos + e.yyx).x +
|
e.yyx*map(pos + e.yyx).x +
|
||||||
e.yxy*map(pos + e.yxy).x +
|
e.yxy*map(pos + e.yxy).x +
|
||||||
e.xxx*map(pos + e.xxx).x);
|
e.xxx*map(pos + e.xxx).x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ float calcAO(in vec3 pos, in vec3 nor)
|
|||||||
sca *= 0.95;
|
sca *= 0.95;
|
||||||
if (occ>0.35) break;
|
if (occ>0.35) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y);
|
return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,15 +172,15 @@ float checkersGradBox(in vec2 p)
|
|||||||
// analytical integral (box filter)
|
// 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;
|
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
|
// 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
|
// https://www.shadertoy.com/view/tdS3DG
|
||||||
vec4 render(in vec3 ro, in vec3 rd)
|
vec4 render(in vec3 ro, in vec3 rd)
|
||||||
{
|
{
|
||||||
// background
|
// background
|
||||||
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
|
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
|
||||||
|
|
||||||
// raycast scene
|
// raycast scene
|
||||||
vec2 res = raycast(ro,rd);
|
vec2 res = raycast(ro,rd);
|
||||||
float t = res.x;
|
float t = res.x;
|
||||||
@ -190,11 +190,11 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
vec3 pos = ro + t*rd;
|
vec3 pos = ro + t*rd;
|
||||||
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
||||||
vec3 ref = reflect(rd, nor);
|
vec3 ref = reflect(rd, nor);
|
||||||
|
|
||||||
// material
|
// material
|
||||||
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
||||||
float ks = 1.0;
|
float ks = 1.0;
|
||||||
|
|
||||||
if (m < 1.5)
|
if (m < 1.5)
|
||||||
{
|
{
|
||||||
float f = checkersGradBox(3.0*pos.xz);
|
float f = checkersGradBox(3.0*pos.xz);
|
||||||
@ -204,7 +204,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
|
|
||||||
// lighting
|
// lighting
|
||||||
float occ = calcAO(pos, nor);
|
float occ = calcAO(pos, nor);
|
||||||
|
|
||||||
vec3 lin = vec3(0.0);
|
vec3 lin = vec3(0.0);
|
||||||
|
|
||||||
// sun
|
// sun
|
||||||
@ -245,7 +245,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
|||||||
dif *= occ;
|
dif *= occ;
|
||||||
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
|
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
|
||||||
}
|
}
|
||||||
|
|
||||||
col = lin;
|
col = lin;
|
||||||
|
|
||||||
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
|
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
|
||||||
@ -285,7 +285,7 @@ void main()
|
|||||||
color = res.xyz;
|
color = res.xyz;
|
||||||
depth = CalcDepth(rd,res.w);
|
depth = CalcDepth(rd,res.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
finalColor = vec4(color , 1.0);
|
finalColor = vec4(color , 1.0);
|
||||||
gl_FragDepth = depth;
|
gl_FragDepth = depth;
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ void main()
|
|||||||
|
|
||||||
float specCo = 0.0;
|
float specCo = 0.0;
|
||||||
|
|
||||||
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
|
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
|
||||||
|
|
||||||
specular += specCo;
|
specular += specCo;
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ void main()
|
|||||||
// to the palette index by scaling up from [0..1] to [0..255]
|
// to the palette index by scaling up from [0..1] to [0..255]
|
||||||
int index = int(texelColor.r*255.0);
|
int index = int(texelColor.r*255.0);
|
||||||
ivec3 color = palette[index];
|
ivec3 color = palette[index];
|
||||||
|
|
||||||
//finalColor = texture(palette, texelColor.xy); // Alternative to ivec3
|
//finalColor = texture(palette, texelColor.xy); // Alternative to ivec3
|
||||||
|
|
||||||
// Calculate final fragment color. Note that the palette color components
|
// Calculate final fragment color. Note that the palette color components
|
||||||
|
|||||||
@ -84,11 +84,11 @@ vec3 ComputePBR()
|
|||||||
{
|
{
|
||||||
vec3 albedo = texture(albedoMap,vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
|
vec3 albedo = texture(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);
|
albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
|
||||||
|
|
||||||
float metallic = clamp(metallicValue, 0.0, 1.0);
|
float metallic = clamp(metallicValue, 0.0, 1.0);
|
||||||
float roughness = clamp(roughnessValue, 0.0, 1.0);
|
float roughness = clamp(roughnessValue, 0.0, 1.0);
|
||||||
float ao = clamp(aoValue, 0.0, 1.0);
|
float ao = clamp(aoValue, 0.0, 1.0);
|
||||||
|
|
||||||
if (useTexMRA == 1)
|
if (useTexMRA == 1)
|
||||||
{
|
{
|
||||||
vec4 mra = texture(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
|
vec4 mra = texture(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
|
||||||
@ -133,18 +133,18 @@ vec3 ComputePBR()
|
|||||||
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
|
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
|
||||||
|
|
||||||
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
|
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
|
||||||
|
|
||||||
// Difuse and spec light can't be above 1.0
|
// Difuse and spec light can't be above 1.0
|
||||||
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
||||||
vec3 kD = vec3(1.0) - F;
|
vec3 kD = vec3(1.0) - F;
|
||||||
|
|
||||||
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
|
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
|
||||||
kD *= 1.0 - metallic;
|
kD *= 1.0 - metallic;
|
||||||
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*lights[i].enabled; // Angle of light has impact on result
|
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*lights[i].enabled; // Angle of light has impact on result
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
|
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
|
||||||
|
|
||||||
return (ambientFinal + lightAccum*ao + emissive);
|
return (ambientFinal + lightAccum*ao + emissive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ void main()
|
|||||||
|
|
||||||
// HDR tonemapping
|
// HDR tonemapping
|
||||||
color = pow(color, color + vec3(1.0));
|
color = pow(color, color + vec3(1.0));
|
||||||
|
|
||||||
// Gamma correction
|
// Gamma correction
|
||||||
color = pow(color, vec3(1.0/2.2));
|
color = pow(color, vec3(1.0/2.2));
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ uniform mat4 mvp;
|
|||||||
uniform mat4 matModel;
|
uniform mat4 matModel;
|
||||||
uniform mat4 matNormal;
|
uniform mat4 matNormal;
|
||||||
|
|
||||||
uniform float time;
|
uniform float time;
|
||||||
|
|
||||||
uniform sampler2D perlinNoiseMap;
|
uniform sampler2D perlinNoiseMap;
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ int main(void)
|
|||||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||||
camera.fovy = 45.0f;
|
camera.fovy = 45.0f;
|
||||||
camera.projection = CAMERA_PERSPECTIVE;
|
camera.projection = CAMERA_PERSPECTIVE;
|
||||||
|
|
||||||
// Load model
|
// Load model
|
||||||
Model model = LoadModel("resources/models/old_car_new.glb");
|
Model model = LoadModel("resources/models/old_car_new.glb");
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ int main(void)
|
|||||||
TextFormat("resources/shaders/glsl%i/cel.vs", GLSL_VERSION),
|
TextFormat("resources/shaders/glsl%i/cel.vs", GLSL_VERSION),
|
||||||
TextFormat("resources/shaders/glsl%i/cel.fs", GLSL_VERSION));
|
TextFormat("resources/shaders/glsl%i/cel.fs", GLSL_VERSION));
|
||||||
celShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(celShader, "viewPos");
|
celShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(celShader, "viewPos");
|
||||||
|
|
||||||
// Apply cel shader to model, keep copy of default shader
|
// Apply cel shader to model, keep copy of default shader
|
||||||
Shader defaultShader = model.materials[0].shader;
|
Shader defaultShader = model.materials[0].shader;
|
||||||
model.materials[0].shader = celShader;
|
model.materials[0].shader = celShader;
|
||||||
@ -134,16 +134,16 @@ int main(void)
|
|||||||
// Outline pass: cull front faces, draw extruded back faces as silhouette
|
// Outline pass: cull front faces, draw extruded back faces as silhouette
|
||||||
float thickness = 0.005f;
|
float thickness = 0.005f;
|
||||||
SetShaderValue(outlineShader, outlineThicknessLoc, &thickness, SHADER_UNIFORM_FLOAT);
|
SetShaderValue(outlineShader, outlineThicknessLoc, &thickness, SHADER_UNIFORM_FLOAT);
|
||||||
|
|
||||||
rlSetCullFace(RL_CULL_FACE_FRONT);
|
rlSetCullFace(RL_CULL_FACE_FRONT);
|
||||||
|
|
||||||
model.materials[0].shader = outlineShader;
|
model.materials[0].shader = outlineShader;
|
||||||
|
|
||||||
DrawModel(model, Vector3Zero(), 0.75f, WHITE);
|
DrawModel(model, Vector3Zero(), 0.75f, WHITE);
|
||||||
|
|
||||||
if (celEnabled) model.materials[0].shader = celShader; // Apply cel shader to model
|
if (celEnabled) model.materials[0].shader = celShader; // Apply cel shader to model
|
||||||
else model.materials[0].shader = defaultShader; // Apply default shader to model
|
else model.materials[0].shader = defaultShader; // Apply default shader to model
|
||||||
|
|
||||||
rlSetCullFace(RL_CULL_FACE_BACK);
|
rlSetCullFace(RL_CULL_FACE_BACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ int main(void)
|
|||||||
UnloadModel(model);
|
UnloadModel(model);
|
||||||
UnloadShader(celShader);
|
UnloadShader(celShader);
|
||||||
UnloadShader(outlineShader);
|
UnloadShader(outlineShader);
|
||||||
|
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -210,7 +210,7 @@ int main(void)
|
|||||||
rlClearColor(0, 0, 0, 0);
|
rlClearColor(0, 0, 0, 0);
|
||||||
rlClearScreenBuffers(); // Clear color and depth buffer
|
rlClearScreenBuffers(); // Clear color and depth buffer
|
||||||
rlDisableColorBlend();
|
rlDisableColorBlend();
|
||||||
|
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
// NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader`
|
// NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader`
|
||||||
// will not work, as they won't immediately load the shader program
|
// will not work, as they won't immediately load the shader program
|
||||||
@ -226,7 +226,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
rlDisableShader();
|
rlDisableShader();
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
rlEnableColorBlend();
|
rlEnableColorBlend();
|
||||||
|
|
||||||
// Go back to the default framebufferId (0) and draw our deferred shading
|
// Go back to the default framebufferId (0) and draw our deferred shading
|
||||||
|
|||||||
@ -59,7 +59,7 @@ int main(void)
|
|||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
const int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - game of life");
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - game of life");
|
||||||
|
|
||||||
const int menuWidth = 100;
|
const int menuWidth = 100;
|
||||||
@ -81,7 +81,7 @@ int main(void)
|
|||||||
{ "Puffer train", { 0.1f, 0.5f } }, { "Glider Gun", { 0.2f, 0.2f } }, { "Breeder", { 0.1f, 0.5f } },
|
{ "Puffer train", { 0.1f, 0.5f } }, { "Glider Gun", { 0.2f, 0.2f } }, { "Breeder", { 0.1f, 0.5f } },
|
||||||
{ "Random", { 0.5f, 0.5f } }
|
{ "Random", { 0.5f, 0.5f } }
|
||||||
};
|
};
|
||||||
|
|
||||||
const int numberOfPresets = sizeof(presetPatterns)/sizeof(presetPatterns[0]);
|
const int numberOfPresets = sizeof(presetPatterns)/sizeof(presetPatterns[0]);
|
||||||
|
|
||||||
int zoom = 1;
|
int zoom = 1;
|
||||||
@ -90,7 +90,7 @@ int main(void)
|
|||||||
int framesPerStep = 1;
|
int framesPerStep = 1;
|
||||||
int frame = 0;
|
int frame = 0;
|
||||||
|
|
||||||
int preset = -1; // No button pressed for preset
|
int preset = -1; // No button pressed for preset
|
||||||
int mode = MODE_RUN; // Starting mode: running
|
int mode = MODE_RUN; // Starting mode: running
|
||||||
bool buttonZoomIn = false; // Button states: false not pressed
|
bool buttonZoomIn = false; // Button states: false not pressed
|
||||||
bool buttonZomOut = false;
|
bool buttonZomOut = false;
|
||||||
@ -185,7 +185,7 @@ int main(void)
|
|||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
imageToDraw = (Image*)RL_MALLOC(sizeof(Image));
|
imageToDraw = (Image*)RL_MALLOC(sizeof(Image));
|
||||||
*imageToDraw = LoadImageFromTexture(worldOnScreen.texture);
|
*imageToDraw = LoadImageFromTexture(worldOnScreen.texture);
|
||||||
|
|
||||||
UnloadRenderTexture(worldOnScreen);
|
UnloadRenderTexture(worldOnScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,9 +199,9 @@ int main(void)
|
|||||||
if (mouseY >= sizeInWorldY) mouseY = sizeInWorldY - 1;
|
if (mouseY >= sizeInWorldY) mouseY = sizeInWorldY - 1;
|
||||||
if (firstColor == -1) firstColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1;
|
if (firstColor == -1) firstColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1;
|
||||||
const int prevColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1;
|
const int prevColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1;
|
||||||
|
|
||||||
ImageDrawPixel(imageToDraw, mouseX, mouseY, (firstColor) ? BLACK : RAYWHITE);
|
ImageDrawPixel(imageToDraw, mouseX, mouseY, (firstColor) ? BLACK : RAYWHITE);
|
||||||
|
|
||||||
if (prevColor != firstColor) UpdateTextureRec(currentWorld->texture, (Rectangle){ floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), (float)(sizeInWorldY) }, imageToDraw->data);
|
if (prevColor != firstColor) UpdateTextureRec(currentWorld->texture, (Rectangle){ floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), (float)(sizeInWorldY) }, imageToDraw->data);
|
||||||
}
|
}
|
||||||
else firstColor = -1;
|
else firstColor = -1;
|
||||||
@ -228,7 +228,7 @@ int main(void)
|
|||||||
BeginTextureMode(*currentWorld);
|
BeginTextureMode(*currentWorld);
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
|
|
||||||
UpdateTextureRec(currentWorld->texture, (Rectangle){ worldWidth*presetPatterns[preset].position.x - pattern.width/2.0f,
|
UpdateTextureRec(currentWorld->texture, (Rectangle){ worldWidth*presetPatterns[preset].position.x - pattern.width/2.0f,
|
||||||
worldHeight*presetPatterns[preset].position.y - pattern.height/2.0f,
|
worldHeight*presetPatterns[preset].position.y - pattern.height/2.0f,
|
||||||
(float)(pattern.width), (float)(pattern.height) }, pattern.data);
|
(float)(pattern.width), (float)(pattern.height) }, pattern.data);
|
||||||
@ -256,7 +256,7 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UnloadImage(pattern);
|
UnloadImage(pattern);
|
||||||
|
|
||||||
mode = MODE_PAUSE;
|
mode = MODE_PAUSE;
|
||||||
offsetX = worldWidth*presetPatterns[preset].position.x - (float)windowWidth/zoom/2.0f;
|
offsetX = worldWidth*presetPatterns[preset].position.x - (float)windowWidth/zoom/2.0f;
|
||||||
offsetY = worldHeight*presetPatterns[preset].position.y - (float)windowHeight/zoom/2.0f;
|
offsetY = worldHeight*presetPatterns[preset].position.y - (float)windowHeight/zoom/2.0f;
|
||||||
@ -293,7 +293,7 @@ int main(void)
|
|||||||
// Draw to screen
|
// Draw to screen
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
DrawTexturePro(currentWorld->texture, textureSourceToScreen, textureOnScreen, (Vector2){ 0, 0 }, 0.0f, WHITE);
|
DrawTexturePro(currentWorld->texture, textureSourceToScreen, textureOnScreen, (Vector2){ 0, 0 }, 0.0f, WHITE);
|
||||||
|
|
||||||
DrawLine(windowWidth, 0, windowWidth, screenHeight, (Color){ 218, 218, 218, 255 });
|
DrawLine(windowWidth, 0, windowWidth, screenHeight, (Color){ 218, 218, 218, 255 });
|
||||||
|
|||||||
@ -69,7 +69,7 @@ int main(void)
|
|||||||
DrawText("USING DEFAULT SHADER", 20, 40, 10, RED);
|
DrawText("USING DEFAULT SHADER", 20, 40, 10, RED);
|
||||||
|
|
||||||
DrawCircle(80, 120, 35, DARKBLUE);
|
DrawCircle(80, 120, 35, DARKBLUE);
|
||||||
DrawCircleGradient(80, 220, 60, GREEN, SKYBLUE);
|
DrawCircleGradient((Vector2){ 80.0f, 220.0f }, 60, GREEN, SKYBLUE);
|
||||||
DrawCircleLines(80, 340, 80, DARKBLUE);
|
DrawCircleLines(80, 340, 80, DARKBLUE);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,7 @@ int main(void)
|
|||||||
// Set the texture tiling using a shader
|
// Set the texture tiling using a shader
|
||||||
float tiling[2] = { 3.0f, 3.0f };
|
float tiling[2] = { 3.0f, 3.0f };
|
||||||
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/tiling.fs", GLSL_VERSION));
|
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/tiling.fs", GLSL_VERSION));
|
||||||
|
SetTextureWrap(texture, TEXTURE_WRAP_REPEAT);
|
||||||
SetShaderValue(shader, GetShaderLocation(shader, "tiling"), tiling, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, GetShaderLocation(shader, "tiling"), tiling, SHADER_UNIFORM_VEC2);
|
||||||
model.materials[0].shader = shader;
|
model.materials[0].shader = shader;
|
||||||
|
|
||||||
|
|||||||
@ -17,17 +17,21 @@
|
|||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h> // Required for: malloc(), free()
|
||||||
#include <math.h>
|
#include <math.h> // Required for: hypot()
|
||||||
|
|
||||||
#define MAX_BALLS 5000 // Maximum quantity of balls
|
#define MAX_BALLS 5000 // Maximum quantity of balls
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Ball data type
|
||||||
typedef struct Ball {
|
typedef struct Ball {
|
||||||
Vector2 pos; // Position
|
Vector2 position;
|
||||||
Vector2 vel; // Velocity
|
Vector2 speed;
|
||||||
Vector2 ppos; // Previous position
|
Vector2 prevPosition;
|
||||||
float radius;
|
float radius;
|
||||||
float friction;
|
float friction;
|
||||||
float elasticity;
|
float elasticity;
|
||||||
Color color;
|
Color color;
|
||||||
bool grabbed;
|
bool grabbed;
|
||||||
@ -45,24 +49,27 @@ int main(void)
|
|||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
|
||||||
|
|
||||||
Ball balls[MAX_BALLS] = {{
|
Ball *balls = (Ball*)RL_MALLOC(sizeof(Ball)*MAX_BALLS);
|
||||||
.pos = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
|
|
||||||
.vel = { 200, 200 },
|
// Init first ball in the array
|
||||||
.ppos = { 0 },
|
balls[0] = (Ball){
|
||||||
|
.position = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
|
||||||
|
.speed = { 200, 200 },
|
||||||
|
.prevPosition = { 0 },
|
||||||
.radius = 40,
|
.radius = 40,
|
||||||
.friction = 0.99f,
|
.friction = 0.99f,
|
||||||
.elasticity = 0.9f,
|
.elasticity = 0.9f,
|
||||||
.color = BLUE,
|
.color = BLUE,
|
||||||
.grabbed = false
|
.grabbed = false
|
||||||
}};
|
};
|
||||||
|
|
||||||
int ballCount = 1;
|
int ballCount = 1;
|
||||||
Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed
|
Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed
|
||||||
Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd
|
Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd
|
||||||
|
|
||||||
float gravity = 100; // World gravity
|
float gravity = 100; // World gravity
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
@ -79,8 +86,8 @@ int main(void)
|
|||||||
for (int i = ballCount - 1; i >= 0; i--)
|
for (int i = ballCount - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
Ball *ball = &balls[i];
|
Ball *ball = &balls[i];
|
||||||
pressOffset.x = mousePos.x - ball->pos.x;
|
pressOffset.x = mousePos.x - ball->position.x;
|
||||||
pressOffset.y = mousePos.y - ball->pos.y;
|
pressOffset.y = mousePos.y - ball->position.y;
|
||||||
|
|
||||||
// If the distance between the ball position and the mouse press position
|
// If the distance between the ball position and the mouse press position
|
||||||
// is less than or equal to the ball radius, the event occurred inside the ball
|
// is less than or equal to the ball radius, the event occurred inside the ball
|
||||||
@ -109,9 +116,9 @@ int main(void)
|
|||||||
if (ballCount < MAX_BALLS)
|
if (ballCount < MAX_BALLS)
|
||||||
{
|
{
|
||||||
balls[ballCount++] = (Ball){
|
balls[ballCount++] = (Ball){
|
||||||
.pos = mousePos,
|
.position = mousePos,
|
||||||
.vel = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) },
|
.speed = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) },
|
||||||
.ppos = { 0 },
|
.prevPosition = { 0 },
|
||||||
.radius = 20.0f + (float)GetRandomValue(0, 30),
|
.radius = 20.0f + (float)GetRandomValue(0, 30),
|
||||||
.friction = 0.99f,
|
.friction = 0.99f,
|
||||||
.elasticity = 0.9f,
|
.elasticity = 0.9f,
|
||||||
@ -126,7 +133,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < ballCount; i++)
|
for (int i = 0; i < ballCount; i++)
|
||||||
{
|
{
|
||||||
if (!balls[i].grabbed) balls[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) };
|
if (!balls[i].grabbed) balls[i].speed = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,49 +149,49 @@ int main(void)
|
|||||||
if (!ball->grabbed)
|
if (!ball->grabbed)
|
||||||
{
|
{
|
||||||
// Ball repositioning using the velocity
|
// Ball repositioning using the velocity
|
||||||
ball->pos.x += ball->vel.x * delta;
|
ball->position.x += ball->speed.x * delta;
|
||||||
ball->pos.y += ball->vel.y * delta;
|
ball->position.y += ball->speed.y * delta;
|
||||||
|
|
||||||
// Does the ball hit the screen right boundary?
|
// Does the ball hit the screen right boundary?
|
||||||
if ((ball->pos.x + ball->radius) >= screenWidth)
|
if ((ball->position.x + ball->radius) >= screenWidth)
|
||||||
{
|
{
|
||||||
ball->pos.x = screenWidth - ball->radius; // Ball repositioning
|
ball->position.x = screenWidth - ball->radius; // Ball repositioning
|
||||||
ball->vel.x = -ball->vel.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit
|
ball->speed.x = -ball->speed.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit
|
||||||
}
|
}
|
||||||
// Does the ball hit the screen left boundary?
|
// Does the ball hit the screen left boundary?
|
||||||
else if ((ball->pos.x - ball->radius) <= 0)
|
else if ((ball->position.x - ball->radius) <= 0)
|
||||||
{
|
{
|
||||||
ball->pos.x = ball->radius;
|
ball->position.x = ball->radius;
|
||||||
ball->vel.x = -ball->vel.x*ball->elasticity;
|
ball->speed.x = -ball->speed.x*ball->elasticity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The same for y axis
|
// The same for y axis
|
||||||
if ((ball->pos.y + ball->radius) >= screenHeight)
|
if ((ball->position.y + ball->radius) >= screenHeight)
|
||||||
{
|
{
|
||||||
ball->pos.y = screenHeight - ball->radius;
|
ball->position.y = screenHeight - ball->radius;
|
||||||
ball->vel.y = -ball->vel.y*ball->elasticity;
|
ball->speed.y = -ball->speed.y*ball->elasticity;
|
||||||
}
|
}
|
||||||
else if ((ball->pos.y - ball->radius) <= 0)
|
else if ((ball->position.y - ball->radius) <= 0)
|
||||||
{
|
{
|
||||||
ball->pos.y = ball->radius;
|
ball->position.y = ball->radius;
|
||||||
ball->vel.y = -ball->vel.y*ball->elasticity;
|
ball->speed.y = -ball->speed.y*ball->elasticity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Friction makes the ball lose 1% of its velocity each frame
|
// Friction makes the ball lose 1% of its velocity each frame
|
||||||
ball->vel.x = ball->vel.x*ball->friction;
|
ball->speed.x = ball->speed.x*ball->friction;
|
||||||
// Gravity affects only the y axis
|
// Gravity affects only the y axis
|
||||||
ball->vel.y = ball->vel.y*ball->friction + gravity;
|
ball->speed.y = ball->speed.y*ball->friction + gravity;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Ball repositioning using the mouse position
|
// Ball repositioning using the mouse position
|
||||||
ball->pos.x = mousePos.x - pressOffset.x;
|
ball->position.x = mousePos.x - pressOffset.x;
|
||||||
ball->pos.y = mousePos.y - pressOffset.y;
|
ball->position.y = mousePos.y - pressOffset.y;
|
||||||
|
|
||||||
// While the ball is grabbed, recalculates its velocity
|
// While the ball is grabbed, recalculates its velocity
|
||||||
ball->vel.x = (ball->pos.x - ball->ppos.x)/delta;
|
ball->speed.x = (ball->position.x - ball->prevPosition.x)/delta;
|
||||||
ball->vel.y = (ball->pos.y - ball->ppos.y)/delta;
|
ball->speed.y = (ball->position.y - ball->prevPosition.y)/delta;
|
||||||
ball->ppos = ball->pos;
|
ball->prevPosition = ball->position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
@ -197,8 +204,8 @@ int main(void)
|
|||||||
|
|
||||||
for (int i = 0; i < ballCount; i++)
|
for (int i = 0; i < ballCount; i++)
|
||||||
{
|
{
|
||||||
DrawCircleV(balls[i].pos, balls[i].radius, balls[i].color);
|
DrawCircleV(balls[i].position, balls[i].radius, balls[i].color);
|
||||||
DrawCircleLinesV(balls[i].pos, balls[i].radius, BLACK);
|
DrawCircleLinesV(balls[i].position, balls[i].radius, BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawText("grab a ball by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY);
|
DrawText("grab a ball by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY);
|
||||||
@ -214,6 +221,7 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
RL_FREE(balls);
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ int main(void)
|
|||||||
|
|
||||||
// Circle shapes and lines
|
// Circle shapes and lines
|
||||||
DrawCircle(screenWidth/5, 120, 35, DARKBLUE);
|
DrawCircle(screenWidth/5, 120, 35, DARKBLUE);
|
||||||
DrawCircleGradient(screenWidth/5, 220, 60, GREEN, SKYBLUE);
|
DrawCircleGradient((Vector2){ screenWidth/5.0f, 220.0f }, 60, GREEN, SKYBLUE);
|
||||||
DrawCircleLines(screenWidth/5, 340, 80, DARKBLUE);
|
DrawCircleLines(screenWidth/5, 340, 80, DARKBLUE);
|
||||||
DrawEllipse(screenWidth/5, 120, 25, 20, YELLOW);
|
DrawEllipse(screenWidth/5, 120, 25, 20, YELLOW);
|
||||||
DrawEllipseLines(screenWidth/5, 120, 30, 25, YELLOW);
|
DrawEllipseLines(screenWidth/5, 120, 30, 25, YELLOW);
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 9.3 KiB |
@ -72,7 +72,7 @@ typedef struct EasingFuncs {
|
|||||||
// Module Functions Declaration
|
// Module Functions Declaration
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Function used when "no easing" is selected for any axis
|
// Function used when "no easing" is selected for any axis
|
||||||
static float NoEase(float t, float b, float c, float d);
|
static float NoEase(float t, float b, float c, float d);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
|
|||||||
@ -46,13 +46,13 @@ int main(void)
|
|||||||
float size = (float)GetScreenHeight();
|
float size = (float)GetScreenHeight();
|
||||||
int strokeCount = 0;
|
int strokeCount = 0;
|
||||||
Vector2 *hilbertPath = LoadHilbertPath(order, size, &strokeCount);
|
Vector2 *hilbertPath = LoadHilbertPath(order, size, &strokeCount);
|
||||||
|
|
||||||
int prevOrder = order;
|
int prevOrder = order;
|
||||||
int prevSize = (int)size; // NOTE: Size from slider is float but for comparison we use int
|
int prevSize = (int)size; // NOTE: Size from slider is float but for comparison we use int
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
float thick = 2.0f;
|
float thick = 2.0f;
|
||||||
bool animate = true;
|
bool animate = true;
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -68,19 +68,19 @@ int main(void)
|
|||||||
{
|
{
|
||||||
UnloadHilbertPath(hilbertPath);
|
UnloadHilbertPath(hilbertPath);
|
||||||
hilbertPath = LoadHilbertPath(order, size, &strokeCount);
|
hilbertPath = LoadHilbertPath(order, size, &strokeCount);
|
||||||
|
|
||||||
if (animate) counter = 0;
|
if (animate) counter = 0;
|
||||||
else counter = strokeCount;
|
else counter = strokeCount;
|
||||||
|
|
||||||
prevOrder = order;
|
prevOrder = order;
|
||||||
prevSize = (int)size;
|
prevSize = (int)size;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
if (counter < strokeCount)
|
if (counter < strokeCount)
|
||||||
@ -90,7 +90,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f));
|
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
counter += 1;
|
counter += 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -101,13 +101,13 @@ int main(void)
|
|||||||
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f));
|
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i/strokeCount)*360.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw UI using raygui
|
// Draw UI using raygui
|
||||||
GuiCheckBox((Rectangle){ 450, 50, 20, 20 }, "ANIMATE GENERATION ON CHANGE", &animate);
|
GuiCheckBox((Rectangle){ 450, 50, 20, 20 }, "ANIMATE GENERATION ON CHANGE", &animate);
|
||||||
GuiSpinner((Rectangle){ 585, 100, 180, 30 }, "HILBERT CURVE ORDER: ", &order, 2, 8, false);
|
GuiSpinner((Rectangle){ 585, 100, 180, 30 }, "HILBERT CURVE ORDER: ", &order, 2, 8, false);
|
||||||
GuiSlider((Rectangle){ 524, 150, 240, 24 }, "THICKNESS: ", NULL, &thick, 1.0f, 10.0f);
|
GuiSlider((Rectangle){ 524, 150, 240, 24 }, "THICKNESS: ", NULL, &thick, 1.0f, 10.0f);
|
||||||
GuiSlider((Rectangle){ 524, 190, 240, 24 }, "TOTAL SIZE: ", NULL, &size, 10.0f, GetScreenHeight()*1.5f);
|
GuiSlider((Rectangle){ 524, 190, 240, 24 }, "TOTAL SIZE: ", NULL, &size, 10.0f, GetScreenHeight()*1.5f);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ int main(void)
|
|||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadHilbertPath(hilbertPath);
|
UnloadHilbertPath(hilbertPath);
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
return 0;
|
return 0;
|
||||||
@ -133,14 +133,14 @@ static Vector2 *LoadHilbertPath(int order, float size, int *strokeCount)
|
|||||||
*strokeCount = N*N;
|
*strokeCount = N*N;
|
||||||
|
|
||||||
Vector2 *hilbertPath = (Vector2 *)RL_CALLOC(*strokeCount, sizeof(Vector2));
|
Vector2 *hilbertPath = (Vector2 *)RL_CALLOC(*strokeCount, sizeof(Vector2));
|
||||||
|
|
||||||
for (int i = 0; i < *strokeCount; i++)
|
for (int i = 0; i < *strokeCount; i++)
|
||||||
{
|
{
|
||||||
hilbertPath[i] = ComputeHilbertStep(order, i);
|
hilbertPath[i] = ComputeHilbertStep(order, i);
|
||||||
hilbertPath[i].x = hilbertPath[i].x*len + len/2.0f;
|
hilbertPath[i].x = hilbertPath[i].x*len + len/2.0f;
|
||||||
hilbertPath[i].y = hilbertPath[i].y*len + len/2.0f;
|
hilbertPath[i].y = hilbertPath[i].y*len + len/2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hilbertPath;
|
return hilbertPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ static Vector2 ComputeHilbertStep(int order, int index)
|
|||||||
[2] = { .x = 1, .y = 1 },
|
[2] = { .x = 1, .y = 1 },
|
||||||
[3] = { .x = 1, .y = 0 },
|
[3] = { .x = 1, .y = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
int hilbertIndex = index&3;
|
int hilbertIndex = index&3;
|
||||||
Vector2 vect = hilbertPoints[hilbertIndex];
|
Vector2 vect = hilbertPoints[hilbertIndex];
|
||||||
float temp = 0.0f;
|
float temp = 0.0f;
|
||||||
@ -171,7 +171,7 @@ static Vector2 ComputeHilbertStep(int order, int index)
|
|||||||
index = index >> 2;
|
index = index >> 2;
|
||||||
hilbertIndex = index&3;
|
hilbertIndex = index&3;
|
||||||
len = 1 << j;
|
len = 1 << j;
|
||||||
|
|
||||||
switch (hilbertIndex)
|
switch (hilbertIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -191,6 +191,6 @@ static Vector2 ComputeHilbertStep(int order, int index)
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vect;
|
return vect;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -106,7 +106,7 @@ int main(void)
|
|||||||
if (generations > 0) rebuild = true;
|
if (generations > 0) rebuild = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rebuild)
|
if (rebuild)
|
||||||
{
|
{
|
||||||
RL_FREE(ls.production); // Free previous production for re-creation
|
RL_FREE(ls.production); // Free previous production for re-creation
|
||||||
@ -118,15 +118,15 @@ int main(void)
|
|||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground( RAYWHITE );
|
ClearBackground( RAYWHITE );
|
||||||
|
|
||||||
if (generations > 0) DrawPenroseLSystem(&ls);
|
if (generations > 0) DrawPenroseLSystem(&ls);
|
||||||
|
|
||||||
DrawText("penrose l-system", 10, 10, 20, DARKGRAY);
|
DrawText("penrose l-system", 10, 10, 20, DARKGRAY);
|
||||||
DrawText("press up or down to change generations", 10, 30, 20, DARKGRAY);
|
DrawText("press up or down to change generations", 10, 30, 20, DARKGRAY);
|
||||||
DrawText(TextFormat("generations: %d", generations), 10, 50, 20, DARKGRAY);
|
DrawText(TextFormat("generations: %d", generations), 10, 50, 20, DARKGRAY);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
@ -171,11 +171,11 @@ static PenroseLSystem CreatePenroseLSystem(float drawLength)
|
|||||||
.drawLength = drawLength,
|
.drawLength = drawLength,
|
||||||
.theta = 36.0f // Degrees
|
.theta = 36.0f // Degrees
|
||||||
};
|
};
|
||||||
|
|
||||||
ls.production = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
|
ls.production = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
|
||||||
ls.production[0] = '\0';
|
ls.production[0] = '\0';
|
||||||
strncpy(ls.production, "[X]++[X]++[X]++[X]++[X]", STR_MAX_SIZE);
|
strncpy(ls.production, "[X]++[X]++[X]++[X]++[X]", STR_MAX_SIZE);
|
||||||
|
|
||||||
return ls;
|
return ls;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ static void BuildProductionStep(PenroseLSystem *ls)
|
|||||||
|
|
||||||
ls->drawLength *= 0.5f;
|
ls->drawLength *= 0.5f;
|
||||||
strncpy(ls->production, newProduction, STR_MAX_SIZE);
|
strncpy(ls->production, newProduction, STR_MAX_SIZE);
|
||||||
|
|
||||||
RL_FREE(newProduction);
|
RL_FREE(newProduction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,9 +228,9 @@ static void DrawPenroseLSystem(PenroseLSystem *ls)
|
|||||||
int repeats = 1;
|
int repeats = 1;
|
||||||
int productionLength = (int)strnlen(ls->production, STR_MAX_SIZE);
|
int productionLength = (int)strnlen(ls->production, STR_MAX_SIZE);
|
||||||
ls->steps += 12;
|
ls->steps += 12;
|
||||||
|
|
||||||
if (ls->steps > productionLength) ls->steps = productionLength;
|
if (ls->steps > productionLength) ls->steps = productionLength;
|
||||||
|
|
||||||
for (int i = 0; i < ls->steps; i++)
|
for (int i = 0; i < ls->steps; i++)
|
||||||
{
|
{
|
||||||
char step = ls->production[i];
|
char step = ls->production[i];
|
||||||
@ -244,24 +244,24 @@ static void DrawPenroseLSystem(PenroseLSystem *ls)
|
|||||||
turtle.origin.y += ls->drawLength*sinf(radAngle);
|
turtle.origin.y += ls->drawLength*sinf(radAngle);
|
||||||
Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y };
|
Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y };
|
||||||
Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y };
|
Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y };
|
||||||
|
|
||||||
DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2f));
|
DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2f));
|
||||||
}
|
}
|
||||||
|
|
||||||
repeats = 1;
|
repeats = 1;
|
||||||
}
|
}
|
||||||
else if (step == '+')
|
else if (step == '+')
|
||||||
{
|
{
|
||||||
for (int j = 0; j < repeats; j++) turtle.angle += ls->theta;
|
for (int j = 0; j < repeats; j++) turtle.angle += ls->theta;
|
||||||
|
|
||||||
repeats = 1;
|
repeats = 1;
|
||||||
}
|
}
|
||||||
else if (step == '-')
|
else if (step == '-')
|
||||||
{
|
{
|
||||||
for (int j = 0; j < repeats; j++) turtle.angle += -ls->theta;
|
for (int j = 0; j < repeats; j++) turtle.angle += -ls->theta;
|
||||||
|
|
||||||
repeats = 1;
|
repeats = 1;
|
||||||
}
|
}
|
||||||
else if (step == '[') PushTurtleState(turtle);
|
else if (step == '[') PushTurtleState(turtle);
|
||||||
else if (step == ']') turtle = PopTurtleState();
|
else if (step == ']') turtle = PopTurtleState();
|
||||||
else if ((step >= 48) && (step <= 57)) repeats = (int) step - 48;
|
else if ((step >= 48) && (step <= 57)) repeats = (int) step - 48;
|
||||||
|
|||||||
@ -341,7 +341,7 @@ static void DrawLightMask(int slot)
|
|||||||
rlSetBlendMode(BLEND_CUSTOM);
|
rlSetBlendMode(BLEND_CUSTOM);
|
||||||
|
|
||||||
// If we are valid, then draw the light radius to the alpha mask
|
// If we are valid, then draw the light radius to the alpha mask
|
||||||
if (lights[slot].valid) DrawCircleGradient((int)lights[slot].position.x, (int)lights[slot].position.y, lights[slot].outerRadius, ColorAlpha(WHITE, 0), WHITE);
|
if (lights[slot].valid) DrawCircleGradient(lights[slot].position, lights[slot].outerRadius, ColorAlpha(WHITE, 0), WHITE);
|
||||||
|
|
||||||
rlDrawRenderBatchActive();
|
rlDrawRenderBatchActive();
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,7 @@ int main(void)
|
|||||||
SetTextLineSpacing(20); // Set line spacing for multiline text (when line breaks are included '\n')
|
SetTextLineSpacing(20); // Set line spacing for multiline text (when line breaks are included '\n')
|
||||||
|
|
||||||
// Free codepoints, atlas has already been generated
|
// Free codepoints, atlas has already been generated
|
||||||
free(codepointsNoDups);
|
RL_FREE(codepointsNoDups);
|
||||||
|
|
||||||
bool showFontAtlas = false;
|
bool showFontAtlas = false;
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ int main(void)
|
|||||||
static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointsResultCount)
|
static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointsResultCount)
|
||||||
{
|
{
|
||||||
int codepointsNoDupsCount = codepointCount;
|
int codepointsNoDupsCount = codepointCount;
|
||||||
int *codepointsNoDups = (int *)calloc(codepointCount, sizeof(int));
|
int *codepointsNoDups = (int *)RL_CALLOC(codepointCount, sizeof(int));
|
||||||
memcpy(codepointsNoDups, codepoints, codepointCount*sizeof(int));
|
memcpy(codepointsNoDups, codepoints, codepointCount*sizeof(int));
|
||||||
|
|
||||||
// Remove duplicates
|
// Remove duplicates
|
||||||
|
|||||||
@ -38,12 +38,12 @@ int main(void)
|
|||||||
|
|
||||||
// Define characters to draw
|
// Define characters to draw
|
||||||
// NOTE: raylib supports UTF-8 encoding, following list is actually codified as UTF8 internally
|
// NOTE: raylib supports UTF-8 encoding, following list is actually codified as UTF8 internally
|
||||||
const char msg[256] = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\nJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmn\nopqrstuvwxyz{|}~¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓ\nÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷\nøùúûüýþÿ";
|
const char msg[256] = "!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\nJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmn\nopqrstuvwxyz{|}~¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓ\nÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷\nøùúûüýþÿ";
|
||||||
|
|
||||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||||
|
|
||||||
// BMFont (AngelCode) : Font data and image atlas have been generated using external program
|
// BMFont (AngelCode) : Font data and image atlas have been generated using external program
|
||||||
Font fontBm = LoadFont("resources/pixantiqua.fnt");
|
Font fontBm = LoadFont("resources/pixantiqua.fnt"); // Requires "resources/pixantiqua.png"
|
||||||
|
|
||||||
// TTF font : Font data and atlas are generated directly from TTF
|
// TTF font : Font data and atlas are generated directly from TTF
|
||||||
// NOTE: We define a font base size of 32 pixels tall and up-to 250 characters
|
// NOTE: We define a font base size of 32 pixels tall and up-to 250 characters
|
||||||
|
|||||||
@ -33,7 +33,7 @@ typedef struct TextParticle {
|
|||||||
Vector2 ppos; // Previous position
|
Vector2 ppos; // Previous position
|
||||||
float padding;
|
float padding;
|
||||||
float borderWidth;
|
float borderWidth;
|
||||||
float friction;
|
float friction;
|
||||||
float elasticity;
|
float elasticity;
|
||||||
Color color;
|
Color color;
|
||||||
bool grabbed;
|
bool grabbed;
|
||||||
@ -118,7 +118,7 @@ int main(void)
|
|||||||
if (IsKeyDown(KEY_LEFT_SHIFT))
|
if (IsKeyDown(KEY_LEFT_SHIFT))
|
||||||
{
|
{
|
||||||
ShatterTextParticle(tp, i, textParticles, &particleCount);
|
ShatterTextParticle(tp, i, textParticles, &particleCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SliceTextParticle(tp, i, TextLength(tp->text)/2, textParticles, &particleCount);
|
SliceTextParticle(tp, i, TextLength(tp->text)/2, textParticles, &particleCount);
|
||||||
@ -158,33 +158,33 @@ int main(void)
|
|||||||
TextParticle *tp = &textParticles[i];
|
TextParticle *tp = &textParticles[i];
|
||||||
|
|
||||||
// The text particle is not grabbed
|
// The text particle is not grabbed
|
||||||
if (!tp->grabbed)
|
if (!tp->grabbed)
|
||||||
{
|
{
|
||||||
// text particle repositioning using the velocity
|
// text particle repositioning using the velocity
|
||||||
tp->rect.x += tp->vel.x * delta;
|
tp->rect.x += tp->vel.x * delta;
|
||||||
tp->rect.y += tp->vel.y * delta;
|
tp->rect.y += tp->vel.y * delta;
|
||||||
|
|
||||||
// Does the text particle hit the screen right boundary?
|
// Does the text particle hit the screen right boundary?
|
||||||
if ((tp->rect.x + tp->rect.width) >= screenWidth)
|
if ((tp->rect.x + tp->rect.width) >= screenWidth)
|
||||||
{
|
{
|
||||||
tp->rect.x = screenWidth - tp->rect.width; // Text particle repositioning
|
tp->rect.x = screenWidth - tp->rect.width; // Text particle repositioning
|
||||||
tp->vel.x = -tp->vel.x*tp->elasticity; // Elasticity makes the text particle lose 10% of its velocity on hit
|
tp->vel.x = -tp->vel.x*tp->elasticity; // Elasticity makes the text particle lose 10% of its velocity on hit
|
||||||
}
|
}
|
||||||
// Does the text particle hit the screen left boundary?
|
// Does the text particle hit the screen left boundary?
|
||||||
else if (tp->rect.x <= 0)
|
else if (tp->rect.x <= 0)
|
||||||
{
|
{
|
||||||
tp->rect.x = 0.0f;
|
tp->rect.x = 0.0f;
|
||||||
tp->vel.x = -tp->vel.x*tp->elasticity;
|
tp->vel.x = -tp->vel.x*tp->elasticity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The same for y axis
|
// The same for y axis
|
||||||
if ((tp->rect.y + tp->rect.height) >= screenHeight)
|
if ((tp->rect.y + tp->rect.height) >= screenHeight)
|
||||||
{
|
{
|
||||||
tp->rect.y = screenHeight - tp->rect.height;
|
tp->rect.y = screenHeight - tp->rect.height;
|
||||||
tp->vel.y = -tp->vel.y*tp->elasticity;
|
tp->vel.y = -tp->vel.y*tp->elasticity;
|
||||||
}
|
}
|
||||||
else if (tp->rect.y <= 0)
|
else if (tp->rect.y <= 0)
|
||||||
{
|
{
|
||||||
tp->rect.y = 0.0f;
|
tp->rect.y = 0.0f;
|
||||||
tp->vel.y = -tp->vel.y*tp->elasticity;
|
tp->vel.y = -tp->vel.y*tp->elasticity;
|
||||||
}
|
}
|
||||||
@ -264,9 +264,9 @@ int main(void)
|
|||||||
void PrepareFirstTextParticle(const char* text, TextParticle *tps, int *particleCount)
|
void PrepareFirstTextParticle(const char* text, TextParticle *tps, int *particleCount)
|
||||||
{
|
{
|
||||||
tps[0] = CreateTextParticle(
|
tps[0] = CreateTextParticle(
|
||||||
text,
|
text,
|
||||||
GetScreenWidth()/2.0f,
|
GetScreenWidth()/2.0f,
|
||||||
GetScreenHeight()/2.0f,
|
GetScreenHeight()/2.0f,
|
||||||
RAYWHITE
|
RAYWHITE
|
||||||
);
|
);
|
||||||
*particleCount = 1;
|
*particleCount = 1;
|
||||||
@ -317,7 +317,7 @@ void SliceTextParticleByChar(TextParticle *tp, char charToSlice, TextParticle *t
|
|||||||
{
|
{
|
||||||
int tokenCount = 0;
|
int tokenCount = 0;
|
||||||
char **tokens = TextSplit(tp->text, charToSlice, &tokenCount);
|
char **tokens = TextSplit(tp->text, charToSlice, &tokenCount);
|
||||||
|
|
||||||
if (tokenCount > 1)
|
if (tokenCount > 1)
|
||||||
{
|
{
|
||||||
int textLength = TextLength(tp->text);
|
int textLength = TextLength(tp->text);
|
||||||
|
|||||||
@ -47,7 +47,7 @@ int main(void)
|
|||||||
// Load bunny texture
|
// Load bunny texture
|
||||||
Texture2D texBunny = LoadTexture("resources/raybunny.png");
|
Texture2D texBunny = LoadTexture("resources/raybunny.png");
|
||||||
|
|
||||||
Bunny *bunnies = (Bunny *)malloc(MAX_BUNNIES*sizeof(Bunny)); // Bunnies array
|
Bunny *bunnies = (Bunny *)RL_MALLOC(MAX_BUNNIES*sizeof(Bunny)); // Bunnies array
|
||||||
|
|
||||||
int bunniesCount = 0; // Bunnies counter
|
int bunniesCount = 0; // Bunnies counter
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
free(bunnies); // Unload bunnies data array
|
RL_FREE(bunnies); // Unload bunnies data array
|
||||||
|
|
||||||
UnloadTexture(texBunny); // Unload bunny texture
|
UnloadTexture(texBunny); // Unload bunny texture
|
||||||
|
|
||||||
|
|||||||
@ -165,7 +165,7 @@ int main(void)
|
|||||||
|
|
||||||
// If the mouse is on this preset, highlight it
|
// If the mouse is on this preset, highlight it
|
||||||
if (mouseInCell == i + 8)
|
if (mouseInCell == i + 8)
|
||||||
DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*((float)i/2),
|
DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*(i/2),
|
||||||
(presetsSizeY + 2.0f)*(i%2),
|
(presetsSizeY + 2.0f)*(i%2),
|
||||||
presetsSizeX + 4.0f, presetsSizeY + 4.0f }, 3, RED);
|
presetsSizeX + 4.0f, presetsSizeY + 4.0f }, 3, RED);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
// Unload textures to avoid memory leaks
|
// Unload textures to avoid memory leaks
|
||||||
for (int i = 0; i < MAX_TEXTURE_COLLECTION; i++) UnloadTexture(collection[i].texture);
|
for (int i = 0; i < MAX_TEXTURE_COLLECTION; i++) UnloadTexture(collection[i].texture);
|
||||||
|
|
||||||
currentCollectionIndex = 0;
|
currentCollectionIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ int main(void)
|
|||||||
(currentCollectionIndex < MAX_TEXTURE_COLLECTION))
|
(currentCollectionIndex < MAX_TEXTURE_COLLECTION))
|
||||||
{
|
{
|
||||||
Image image = GetClipboardImage();
|
Image image = GetClipboardImage();
|
||||||
|
|
||||||
if (IsImageValid(image))
|
if (IsImageValid(image))
|
||||||
{
|
{
|
||||||
collection[currentCollectionIndex].texture = LoadTextureFromImage(image);
|
collection[currentCollectionIndex].texture = LoadTextureFromImage(image);
|
||||||
@ -76,15 +76,15 @@ int main(void)
|
|||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
for (int i = 0; i < currentCollectionIndex; i++)
|
for (int i = 0; i < currentCollectionIndex; i++)
|
||||||
{
|
{
|
||||||
if (IsTextureValid(collection[i].texture))
|
if (IsTextureValid(collection[i].texture))
|
||||||
{
|
{
|
||||||
DrawTexturePro(collection[i].texture,
|
DrawTexturePro(collection[i].texture,
|
||||||
(Rectangle){0,0,collection[i].texture.width, collection[i].texture.height},
|
(Rectangle){0,0,collection[i].texture.width, collection[i].texture.height},
|
||||||
(Rectangle){collection[i].position.x,collection[i].position.y,collection[i].texture.width, collection[i].texture.height},
|
(Rectangle){collection[i].position.x,collection[i].position.y,collection[i].texture.width, collection[i].texture.height},
|
||||||
(Vector2){collection[i].texture.width*0.5f, collection[i].texture.height*0.5f},
|
(Vector2){collection[i].texture.width*0.5f, collection[i].texture.height*0.5f},
|
||||||
0.0f, WHITE);
|
0.0f, WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,8 +51,8 @@ int main(void)
|
|||||||
// NOTE: We can have up to 256 values for tile ids and for tile fog state,
|
// NOTE: We can have up to 256 values for tile ids and for tile fog state,
|
||||||
// probably we don't need that many values for fog state, it can be optimized
|
// probably we don't need that many values for fog state, it can be optimized
|
||||||
// to use only 2 bits per fog state (reducing size by 4) but logic will be a bit more complex
|
// to use only 2 bits per fog state (reducing size by 4) but logic will be a bit more complex
|
||||||
map.tileIds = (unsigned char *)calloc(map.tilesX*map.tilesY, sizeof(unsigned char));
|
map.tileIds = (unsigned char *)RL_CALLOC(map.tilesX*map.tilesY, sizeof(unsigned char));
|
||||||
map.tileFog = (unsigned char *)calloc(map.tilesX*map.tilesY, sizeof(unsigned char));
|
map.tileFog = (unsigned char *)RL_CALLOC(map.tilesX*map.tilesY, sizeof(unsigned char));
|
||||||
|
|
||||||
// Load map tiles (generating 2 random tile ids for testing)
|
// Load map tiles (generating 2 random tile ids for testing)
|
||||||
// NOTE: Map tile ids should be probably loaded from an external map file
|
// NOTE: Map tile ids should be probably loaded from an external map file
|
||||||
@ -149,8 +149,8 @@ int main(void)
|
|||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
free(map.tileIds); // Free allocated map tile ids
|
RL_FREE(map.tileIds); // Free allocated map tile ids
|
||||||
free(map.tileFog); // Free allocated map tile fog state
|
RL_FREE(map.tileFog); // Free allocated map tile fog state
|
||||||
|
|
||||||
UnloadRenderTexture(fogOfWar); // Unload render texture
|
UnloadRenderTexture(fogOfWar); // Unload render texture
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
* raylib textures example - magnifying glass
|
* raylib textures example - magnifying glass
|
||||||
*
|
*
|
||||||
* Example complexity rating: [★★★☆] 3/4
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||||
*
|
*
|
||||||
* Example contributed by Luke Vaughan (@badram) and reviewed by Ramon Santamaria (@raysan5)
|
* Example contributed by Luke Vaughan (@badram) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
@ -29,18 +29,18 @@ int main(void)
|
|||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - magnifying glass");
|
InitWindow(screenWidth, screenHeight, "raylib [textures] example - magnifying glass");
|
||||||
|
|
||||||
Texture2D bunny = LoadTexture("resources/raybunny.png");
|
Texture2D bunny = LoadTexture("resources/raybunny.png");
|
||||||
Texture2D parrots = LoadTexture("resources/parrots.png");
|
Texture2D parrots = LoadTexture("resources/parrots.png");
|
||||||
|
|
||||||
// Use image draw to generate a mask texture instead of loading it from a file.
|
// Use image draw to generate a mask texture instead of loading it from a file.
|
||||||
Image circle = GenImageColor(256, 256, BLANK);
|
Image circle = GenImageColor(256, 256, BLANK);
|
||||||
ImageDrawCircle(&circle, 128, 128, 128, WHITE);
|
ImageDrawCircle(&circle, 128, 128, 128, WHITE);
|
||||||
Texture2D mask = LoadTextureFromImage(circle); // Copy the mask image from RAM to VRAM
|
Texture2D mask = LoadTextureFromImage(circle); // Copy the mask image from RAM to VRAM
|
||||||
UnloadImage(circle); // Unload the image from RAM
|
UnloadImage(circle); // Unload the image from RAM
|
||||||
|
|
||||||
RenderTexture2D magnifiedWorld = LoadRenderTexture(256, 256);
|
RenderTexture2D magnifiedWorld = LoadRenderTexture(256, 256);
|
||||||
|
|
||||||
Camera2D camera = { 0 };
|
Camera2D camera = { 0 };
|
||||||
// Set magnifying glass zoom
|
// Set magnifying glass zoom
|
||||||
camera.zoom = 2;
|
camera.zoom = 2;
|
||||||
@ -71,7 +71,7 @@ int main(void)
|
|||||||
DrawTexture(parrots, 144, 33, WHITE);
|
DrawTexture(parrots, 144, 33, WHITE);
|
||||||
DrawText("Use the magnifying glass to find hidden bunnies!", 154, 6, 20, BLACK);
|
DrawText("Use the magnifying glass to find hidden bunnies!", 154, 6, 20, BLACK);
|
||||||
|
|
||||||
// Render to a the magnifying glass
|
// Render to a the magnifying glass
|
||||||
BeginTextureMode(magnifiedWorld);
|
BeginTextureMode(magnifiedWorld);
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: malloc() and free()
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
@ -39,26 +37,31 @@ int main(void)
|
|||||||
UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data
|
UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data
|
||||||
|
|
||||||
// Generate a checked texture by code
|
// Generate a checked texture by code
|
||||||
int width = 960;
|
int imWidth = 960;
|
||||||
int height = 480;
|
int imHeight = 480;
|
||||||
|
|
||||||
// Dynamic memory allocation to store pixels data (Color type)
|
// Dynamic memory allocation to store pixels data (Color type)
|
||||||
Color *pixels = (Color *)malloc(width*height*sizeof(Color));
|
// WARNING: Using raylib provided MemAlloc() that uses default raylib
|
||||||
|
// internal memory allocator, so this data can be freed using UnloadImage()
|
||||||
|
// that also uses raylib internal memory de-allocator
|
||||||
|
Color *pixels = (Color *)MemAlloc(imWidth*imHeight*sizeof(Color));
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < imHeight; y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < imWidth; x++)
|
||||||
{
|
{
|
||||||
if (((x/32+y/32)/1)%2 == 0) pixels[y*width + x] = ORANGE;
|
if (((x/32+y/32)/1)%2 == 0) pixels[y*imWidth + x] = ORANGE;
|
||||||
else pixels[y*width + x] = GOLD;
|
else pixels[y*imWidth + x] = GOLD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load pixels data into an image structure and create texture
|
// Load pixels data into an image structure and create texture
|
||||||
|
// NOTE: We can assign pixels directly to data because Color is R8G8B8A8
|
||||||
|
// data structure defining that pixelformat, format must be set properly
|
||||||
Image checkedIm = {
|
Image checkedIm = {
|
||||||
.data = pixels, // We can assign pixels directly to data
|
.data = pixels,
|
||||||
.width = width,
|
.width = imWidth,
|
||||||
.height = height,
|
.height = imHeight,
|
||||||
.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8,
|
.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8,
|
||||||
.mipmaps = 1
|
.mipmaps = 1
|
||||||
};
|
};
|
||||||
|
|||||||
@ -52,7 +52,7 @@ int main(void)
|
|||||||
float hue = t*t;
|
float hue = t*t;
|
||||||
float saturation = t;
|
float saturation = t;
|
||||||
float value = t;
|
float value = t;
|
||||||
|
|
||||||
palette[i] = ColorFromHSV(250.0f + 150.0f*hue, saturation, value);
|
palette[i] = ColorFromHSV(250.0f + 150.0f*hue, saturation, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,14 +92,14 @@ int main(void)
|
|||||||
{
|
{
|
||||||
unsigned int i = x + y*imageWidth;
|
unsigned int i = x + y*imageWidth;
|
||||||
unsigned char colorIndex = indexBuffer[i];
|
unsigned char colorIndex = indexBuffer[i];
|
||||||
|
|
||||||
if (colorIndex != 0)
|
if (colorIndex != 0)
|
||||||
{
|
{
|
||||||
// Move pixel a row above
|
// Move pixel a row above
|
||||||
indexBuffer[i] = 0;
|
indexBuffer[i] = 0;
|
||||||
int moveX = GetRandomValue(0, 2) - 1;
|
int moveX = GetRandomValue(0, 2) - 1;
|
||||||
int newX = x + moveX;
|
int newX = x + moveX;
|
||||||
|
|
||||||
if ((newX > 0) && (newX < imageWidth))
|
if ((newX > 0) && (newX < imageWidth))
|
||||||
{
|
{
|
||||||
unsigned int iabove = i - imageWidth + moveX;
|
unsigned int iabove = i - imageWidth + moveX;
|
||||||
@ -130,7 +130,7 @@ int main(void)
|
|||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
DrawTextureEx(screenTexture, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);
|
DrawTextureEx(screenTexture, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);
|
||||||
|
|||||||
@ -34,7 +34,7 @@ int main()
|
|||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user