79 Commits

Author SHA1 Message Date
Ray
fbcc8cdb55 Update shapes_top_down_lights.c 2026-04-09 11:52:06 +02:00
Ray
ca6f188233 Update shaders_shapes_textures.c 2026-04-09 11:52:04 +02:00
Ray
8e54b19d9f Update shapes_basic_shapes.c 2026-04-09 11:46:00 +02:00
Ray
e24b01bb28 Update HISTORY.md 2026-04-09 11:36:26 +02:00
Ray
68d519910a Merge branch 'master' of https://github.com/raysan5/raylib 2026-04-09 11:35:24 +02:00
Ray
53915d77e6 Update CHANGELOG 2026-04-09 11:22:13 +02:00
b202421e08 rlparser: update raylib_api.* by CI 2026-04-09 09:16:49 +00:00
Ray
05a14456ae REDESIGNED: DrawCircleGradieent() to use Vector2 as center parameter #5738 2026-04-09 11:16:31 +02:00
c5fc771622 removed the first RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEMATRICES (#5727) 2026-04-06 00:38:04 +02:00
Ray
d3c6f426b4 Update for software renderer on DRM #5721 2026-04-05 11:02:26 +02:00
c4bd4faab5 [build][CMake] REVIEWED: DRM software renderer configuration (#5721)
https://github.com/raysan5/raylib/pull/5720#issuecomment-4187113099

In this comment, it was pointed out that LibraryConfigurations.cmake
still tries to find and link egl, gbm, and glesv2, even when using the
software renderer is it not necessary.

This patch addresses that.
2026-04-05 11:01:44 +02:00
4a6ceb9c76 [rcore_rgfw] Icon color format fix (#5724)
After RGFW update to 2.0.0-dev in fbd83cafc7, RGFW_window_setIcon api has changed -- not it takes pixel format enum instead of number of channels. On raylib side it was still passing 4 (number of channels in rgba) which is enum value for BGRA8. Instead we have to pass 2 now (RGFW_formatRGBA8 = 2).
2026-04-05 10:50:31 +02:00
Ray
6ef0044381 REVIEWED: Window messages WM_SIZING, WM_SIZE, WM_WINDOWPOSCHANGED #5720 2026-04-04 17:37:25 +02:00
Ray
1122add3ee Minor format tweak 2026-04-04 17:36:18 +02:00
Ray
92f82b4add Update raylib.h 2026-04-04 16:50:15 +02:00
Ray
cdff3d7bea Update CHANGELOG 2026-04-04 16:50:10 +02:00
138ef838d9 [rlsw] Some platform fixes (#5720)
* fix drm with rlsw

* fix window resizing with sdl

* fix window resizing with win32
2026-04-04 16:47:33 +02:00
Ray
6ff51d3a2a Update audio_amp_envelope.c 2026-04-04 11:13:29 +02:00
Ray
ea6292e27a REVIEWED: example: audio_amp_envelope, code formating to follow raylib code conventions #5713 2026-04-04 11:12:30 +02:00
bb7b8d70e9 Example/audio adsr (#5713)
* add  audio_amp_envelope example

* Change 1.0f to env->sustainLevel in case the user
release the spacebar before attack state done
2026-04-04 11:04:24 +02:00
f36533cbd8 rlparser: update raylib_api.* by CI 2026-04-01 21:23:44 +00:00
Ray
5c2dee0862 REVIEWED: LoadDirectoryFiles*() comments 2026-04-01 23:23:25 +02:00
12140cd444 explicitly state TEXTURE_WRAP_REPEAT for web build (#5711) 2026-04-01 14:48:49 +02:00
Ray
3f7f040c7e Merge branch 'master' of https://github.com/raysan5/raylib 2026-04-01 10:17:43 +02:00
Ray
4799cab772 Update rexm.c 2026-04-01 10:17:41 +02:00
Ray
eb4f1a6da0 Update ROADMAP.md 2026-04-01 10:17:37 +02:00
Ray
449182bb51 Update README.md 2026-04-01 10:17:34 +02:00
4ca9170f5b [rcore_rgfw] Updating render resolution as well on SetWindowSize (#5709)
* [rcore_rgfw] Updating render resolution as well on SetWindowSize

* Actually, maybe even better call SetupViewport()
2026-04-01 09:46:14 +02:00
78797757f0 store bytes at global data seg (#5708) 2026-03-31 16:45:54 +02:00
Ray
a6dc9f9e92 Update LICENSE.md 2026-03-30 20:16:40 +02:00
Ray
c7df641aa2 Update text_font_loading.c 2026-03-30 11:00:39 +02:00
Ray
63beefd0de Update Makefile.Web 2026-03-30 11:00:29 +02:00
Ray
b3bf537fab Update rexm.c 2026-03-30 11:00:26 +02:00
Ray
8743e11285 Update rmodels.c 2026-03-29 21:40:41 +02:00
Ray
04f81538b7 ADDED: Some sample code to export gltf/glb meshes -WIP- 2026-03-29 21:37:01 +02:00
Ray
8d70f1007b Update CHANGELOG 2026-03-29 21:24:33 +02:00
Ray
6c0134bb5c Create cgltf_write.h 2026-03-29 21:24:24 +02:00
Ray
e9231bc4f1 Update stb_image_resize2.h 2026-03-29 21:24:20 +02:00
Ray
4c79c6837b Update qoi.h 2026-03-29 21:21:16 +02:00
Ray
e5f0c9f8b1 Update qoa.h 2026-03-29 21:21:11 +02:00
Ray
d5326fe880 Update m3d.h 2026-03-29 21:20:23 +02:00
Ray
adc4c9b875 Update dr_wav.h 2026-03-29 21:19:31 +02:00
Ray
b09da8fce8 Update dr_mp3.h 2026-03-29 21:18:56 +02:00
Ray
0b87a35e5a Update dr_flac.h 2026-03-29 21:18:28 +02:00
Ray
a1bf8d9c75 Update cgltf.h 2026-03-29 21:17:51 +02:00
Ray
d3cc78d9d7 Update rexm.c 2026-03-29 01:44:33 +01:00
Ray
e3dcb144bc Update rexm.c 2026-03-29 01:33:27 +01:00
Ray
da93ec4a21 Remove trailing spaces 2026-03-29 01:17:25 +01:00
Ray
fb0f83bc91 Remove trailing spaces on shaders 2026-03-29 01:10:29 +01:00
Ray
29ded51ea4 Update rlgl.h 2026-03-29 00:43:50 +01:00
bb78e98a71 Remove forced normalization of normal vectors in rlNormal3f, assume the user has set the correct input for the shader. (#5703) 2026-03-29 00:39:23 +01:00
5915584cd6 Fix zig build and minor improvements (#5702)
- Added zig-pkg directory to gitignore
- Brought min zig version to recent nightly release these improvements
  were completed on
- For linux build, only add rglfw.c if the platform is glfw
- Add a None option to the LinuxDisplayBackend
- Fixed xcode-frameworks dependency and update to using most recent
  commit hash
2026-03-29 00:38:45 +01:00
Ray
8c44ea5032 Code gardening
REVIEWED: Some early returns, avoid if possible
REVIEWED: Some return variable names, for consistency, rename `success` to `result`
2026-03-29 00:37:01 +01:00
Ray
5fad835ff1 Update rcore.c 2026-03-28 23:54:51 +01:00
mjt
4142c89baa Update rcore.c comment (#5700) 2026-03-27 21:58:28 +01:00
990a5e0cb4 rlparser: update raylib_api.* by CI 2026-03-27 20:56:45 +00:00
Ray
8a7aff509d WARNING: BREAKING: REDESIGNED: TextInsert(), TextReplace(), TextReplaceBetween(), using static buffers
Redesign has been conditioned by the usage of those functions on `rexm`, `rpc` and other tools; for many use cases a static buffer is enough and way more comfortable to use.
ADDED: `TextInsertAlloc()`, `TextReplaceAlloc()`, `TextReplaceBetweenAlloc()`, alternatives with internal allocations
2026-03-27 21:56:29 +01:00
ba83bd33f3 simplify CheckCollisionSpheres using Vector3DistanceSqr (#5695) 2026-03-27 09:26:53 +01:00
mjt
98d6e24c44 remove comment (#5696) 2026-03-27 09:26:01 +01:00
51f4741912 [rmodel] fix for devices without VAO support (#5692) 2026-03-27 09:25:26 +01:00
d7bd56ef1b rlparser: update raylib_api.* by CI 2026-03-26 17:29:18 +00:00
a693365bf2 Move DrawModelPoints methods to example - point rendering (#5697) 2026-03-26 18:29:05 +01:00
bd3a35ca21 [build.zig.zon] Fix: replace deleted hexops/xcode-frameworks with pkg.machengine.org mirror (#5693) 2026-03-26 09:20:44 +01:00
Ray
0f0983c065 Remove trailing spaces 2026-03-25 16:51:02 +01:00
5dd4036ed0 Fix UI Cellular Automata (#5688) 2026-03-24 08:20:37 +01:00
cb05ef7f03 [rcore_desktop_rgfw] [emscripten] fix typo (#5687)
* RGFW also requires RGBA8 images as window icons, as raylib already reports in raylib.h

* LibraryConfigurations.cmake: exchanged MATCHES -> STREQUAL in platform choosing if-statements

* WebRGFW: remapping mouse/touch position to canvas pixel coordinates

* fix 'typo'

* has to be done like that because of += in case of captured mouse

* [rcore_desktop_rgfw] [emscripten] fix typo
2026-03-23 22:22:21 +01:00
Ray
52d2158f49 Update ROADMAP.md 2026-03-23 18:28:09 +01:00
0f1e14a600 Fix typo: dependant -> dependent in rlgl.h and rexm.c (#5685)
5 instances in src/rlgl.h comments and 1 in tools/rexm/rexm.c.
Skipped vendored raygui.h files in examples/.
2026-03-23 17:58:45 +01:00
6cf71f565c Fix typo: dependant -> dependent in rlgl.h and rexm.c (#5685)
5 instances in src/rlgl.h comments and 1 in tools/rexm/rexm.c.
Skipped vendored raygui.h files in examples/.
2026-03-23 17:17:50 +01:00
e71633a0be Set textureWrapRepeat to avoid issue on web version (#5684) 2026-03-23 14:05:23 +01:00
Ray
ca1baca7c2 REVIEWED: examples memory allocators, using raylib provided macros 2026-03-23 11:53:57 +01:00
Ray
7e8aca00b6 Update textures_raw_data.c 2026-03-23 11:53:31 +01:00
Ray
c1dbfc87f3 REVIEWED: PR #5679 2026-03-23 11:52:01 +01:00
Ray
644e4adbe2 Update rcore.c 2026-03-23 11:51:37 +01:00
1e74aba7c3 WebRGFW: remapping mouse/touch position to canvas pixel coordinates (#5679)
* RGFW also requires RGBA8 images as window icons, as raylib already reports in raylib.h

* LibraryConfigurations.cmake: exchanged MATCHES -> STREQUAL in platform choosing if-statements

* WebRGFW: remapping mouse/touch position to canvas pixel coordinates

* fix 'typo'

* has to be done like that because of += in case of captured mouse
2026-03-23 11:31:06 +01:00
83e35ba170 [rcore] refactor possible data loss on FileMove() (#5682) 2026-03-23 11:30:28 +01:00
22cc2554b1 Fix Memory out of bounds in [shapes] example - ball physics (#5683)
Update screenshot to shapes_bouncing_ball.png
2026-03-23 11:28:28 +01:00
1b084ff9f2 fixed error in readme, found by discord user the.enemy (#5680) 2026-03-22 09:06:03 +01:00
8a685877eb [rlsw] Remove position attribute from sw_vertex_t (#5677)
* review `sw_vertex_t`

* fix comment

* fix pop matrix
2026-03-20 12:07:50 +01:00
127 changed files with 10677 additions and 2026 deletions

View File

@ -28,20 +28,20 @@ jobs:
max-parallel: 1
matrix:
ARCH: ["arm64", "x86_64"]
env:
RELEASE_NAME: raylib-dev_android_api29_${{ matrix.ARCH }}
steps:
- name: Checkout
uses: actions/checkout@master
- name: Setup Release Version
run: |
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_android_api29_${{ matrix.ARCH }}" >> $GITHUB_ENV
shell: bash
if: github.event_name == 'release' && github.event.action == 'published'
- name: Setup Android NDK
id: setup-ndk
uses: nttld/setup-ndk@v1
@ -52,7 +52,7 @@ jobs:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- name: Setup Environment
run: |
run: |
mkdir build
cd build
mkdir ${{ env.RELEASE_NAME }}
@ -60,7 +60,7 @@ jobs:
mkdir include
mkdir lib
cd ../..
# Generating static + shared library for 64bit arquitectures and API version 29
- name: Build Library
run: |
@ -69,7 +69,7 @@ jobs:
make PLATFORM=PLATFORM_ANDROID ANDROID_ARCH=${{ matrix.ARCH }} ANDROID_API_VERSION=29 ANDROID_NDK=${{ env.ANDROID_NDK_HOME }} RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
cd ..
shell: cmd
- name: Generate Artifacts
run: |
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
@ -80,7 +80,7 @@ jobs:
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
cd build
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
@ -88,7 +88,7 @@ jobs:
path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1
with:

View File

@ -23,18 +23,18 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Environment
run: |
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxext-dev libxfixes-dev libwayland-dev libxkbcommon-dev
- name: Build Library
run: |
cd src
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=STATIC
cd ..
- name: Build Examples
run: |
cd examples

View File

@ -13,7 +13,7 @@ on:
- 'src/**'
- 'examples/**'
- '.github/workflows/windows_examples.yml'
permissions:
contents: read

View File

@ -42,23 +42,23 @@ jobs:
ARCH_NAME: "arm64"
COMPILER_PATH: "/usr/bin"
runner: "ubuntu-24.04-arm"
runs-on: ${{ matrix.runner }}
env:
RELEASE_NAME: raylib-dev_linux_${{ matrix.ARCH_NAME }}
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Setup Release Version
run: |
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_linux_${{ matrix.ARCH_NAME }}" >> $GITHUB_ENV
shell: bash
if: github.event_name == 'release' && github.event.action == 'published'
- name: Setup Environment
run: |
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends libglfw3 libglfw3-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libxext-dev libxfixes-dev libwayland-dev libxkbcommon-dev
mkdir build
@ -74,7 +74,7 @@ jobs:
run : |
sudo apt-get install gcc-multilib
if: matrix.bits == 32 && matrix.ARCH == 'i386'
# TODO: Support 32bit (i386) static/shared library building
- name: Build Library (32-bit)
run: |
@ -91,7 +91,7 @@ jobs:
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
cd ..
if: matrix.bits == 64 && matrix.ARCH == 'x86_64'
- name: Build Library (64-bit ARM)
run: |
cd src
@ -99,7 +99,7 @@ jobs:
make PLATFORM=PLATFORM_DESKTOP CC=gcc RAYLIB_LIBTYPE=SHARED RAYLIB_RELEASE_PATH="../build/${{ env.RELEASE_NAME }}/lib" -B
cd ..
if: matrix.bits == 64 && matrix.ARCH == 'aarch64'
- name: Generate Artifacts
run: |
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
@ -110,7 +110,7 @@ jobs:
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
cd build
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
@ -118,7 +118,7 @@ jobs:
path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1
with:

View File

@ -23,14 +23,14 @@ jobs:
permissions:
contents: write # for actions/upload-release-asset to upload release asset
runs-on: macos-latest
env:
RELEASE_NAME: raylib-dev_macos
steps:
- name: Checkout
uses: actions/checkout@master
- name: Setup Release Version
run: |
echo "RELEASE_NAME=raylib-${{ github.event.release.tag_name }}_macos" >> $GITHUB_ENV
@ -38,7 +38,7 @@ jobs:
if: github.event_name == 'release' && github.event.action == 'published'
- name: Setup Environment
run: |
run: |
mkdir build
cd build
mkdir ${{ env.RELEASE_NAME }}
@ -46,47 +46,47 @@ jobs:
mkdir include
mkdir lib
cd ../..
# Generating static + shared library, note that i386 architecture is deprecated
# Defining GL_SILENCE_DEPRECATION because OpenGL is deprecated on macOS
- name: Build Library
run: |
cd src
clang --version
# Extract version numbers from Makefile
brew install grep
RAYLIB_API_VERSION=`ggrep -Po 'RAYLIB_API_VERSION\s*=\s\K(.*)' Makefile`
RAYLIB_VERSION=`ggrep -Po 'RAYLIB_VERSION\s*=\s\K(.*)' Makefile`
# Build raylib x86_64 static
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=STATIC CUSTOM_CFLAGS="-target x86_64-apple-macos10.12 -DGL_SILENCE_DEPRECATION"
mv libraylib.a /tmp/libraylib_x86_64.a
make clean
# Build raylib arm64 static
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=STATIC CUSTOM_CFLAGS="-target arm64-apple-macos11 -DGL_SILENCE_DEPRECATION" -B
mv libraylib.a /tmp/libraylib_arm64.a
make clean
# Join x86_64 and arm64 static
lipo -create -output ../build/${{ env.RELEASE_NAME }}/lib/libraylib.a /tmp/libraylib_x86_64.a /tmp/libraylib_arm64.a
# Build raylib x86_64 dynamic
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=SHARED CUSTOM_CFLAGS="-target x86_64-apple-macos10.12 -DGL_SILENCE_DEPRECATION" CUSTOM_LDFLAGS="-target x86_64-apple-macos10.12" -B
mv libraylib.${RAYLIB_VERSION}.dylib /tmp/libraylib_x86_64.${RAYLIB_VERSION}.dylib
make clean
# Build raylib arm64 dynamic
make PLATFORM=PLATFORM_DESKTOP RAYLIB_LIBTYPE=SHARED CUSTOM_CFLAGS="-target arm64-apple-macos11 -DGL_SILENCE_DEPRECATION" CUSTOM_LDFLAGS="-target arm64-apple-macos11" -B
mv libraylib.${RAYLIB_VERSION}.dylib /tmp/libraylib_arm64.${RAYLIB_VERSION}.dylib
# Join x86_64 and arm64 dynamic
lipo -create -output ../build/${{ env.RELEASE_NAME }}/lib/libraylib.${RAYLIB_VERSION}.dylib /tmp/libraylib_x86_64.${RAYLIB_VERSION}.dylib /tmp/libraylib_arm64.${RAYLIB_VERSION}.dylib
ln -sv libraylib.${RAYLIB_VERSION}.dylib ../build/${{ env.RELEASE_NAME }}/lib/libraylib.dylib
ln -sv libraylib.${RAYLIB_VERSION}.dylib ../build/${{ env.RELEASE_NAME }}/lib/libraylib.${RAYLIB_API_VERSION}.dylib
cd ..
- name: Generate Artifacts
run: |
cp -v ./src/raylib.h ./build/${{ env.RELEASE_NAME }}/include
@ -97,7 +97,7 @@ jobs:
cp -v ./LICENSE ./build/${{ env.RELEASE_NAME }}/LICENSE
cd build
tar -czvf ${{ env.RELEASE_NAME }}.tar.gz ${{ env.RELEASE_NAME }}
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
@ -105,7 +105,7 @@ jobs:
path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1
with:

View File

@ -12,11 +12,11 @@ on:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v14
with:

1
.gitignore vendored
View File

@ -118,6 +118,7 @@ GTAGS
# Zig programming language
.zig-cache/
zig-cache/
zig-pkg/
zig-out/
build/
build-*/

View File

@ -4,7 +4,7 @@ changelog
Current Release: raylib 5.5 (18 November 2024)
-------------------------------------------------------------------------
Release: raylib 6.0 (?? March 2026)
Release: raylib 6.0 (23 April 2026)
-------------------------------------------------------------------------
KEY CHANGES:
- New Software Renderer backend [rlsw]
@ -21,11 +21,17 @@ KEY 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: 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: `ComputeSHA256()` (#5264) by @iamahuman1395
[rcore] ADDED: `GetKeyName()` (#4544) by @lecongsebastien
[rcore] REMOVED: GIF recording option, added example by @raysan5 -WARNING-
[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
@ -111,7 +117,7 @@ Detailed changes:
[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: 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: Forward declare the windows stuff, prevents failures in GCC (#5269) by @Jeffm2501
[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: `rlGetPixelDataSize()`, correct compressed data size calculation per blocks #5416 by @raysan5
[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: Shader loading API function names for more consistency #5631 by @raysan5 -WARNING-
[rlsw] ADDED: `swGetColorBuffer()` for convenience by @raysan5
@ -215,6 +221,7 @@ Detailed changes:
[rlsw] REVIEWED: C++ support (#5291) by @alexgb0
[rshapes] ADDED: `DrawLineDashed()` (#5222) by @luis605
[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: `DrawRectangleGradientEx()`, incorrect parameter names (#4980) by @vincent
[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: `ImageBlurGaussian()`, fix integer overflow in cast (#5037) by @garrisonhh
[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] 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
@ -263,16 +277,16 @@ Detailed changes:
[rtext] REVIEWED: `GetCodepointCount()`, misuse of cast (#4741) by @sleeptightAnsiC
[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()`, use static buffer, easier to use by @raysan5 -WARNING-
[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: `TextReplaceBetween()` by @raysan5
[rtext] REVIEWED: `TextReplace()` and `TextLength()`, avoid using `strcpy()` by @raysan5
[rtext] REVIEWED: `TextSubtext(), fixes (#4759) by @veins1
[rtext] REVIEWED: `TextToPascal()`, fix issue by @raysan5
[rtext] REVIEWED: `TextToFloat()`, remove removed inaccurate comment (#4596) by @hexmaster111
[rtext] REDESIGNED: `LoadFontData()`, added input parameter by @raysan5 -WARNING-
[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] 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
@ -299,6 +313,7 @@ Detailed changes:
[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, properly load 1 frame animations (#5561) by @arlez80
[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: `UplaodMesh()`, fix for devices without VAO support (#5692) by @psxdev
[rmodels] REVIEWED: `GenMeshTangents()`, improvements (#4937) by @Bigfoot71
[rmodels] REVIEWED: `UpdateModelAnimation()` optimization (#5244) by @Arrangemonk
[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: `DrawSphereEx()`, normals support (#4926) by @karl-zylinski
[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: Improvements to device configuration (#5577) by @mackron
[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: `UpdateSourceMetadata()` and `TextReplaceBetween()` 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: Report issues if logs can not be loaded 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: 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] 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
@ -755,16 +772,23 @@ Detailed changes:
[external] REVIEWED: `sdefl` and `sinfl` issues (#5367) by @raysan5
[external] REVIEWED: `sinfl_bsr()`, improvements by @RicoP
[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: miniaudio to v0.11.22 (#4983) by @M374LX
[external] UPDATED: miniaudio to v0.11.23 (#5234) by @pyrokn8
[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.6 (#4795) by @colleagueRiley
[external] UPDATED: RGFW to 1.7 (#4965) 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: `miniaudio` to v0.11.22 (#4983) by @M374LX
[external] UPDATED: `miniaudio` to v0.11.23 (#5234) by @pyrokn8
[external] UPDATED: `miniaudio` to v0.11.24 (#5506) by @vdemcak
[external] UPDATED: `RGFW` to 1.5 (#4688) 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.5-dev (#4976) by @M374LX
[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: `examples/examples_list`, to be used by `rexm` or other tools by @raysan5

View File

@ -526,26 +526,79 @@ Last but not least, I want to thank **raylib sponsors and all the raylib communi
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:
- **+320** closed issues (for a TOTAL of **+2130**!)
- **+1800** commits since previous RELEASE (for a TOTAL of **+9600**!)
- **18** functions ADDED to raylib API (for a TOTAL of **599**!)
- **+50** new examples to learn from (for a TOTAL of **212**!)
- **+200** new contributors (for a TOTAL of **+840**!)
- **+320** closed issues (for a TOTAL of **+2140**!)
- **+1950** commits since previous RELEASE (for a TOTAL of **+9700**!)
- **+20** new functions ADDED to raylib API (for a TOTAL of **600**!)
- **+50** new examples to learn from (for a TOTAL of **+210**!)
- **+210** new contributors (for a TOTAL of **+850**!)
Highlights for `raylib 6.0`:
- New Software Renderer backend [rlsw]
- 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` Software Renderer - [`rlsw`](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h)**: The biggest addition of this new release. A new software renderer backend, that allows raylib to run purely on CPU, with no neeed for a GPU. It finally closes the circle of my search for a portable self-contained, with **no-external-dependencies**, graphics library, able to run on any device providing some CPU-power and some RAM memory. It has been possible thanks to the amazing work of **Le Juez Victor** ([@Bigfoot71](https://github.com/Bigfoot71)), who created [`rlsw`](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h), a single-file header-only library implementing OpenGL 1.1+ specification, tailored to fit into raylib [`rlgl`](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) OpenGL wrapper, and allowing to run raylib seamlessly over CPU with **no code changes required on user side**. As expected, software rendering is slower than hardware-accelerated rendering but it is still fast enough to run basic application at 30-60 fps. Actually, it already proved it usefulness on a new [raylib port for ESP32](https://components.espressif.com/components/georgik/raylib/versions/6.0.0/readme) microcontroller by Espressif, useful for industrial applications, and opens the door to the upcoming RISC-V powered devices that start arriving to the marked, and many times come with no GPU. Along the new software renderer, some of the existing platform backends have been adapted to support it (SDL, RGFW, DRM) and also **new platforms backends have been created** to accomodate it (Win32, Emscripten), incluing a new `PLATFORM_MEMORY`, that allows direct rendering to a memory framebuffer.
- **`NEW` Platform backend: Memory - [`rcore_memory`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_memory.c)**: This new platform has been added along the **software renderer** backend, allowing 2d and 3d rendering over a **platform-agnostic memory framebuffer**, it can run headless and output frames can be directly exported to images. This new backend could also be useful for graphics rendering on servers or process images directly using the memory buffer.
- **`NEW` Platform backend: Win32 - [`rcore_desktop_win32`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_win32.c)**: A new **Windows platform backend** and the first step towards a potential replacement/alternative to the platform libraries currently used by raylib (GLFW/SDL/RGFW). This backend follows same API template structure than the other raylib backends, but directly implementing Win32 API calls. It allows initializing OpenGL GPU-accelerated windows and also GDI based windows, useful for the software renderer backend. This new backend approach, following a common template-structure and separating the platform logic by specific OS/Windowing system, will simplify code, improve maintenance, readability and portability for raylib, setting some bases for the future. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
- **`NEW` Platform backend: Emscripten - [`rcore_web_emscripten`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_web_emscripten.c)**: In the same line as Win32 backend, this new web backend moves away from `libglfw.js` and **directly implements Emscripten/JS functionality**, with **no other dependencies**, adding support for the new software renderer to draw directly on a **non-accelerated 2d canvas** but also supporting a WebGL-hardware-accelerated canvas when required. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
- **`REDESIGNED` Fullscreen modes and High-DPI content scaling**: After many years and many related issues, the full-screen and high-dpi content scaling support has been **completely redesigned** from scratch. New design prioritizes **borderless fullscreen modes** and automatically detects current monitor content scaling configuration to scale window and framebuffer accordingly when required. Still, High-DPI support must be requested by user if desired enabling `FLAG_WINDOW_HIGHDPI` on window creation. This new system has been carefully tested on Windows, Linux (X11, Wayland), macOS with multiple monitors and multiple resolutions, including 4K monitors.
- **`REDESIGNED` Skeletal Animation System**: A new animation system for 3d models has been created to support animation blending, between single frames but also between differents frames on different animations, to allow easy **timed transitions** between animations. This redesign implied reviewing several raylib structures to better accomodate animation data: `Model`, `ModelSkeleton`, `ModelAnimation`, but the API was simplified and support for GPU-skinning was improved with multiple optimizations.
- **`REDESIGNED` Build Config System - [`config.h`](https://github.com/raysan5/raylib/blob/master/src/config.h)**: raylib allows lot of customization for specific needs (i.e. disabling modules not needed for specific applications like rmodels or raudio) but previous implementation did not allow easely disabling some features from **custom build systems**. New design not only allows disabling features with simple `-DSUPPORT_FILEFORMAT_OBJ=0` on building command-line but also the full system has been reviewed, removing useless flags and exposing new ones.
- **`NEW` File System API**: Along the years, multiple filesystem functions have been added to raylib API as required but it felt somewhat inconsistent with some pieces missing. In this new release, the full filesystem API has beeen reviewed and reorganized, compiling all the functionality single module: [rcore](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1126), consequently `utils` module has been removed and build system has been simplified even more; **only 6-7 modules (.c) need to be compiled containing the full raylib library**. This new filesystem API will allow raylib to be used on the creation of custom build systems, as already demostrated with the new `rexm` tool for examples management. At the moment raylib includes **+40 file system management functions**, here a list with the new functions added:
```c
int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists)
int FileRemove(const char *fileName); // Remove file (if exists)
int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist
int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist
int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file
int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file
```
- **`NEW` Text Management API**: Along with the new file system functionality, a new set of text management functions has been added, also very useful for text procesing and also used in custom build systems creation using raylib. At the moment raylib includes **+30 text management functions**, here a list with the new functions added:
```c
char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
void UnloadTextLines(char **text, int lineCount); // Unload text lines
const char *TextRemoveSpaces(const char *text); // Remove text spaces, concat words
char *GetTextBetween(const char *text, const char *begin, const char *end); // Get text between two strings
char *TextReplace(const char *text, const char *search, const char *replacement); // Replace text string with new string
char *TextReplaceAlloc(const char *text, const char *search, const char *replacement); // Replace text string with new string, memory must be MemFree()
char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings
char *TextReplaceBetweenAlloc(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings, memory must be MemFree()
char *TextInsertAlloc(const char *text, const char *insert, int position); // Insert text in a defined byte position, memory must be MemFree()
```
- **`NEW` tool: raylib examples manager - [rexm](https://github.com/raysan5/raylib/tree/master/tools/rexm)**: raylib examples collection is huge, with **more than 200 examples** it was quite difficult to manage: adding, removing, renaming examples was a very costly process involving many files to be modified (including build systems), also the examples did not follow a common header convention neither a structure conventions. For that reason, a new support tool has been created: **rexm**, a raylib examples manager that allows to easely add/remove/rename examples, automatically fix inconsistencies and even **building and automated testing** on multiple platforms.
```
USAGE:
> rexm <command> <example_name> [<example_rename>]
COMMANDS:
create <new_example_name> : Creates an empty example, from internal template
add <example_name> : Add existing example to collection
rename <old_examples_name> <new_example_name> : Rename an existing example
remove <example_name> : Remove an existing example from collection
build <example_name> : Build example for Desktop and Web platforms
test <example_name> : Build and Test example for Desktop and Web platforms
validate : Validate examples collection, generates report
update : Validate and update examples collection, generates report
```
- **`NEW` +50 new examples**: Thanks to `rexm` and the simplification on examples management, this new raylib release includes +50 new examples to leearn from, most of them contributed by community.
Make sure to check raylib [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) for a detailed list of changes!
I want to **thank all the contributors (+850!**) that along the years have **greatly improved raylib** and pushed it further and better day after day. And **many thanks to raylib community and all raylib users** for supporting the library along those many years.
Finally, I want to thank [puffer.ai](https://puffer.ai/) and [comma.ai](https://comma.ai/) for **supporting and sponsoring the project** as platinum sponsors, along many others individuals that have been sponsoring raylib along the years. Thanks to all of you for allowing me to keep working on this library!
**After +12 years of development, `raylib 6.0` is today one of the bests libraries to enjoy games/tools/graphic programming!**
**Enjoy graphics programming with raylib!** :)

View File

@ -40,6 +40,7 @@ features
- Written in plain C code (C99) using PascalCase/camelCase notation
- Hardware accelerated with OpenGL: **1.1, 2.1, 3.3, 4.3, ES 2.0, ES 3.0**
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
- **Software Renderer** backend (no OpenGL required!): [rlsw](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h)
- Multiple **Fonts** formats supported (TTF, OTF, FNT, BDF, sprite fonts)
- Multiple texture formats supported, including **compressed formats** (DXT, ETC, ASTC)
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
@ -61,7 +62,7 @@ This is a basic raylib example, it creates a window and draws the text `"Congrat
int main(void)
{
InitWindow(800, 450, "raylib [core] example - basic window");
InitWindow(800, 450, "raylib example - basic window");
while (!WindowShouldClose())
{

View File

@ -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.
- [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve.
- raylib wishlists discussions are open to everyone to ask for improvements, feel free to check and comment:
- [raylib 7.0 wishlist](https://github.com/raysan5/raylib/discussions/5710)
- [raylib 6.0 wishlist](https://github.com/raysan5/raylib/discussions/4660)
- [raylib 5.0 wishlist](https://github.com/raysan5/raylib/discussions/2952)
- [raylib wishlist 2022](https://github.com/raysan5/raylib/discussions/2272)
@ -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`: Investigate alternative embedded platforms and realtime OSs
- [ ] `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
- [ ] `rtext`: Investigate the recently opened [`Slug`](https://sluglibrary.com/) font rendering algorithm
- [ ] `raudio`: Support microphone input, basic API to read microphone
- [ ] `rltexgpu`: Improve compressed textures support, loading and saving, improve KTX 2.0
- [ ] `rlobj`: Create OBJ loader, supporting material file separately (low priority)

View File

@ -2,7 +2,7 @@ const std = @import("std");
const builtin = @import("builtin");
/// Minimum supported version of Zig
const min_ver = "0.16.0-dev.2349+204fa8959";
const min_ver = "0.16.0-dev.3013+abd131e33";
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
const emccOutputFile = "index.html";
@ -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.linkSystemLibrary("EGL", .{});
raylib.root_module.linkSystemLibrary("gbm", .{});
if (options.opengl_version != .gl_soft) {
raylib.root_module.linkSystemLibrary("EGL", .{});
raylib.root_module.linkSystemLibrary("gbm", .{});
}
raylib.root_module.linkSystemLibrary("libdrm", .{ .use_pkg_config = .force });
raylib.root_module.addCMacro("PLATFORM_DRM", "");
@ -264,7 +266,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
setDesktopPlatform(raylib, .android);
} else {
try c_source_files.append(b.allocator, "src/rglfw.c");
switch (options.platform) {
.glfw => try c_source_files.append(b.allocator, "src/rglfw.c"),
.rgfw, .sdl, .drm, .android => {},
}
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
raylib.root_module.addCMacro("_GLFW_X11", "");
@ -413,6 +418,7 @@ pub const Options = struct {
pub const OpenglVersion = enum {
auto,
gl_soft,
gl_1_1,
gl_2_1,
gl_3_3,
@ -423,6 +429,7 @@ pub const OpenglVersion = enum {
pub fn toCMacroStr(self: @This()) []const u8 {
switch (self) {
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
.gl_soft => return "GRAPHICS_API_OPENGL_SOFTWARE",
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
@ -434,6 +441,7 @@ pub const OpenglVersion = enum {
};
pub const LinuxDisplayBackend = enum {
None,
X11,
Wayland,
Both,

View File

@ -7,8 +7,8 @@
.dependencies = .{
.xcode_frameworks = .{
.url = "git+https://github.com/hexops/xcode-frameworks#9a45f3ac977fd25dff77e58c6de1870b6808c4a7",
.hash = "N-V-__8AABHMqAWYuRdIlflwi8gksPnlUMQBiSxAqQAAZFms",
.url = "https://pkg.machengine.org/xcode-frameworks/8a1cfb373587ea4c9bb1468b7c986462d8d4e10e.tar.gz",
.hash = "N-V-__8AALShqgXkvqYU6f__FrA22SMWmi2TXCJjNTO1m8XJ",
.lazy = true,
},
.emsdk = .{

View File

@ -96,21 +96,30 @@ elseif (${PLATFORM} STREQUAL "Android")
elseif ("${PLATFORM}" STREQUAL "DRM")
set(PLATFORM_CPP "PLATFORM_DRM")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
add_definitions(-D_DEFAULT_SOURCE)
add_definitions(-DEGL_NO_X11)
add_definitions(-DPLATFORM_DRM)
find_library(GLESV2 GLESv2)
find_library(EGL EGL)
find_library(DRM drm)
find_library(GBM gbm)
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
include_directories(/usr/include/libdrm)
endif ()
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
if ("${OPENGL_VERSION}" STREQUAL "Software")
# software rendering does not require EGL/GBM.
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
set(LIBS_PRIVATE ${DRM} atomic pthread dl)
else ()
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
add_definitions(-DEGL_NO_X11)
find_library(GLESV2 GLESv2)
find_library(EGL EGL)
find_library(GBM gbm)
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
endif ()
set(LIBS_PUBLIC m)
elseif ("${PLATFORM}" STREQUAL "SDL")

View File

@ -1153,7 +1153,10 @@ text/text_font_filters: text/text_font_filters.c
--preload-file text/resources/KAISG.ttf@resources/KAISG.ttf
text/text_font_loading: text/text_font_loading.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file text/resources/pixantiqua.fnt@resources/pixantiqua.fnt \
--preload-file text/resources/pixantiqua.png@resources/pixantiqua.png \
--preload-file text/resources/pixantiqua.ttf@resources/pixantiqua.ttf
text/text_font_sdf: text/text_font_sdf.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \

View File

@ -223,7 +223,7 @@ Examples using raylib models functionality, including models loading/generation
### 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 |
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|

View 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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -110,16 +110,16 @@ int main(void)
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText(TextFormat("sine frequency: %i", sineFrequency), screenWidth - 220, 10, 20, RED);
DrawText(TextFormat("pan: %.2f", pan), screenWidth - 220, 30, 20, RED);
DrawText("Up/down to change frequency", 10, 10, 20, DARKGRAY);
DrawText("Left/right to pan", 10, 30, 20, DARKGRAY);
int windowStart = (GetTime() - sineStartTime)*SAMPLE_RATE;
int windowSize = 0.1f*SAMPLE_RATE;
int wavelength = SAMPLE_RATE/sineFrequency;
// Draw a sine wave with the same frequency as the one being sent to the audio stream
for (int i = 0; i < screenWidth; i++)
{

6051
examples/audio/raygui.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -23,15 +23,15 @@ void main()
float localX = mod(fragCoord.x, cellWidth);
float barWidth = cellWidth - 1.0;
vec4 color = WHITE;
if (localX <= barWidth)
{
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
if (fragTexCoord.y < amplitude) color = BLACK;
}
gl_FragColor = color;
}

View File

@ -21,15 +21,15 @@ void main()
float localX = mod(fragCoord.x, cellWidth);
float barWidth = cellWidth - 1.0;
vec4 color = WHITE;
if (localX <= barWidth)
{
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
if (fragTexCoord.y < amplitude) color = BLACK;
}
gl_FragColor = color;
}

View File

@ -21,15 +21,15 @@ void main()
float localX = mod(fragCoord.x, cellWidth);
float barWidth = cellWidth - 1.0;
vec4 color = WHITE;
if (localX <= barWidth)
{
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
if (fragTexCoord.y < amplitude) color = BLACK;
}
finalColor = color;
}

View File

@ -73,7 +73,7 @@ int main(void)
}
// Draw UI info
DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY);
DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY);
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);

View File

@ -4,7 +4,7 @@
*
* Example complexity rating: [★★☆☆] 2/4
*
* NOTE: raylib defined keys refer to ENG-US Keyboard layout,
* NOTE: raylib defined keys refer to ENG-US Keyboard layout,
* mapping to other layouts is up to the user
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
@ -43,20 +43,20 @@ int main(void)
int line01KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45;
line01KeyWidths[13] = 62; // PRINTSCREEN
int line01Keys[15] = {
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
int line01Keys[15] = {
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
};
// Keyboard line 02
int line02KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45;
line02KeyWidths[0] = 25; // GRAVE
line02KeyWidths[13] = 82; // BACKSPACE
int line02Keys[15] = {
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
int line02Keys[15] = {
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE };
// Keyboard line 03
@ -103,7 +103,7 @@ int main(void)
KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL,
KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT
};
Vector2 keyboardOffset = { 26, 80 };
SetTargetFPS(60);
@ -128,23 +128,23 @@ int main(void)
ClearBackground(RAYWHITE);
DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY);
// Keyboard line 01 - 15 keys
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
for (int i = 0, recOffsetX = 0; i < 15; i++)
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, (float)line01KeyWidths[i], 30.0f }, line01Keys[i]);
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 02 - 15 keys
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
for (int i = 0, recOffsetX = 0; i < 15; i++)
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, (float)line02KeyWidths[i], 38.0f }, line02Keys[i]);
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 03 - 15 keys
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
for (int i = 0, recOffsetX = 0; i < 15; i++)
@ -324,8 +324,8 @@ static void GuiKeyboardKey(Rectangle bounds, int key)
DrawText(GetKeyText(key), (int)(bounds.x + 4), (int)(bounds.y + 4), 10, DARKGRAY);
}
}
if (CheckCollisionPointRec(GetMousePosition(), bounds))
if (CheckCollisionPointRec(GetMousePosition(), bounds))
{
DrawRectangleRec(bounds, Fade(RED, 0.2f));
DrawRectangleLinesEx(bounds, 3.0f, RED);

View File

@ -111,7 +111,7 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
free(rectangles);
RL_FREE(rectangles);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -43,7 +43,7 @@
// Module Functions Declaration
//------------------------------------------------------------------------------------
static bool IsUpperBodyBone(const char *boneName);
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim1, int frame1,
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim1, int frame1,
ModelAnimation *anim2, int frame2, float blend, bool upperBodyBlend);
//------------------------------------------------------------------------------------
@ -86,7 +86,7 @@ int main(void)
int animIndex1 = 3; // Attack animation (index 3)
int animCurrentFrame0 = 0;
int animCurrentFrame1 = 0;
// Validate indices
if (animIndex0 >= animCount) animIndex0 = 0;
if (animIndex1 >= animCount) animIndex1 = (animCount > 1) ? 1 : 0;
@ -109,7 +109,7 @@ int main(void)
// Update animation frames
ModelAnimation anim0 = anims[animIndex0];
ModelAnimation anim1 = anims[animIndex1];
animCurrentFrame0 = (animCurrentFrame0 + 1)%anim0.keyframeCount;
animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.keyframeCount;
@ -117,11 +117,11 @@ int main(void)
// When upperBodyBlend is ON: upper body = attack (1.0), lower body = walk (0.0)
// When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack)
float blendFactor = (upperBodyBlend? 1.0f : 0.5f);
UpdateModelAnimationBones(&model, &anim0, animCurrentFrame0,
UpdateModelAnimationBones(&model, &anim0, animCurrentFrame0,
&anim1, animCurrentFrame1, blendFactor, upperBodyBlend);
// raylib provided animation blending function
//UpdateModelAnimationEx(model, anim0, (float)animCurrentFrame0,
//UpdateModelAnimationEx(model, anim0, (float)animCurrentFrame0,
// anim1, (float)animCurrentFrame1, blendFactor);
//----------------------------------------------------------------------------------
@ -142,8 +142,8 @@ int main(void)
// Draw UI
DrawText(TextFormat("ANIM 0: %s", anim0.name), 10, 10, 20, GRAY);
DrawText(TextFormat("ANIM 1: %s", anim1.name), 10, 40, 20, GRAY);
DrawText(TextFormat("[SPACE] Toggle blending mode: %s",
upperBodyBlend? "Upper/Lower Body Blending" : "Uniform Blending"),
DrawText(TextFormat("[SPACE] Toggle blending mode: %s",
upperBodyBlend? "Upper/Lower Body Blending" : "Uniform Blending"),
10, GetScreenHeight() - 30, 20, DARKGRAY);
EndDrawing();
@ -180,7 +180,7 @@ static bool IsUpperBodyBone(const char *boneName)
{
return true;
}
// Check if bone name contains upper body keywords
if (strstr(boneName, "spine") != NULL || strstr(boneName, "chest") != NULL ||
strstr(boneName, "neck") != NULL || strstr(boneName, "head") != NULL ||
@ -189,12 +189,12 @@ static bool IsUpperBodyBone(const char *boneName)
{
return true;
}
return false;
}
// Blend two animations per-bone with selective upper/lower body blending
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int frame0,
static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int frame0,
ModelAnimation *anim1, int frame1, float blend, bool upperBodyBlend)
{
// Validate inputs
@ -204,59 +204,59 @@ static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int f
{
// Clamp blend factor to [0, 1]
blend = fminf(1.0f, fmaxf(0.0f, blend));
// Ensure frame indices are valid
if (frame0 >= anim0->keyframeCount) frame0 = anim0->keyframeCount - 1;
if (frame1 >= anim1->keyframeCount) frame1 = anim1->keyframeCount - 1;
if (frame0 < 0) frame0 = 0;
if (frame1 < 0) frame1 = 0;
// Get bone count (use minimum of all to be safe)
int boneCount = model->skeleton.boneCount;
if (anim0->boneCount < boneCount) boneCount = anim0->boneCount;
if (anim1->boneCount < boneCount) boneCount = anim1->boneCount;
// Blend each bone
for (int boneIndex = 0; boneIndex < boneCount; boneIndex++)
{
// Determine blend factor for this bone
float boneBlendFactor = blend;
// If upper body blending is enabled, use different blend factors for upper vs lower body
if (upperBodyBlend)
{
const char *boneName = model->skeleton.bones[boneIndex].name;
bool isUpperBody = IsUpperBodyBone(boneName);
// Upper body: use anim1 (attack), Lower body: use anim0 (walk)
// blend = 0.0 means full anim0 (walk), 1.0 means full anim1 (attack)
if (isUpperBody) boneBlendFactor = blend; // Upper body: blend towards anim1 (attack)
else boneBlendFactor = 1.0f - blend; // Lower body: blend towards anim0 (walk) - invert the blend
}
// Get transforms from both animations
Transform *bindTransform = &model->skeleton.bindPose[boneIndex];
Transform *animTransform0 = &anim0->keyframePoses[frame0][boneIndex];
Transform *animTransform1 = &anim1->keyframePoses[frame1][boneIndex];
// Blend the transforms
Transform blended = { 0 };
blended.translation = Vector3Lerp(animTransform0->translation, animTransform1->translation, boneBlendFactor);
blended.rotation = QuaternionSlerp(animTransform0->rotation, animTransform1->rotation, boneBlendFactor);
blended.scale = Vector3Lerp(animTransform0->scale, animTransform1->scale, boneBlendFactor);
// Convert bind pose to matrix
Matrix bindMatrix = MatrixMultiply(MatrixMultiply(
MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z),
QuaternionToMatrix(bindTransform->rotation)),
MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z));
// Convert blended transform to matrix
Matrix blendedMatrix = MatrixMultiply(MatrixMultiply(
MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z),
QuaternionToMatrix(blended.rotation)),
MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z));
// Calculate final bone matrix (similar to UpdateModelAnimationBones)
model->boneMatrices[boneIndex] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix);
}
@ -276,7 +276,7 @@ static void UpdateModelAnimationBones(Model *model, ModelAnimation *anim0, int f
bool bufferUpdateRequired = false; // Flag to check when anim vertex information is updated
// Skip if missing bone data or missing anim buffers initialization
if ((mesh.boneWeights == NULL) || (mesh.boneIndices == NULL) ||
if ((mesh.boneWeights == NULL) || (mesh.boneIndices == NULL) ||
(mesh.animVertices == NULL) || (mesh.animNormals == NULL)) continue;
for (int vCounter = 0; vCounter < vertexValuesCount; vCounter += 3)

View File

@ -3,7 +3,7 @@
* raylib [models] example - animation blending
*
* Example complexity rating: [★★★★] 4/4
*
*
* Example originally created with raylib 5.5, last time updated with raylib 6.0
*
* Example contributed by Kirandeep (@Kirandeep-Singh-Khehra) and reviewed by Ramon Santamaria (@raysan5)
@ -57,7 +57,7 @@ int main(void)
// WARNING: It requires SUPPORT_GPU_SKINNING enabled on raylib (disabled by default)
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
// Assign skinning shader to all materials shaders
//for (int i = 0; i < model.materialCount; i++) model.materials[i].shader = skinningShader;
@ -105,7 +105,7 @@ int main(void)
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera, CAMERA_ORBITAL);
if (IsKeyPressed(KEY_P)) animPause = !animPause;
if (!animPause)
@ -127,7 +127,7 @@ int main(void)
}
// Set animation transition
animTransition = true;
animTransition = true;
animBlendTimeCounter = 0.0f;
animBlendFactor = 0.0f;
}
@ -182,7 +182,7 @@ int main(void)
animCurrentFrame0 += animFrameSpeed0;
if (animCurrentFrame0 >= anims[animIndex0].keyframeCount) animCurrentFrame0 = 0.0f;
UpdateModelAnimation(model, anims[animIndex0], animCurrentFrame0);
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
// anims[animIndex1], animCurrentFrame1, 0.0f); // Same as above, first animation frame blend
}
else if (currentAnimPlaying == 1)
@ -191,7 +191,7 @@ int main(void)
animCurrentFrame1 += animFrameSpeed1;
if (animCurrentFrame1 >= anims[animIndex1].keyframeCount) animCurrentFrame1 = 0.0f;
UpdateModelAnimation(model, anims[animIndex1], animCurrentFrame1);
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
//UpdateModelAnimationEx(model, anims[animIndex0], animCurrentFrame0,
// anims[animIndex1], animCurrentFrame1, 1.0f); // Same as above, second animation frame blend
}
}
@ -213,7 +213,7 @@ int main(void)
DrawModel(model, position, 1.0f, WHITE); // Draw animated model
DrawGrid(10, 1.0f);
EndMode3D();
if (animTransition) DrawText("ANIM TRANSITION BLENDING!", 170, 50, 30, BLUE);
@ -221,18 +221,18 @@ int main(void)
// Draw UI elements
//---------------------------------------------------------------------------------------------
if (dropdownEditMode0) GuiDisable();
GuiSlider((Rectangle){ 10, 38, 160, 12 },
GuiSlider((Rectangle){ 10, 38, 160, 12 },
NULL, TextFormat("x%.1f", animFrameSpeed0), &animFrameSpeed0, 0.1f, 2.0f);
GuiEnable();
if (dropdownEditMode1) GuiDisable();
GuiSlider((Rectangle){ GetScreenWidth() - 170.0f, 38, 160, 12 },
GuiSlider((Rectangle){ GetScreenWidth() - 170.0f, 38, 160, 12 },
TextFormat("%.1fx", animFrameSpeed1), NULL, &animFrameSpeed1, 0.1f, 2.0f);
GuiEnable();
// Draw animation selectors for blending transition
// NOTE: Transition does not start until requested
// NOTE: Transition does not start until requested
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 1);
if (GuiDropdownBox((Rectangle){ 10, 10, 160, 24 }, TextJoin(animNames, animCount, ";"),
if (GuiDropdownBox((Rectangle){ 10, 10, 160, 24 }, TextJoin(animNames, animCount, ";"),
&animIndex0, dropdownEditMode0)) dropdownEditMode0 = !dropdownEditMode0;
// Blending process progress bar
@ -249,7 +249,7 @@ int main(void)
TextFormat("FRAME: %.2f / %i", animFrameProgress0, anims[animIndex0].keyframeCount),
&animFrameProgress0, 0.0f, (float)anims[animIndex0].keyframeCount);
for (int i = 0; i < anims[animIndex0].keyframeCount; i++)
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex0].keyframeCount)*(float)i),
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex0].keyframeCount)*(float)i),
GetScreenHeight() - 60, 1, 20, BLUE);
// Draw playing timeline with keyframes for anim1[]
@ -257,7 +257,7 @@ int main(void)
TextFormat("FRAME: %.2f / %i", animFrameProgress1, anims[animIndex1].keyframeCount),
&animFrameProgress1, 0.0f, (float)anims[animIndex1].keyframeCount);
for (int i = 0; i < anims[animIndex1].keyframeCount; i++)
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
DrawRectangle(60 + (int)(((float)(GetScreenWidth() - 180)/(float)anims[animIndex1].keyframeCount)*(float)i),
GetScreenHeight() - 30, 1, 20, BLUE);
//---------------------------------------------------------------------------------------------
@ -270,7 +270,7 @@ int main(void)
UnloadModelAnimations(anims, animCount); // Unload model animation
UnloadModel(model); // Unload model and meshes/material
UnloadShader(skinningShader); // Unload GPU skinning shader
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -94,26 +94,26 @@ int main(void)
BeginMode3D(camera);
DrawModel(model, position, 1.0f, WHITE);
DrawGrid(10, 1.0f);
EndMode3D();
// Draw UI, select anim and playing speed
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 1);
if (GuiDropdownBox((Rectangle){ 10, 10, 140, 24 }, TextJoin(animNames, animCount, ";"),
if (GuiDropdownBox((Rectangle){ 10, 10, 140, 24 }, TextJoin(animNames, animCount, ";"),
&animIndex, dropdownEditMode)) dropdownEditMode = !dropdownEditMode;
GuiSlider((Rectangle){ 260, 10, 500, 24 }, "FRAME SPEED: ", TextFormat("x%.1f", animFrameSpeed),
&animFrameSpeed, 0.1f, 2.0f);
// Draw playing timeline with keyframes
GuiLabel((Rectangle){ 10, GetScreenHeight() - 64.0f, GetScreenWidth() - 20.0f, 24 },
GuiLabel((Rectangle){ 10, GetScreenHeight() - 64.0f, GetScreenWidth() - 20.0f, 24 },
TextFormat("CURRENT FRAME: %.2f / %i", animFrameProgress, anims[animIndex].keyframeCount));
GuiProgressBar((Rectangle){ 10, GetScreenHeight() - 40.0f, GetScreenWidth() - 20.0f, 24 }, NULL, NULL,
&animFrameProgress, 0.0f, (float)anims[animIndex].keyframeCount);
for (int i = 0; i < anims[animIndex].keyframeCount; i++)
DrawRectangle(10 + (int)(((float)(GetScreenWidth() - 20)/(float)anims[animIndex].keyframeCount)*(float)i),
DrawRectangle(10 + (int)(((float)(GetScreenWidth() - 20)/(float)anims[animIndex].keyframeCount)*(float)i),
GetScreenHeight() - 40, 1, 24, BLUE);
EndDrawing();

View File

@ -60,7 +60,7 @@ int main(void)
}
}
}
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
@ -109,7 +109,7 @@ int main(void)
}
}
}
// Remove the closest voxel if one was hit
if (voxelFound)
{
@ -145,9 +145,9 @@ int main(void)
}
}
}
EndMode3D();
// Draw reference point for raycasting to delete blocks
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 4, RED);
@ -161,7 +161,7 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadModel(cubeModel);
CloseWindow();
//--------------------------------------------------------------------------------------

View File

@ -108,7 +108,7 @@ int main(void)
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
bool showModel = true;
Model decalModels[MAX_DECALS] = { 0 };
static Model decalModels[MAX_DECALS] = { 0 };
int decalCount = 0;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second

View File

@ -16,6 +16,7 @@
********************************************************************************************/
#include "raylib.h"
#include "rlgl.h"
#include <stdlib.h> // Required for: rand()
#include <math.h> // Required for: cosf(), sinf()
@ -26,8 +27,9 @@
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
// Generate mesh using points
static Mesh GenMeshPoints(int numPoints);
static Mesh GenMeshPoints(int numPoints); // Generate mesh using points
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters
//------------------------------------------------------------------------------------
// Program main entry point
@ -184,3 +186,30 @@ static Mesh GenMeshPoints(int numPoints)
return mesh;
}
// Draw a model points
// WARNING: OpenGL ES 2.0 does not support point mode drawing
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint)
{
rlEnablePointMode();
rlDisableBackfaceCulling();
DrawModel(model, position, scale, tint);
rlEnableBackfaceCulling();
rlDisablePointMode();
}
// Draw a model points
// WARNING: OpenGL ES 2.0 does not support point mode drawing
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
{
rlEnablePointMode();
rlDisableBackfaceCulling();
DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
rlEnableBackfaceCulling();
rlDisablePointMode();
}

View File

@ -92,7 +92,7 @@ int main(void)
}
else
{
// TODO: WARNING: On PLATFORM_WEB it requires a big amount of memory to process input image
// TODO: WARNING: On PLATFORM_WEB it requires a big amount of memory to process input image
// and generate the required cubemap image to be passed to rlLoadTextureCubemap()
Image image = LoadImage("resources/skybox.png");
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);

View File

@ -41,6 +41,9 @@ int main(void)
Model model = LoadModel("resources/models/obj/plane.obj"); // Load model
Texture2D texture = LoadTexture("resources/models/obj/plane_diffuse.png"); // Load model texture
SetTextureWrap(texture, TEXTURE_WRAP_REPEAT); // Force Repeat to avoid issue on Web version
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture
float pitch = 0.0f;

View File

@ -13,9 +13,9 @@
| models/vox/chr_knight.vox | ❔ | ❔ | - |
| models/vox/chr_sword.vox | ❔ | ❔ | - |
| models/vox/monu9.vox | ❔ | ❔ | - |
| billboard.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| billboard.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| cubicmap_atlas.png | [@emegeme](https://github.com/emegeme) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| cubicmap_atlas.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| heightmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| dresden_square_1k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |
| dresden_square_2k.hdr | [HDRIHaven](https://hdrihaven.com/hdri/?h=dresden_square) | [CC0](https://hdrihaven.com/p/license.php) | - |

View File

@ -14,7 +14,7 @@ void main()
{
// Fetch color from texture sampler
vec4 texelColor = texture2D(texture0, fragTexCoord);
// Calculate final fragment color
gl_FragColor = texelColor*colDiffuse*fragColor;
}

View File

@ -23,7 +23,7 @@ void main()
int boneIndex1 = int(vertexBoneIndices.y);
int boneIndex2 = int(vertexBoneIndices.z);
int boneIndex3 = int(vertexBoneIndices.w);
// WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
mat4 boneMatrixTransposed0 = mat4(
vec4(boneMatrices[boneIndex0][0].x, boneMatrices[boneIndex0][1].x, boneMatrices[boneIndex0][2].x, boneMatrices[boneIndex0][3].x),
@ -45,13 +45,13 @@ void main()
vec4(boneMatrices[boneIndex3][0].y, boneMatrices[boneIndex3][1].y, boneMatrices[boneIndex3][2].y, boneMatrices[boneIndex3][3].y),
vec4(boneMatrices[boneIndex3][0].z, boneMatrices[boneIndex3][1].z, boneMatrices[boneIndex3][2].z, boneMatrices[boneIndex3][3].z),
vec4(boneMatrices[boneIndex3][0].w, boneMatrices[boneIndex3][1].w, boneMatrices[boneIndex3][2].w, boneMatrices[boneIndex3][3].w));
vec4 skinnedPosition =
vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;

View File

@ -12,7 +12,7 @@ void main()
{
// Fetch color from texture sampler
vec4 texelColor = texture2D(texture0, fragTexCoord);
// Calculate final fragment color
gl_FragColor = texelColor*colDiffuse*fragColor;
}

View File

@ -23,7 +23,7 @@ void main()
int boneIndex1 = int(vertexBoneIndices.y);
int boneIndex2 = int(vertexBoneIndices.z);
int boneIndex3 = int(vertexBoneIndices.w);
// WARNING: OpenGL ES 2.0 does not support automatic matrix transposing, neither transpose() function
mat4 boneMatrixTransposed0 = mat4(
vec4(boneMatrices[boneIndex0][0].x, boneMatrices[boneIndex0][1].x, boneMatrices[boneIndex0][2].x, boneMatrices[boneIndex0][3].x),
@ -45,13 +45,13 @@ void main()
vec4(boneMatrices[boneIndex3][0].y, boneMatrices[boneIndex3][1].y, boneMatrices[boneIndex3][2].y, boneMatrices[boneIndex3][3].y),
vec4(boneMatrices[boneIndex3][0].z, boneMatrices[boneIndex3][1].z, boneMatrices[boneIndex3][2].z, boneMatrices[boneIndex3][3].z),
vec4(boneMatrices[boneIndex3][0].w, boneMatrices[boneIndex3][1].w, boneMatrices[boneIndex3][2].w, boneMatrices[boneIndex3][3].w));
vec4 skinnedPosition =
vertexBoneWeights.x*(boneMatrixTransposed0*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.y*(boneMatrixTransposed1*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.z*(boneMatrixTransposed2*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.w*(boneMatrixTransposed3*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;

View File

@ -26,17 +26,17 @@ void main()
int boneIndex1 = int(vertexBoneIndices.y);
int boneIndex2 = int(vertexBoneIndices.z);
int boneIndex3 = int(vertexBoneIndices.w);
vec4 skinnedPosition =
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexPosition, 1.0));
vec4 skinnedNormal =
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexNormal, 0.0)) +
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexNormal, 0.0)) +
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexNormal, 0.0)) +
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexNormal, 0.0)) +
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexNormal, 0.0)) +
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexNormal, 0.0));
skinnedNormal.w = 0.0;

View File

@ -58,12 +58,12 @@ void main()
float gray = GreyScale(cellColor);
float n = 4096.0;
// Character set from https://www.shadertoy.com/view/lssGDj
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
if (gray > 0.2) n = 65600.0; // :
if (gray > 0.3) n = 18725316.0; // v
if (gray > 0.4) n = 15255086.0; // o
if (gray > 0.4) n = 15255086.0; // o
if (gray > 0.5) n = 13121101.0; // &
if (gray > 0.6) n = 15252014.0; // 8
if (gray > 0.7) n = 13195790.0; // @

View File

@ -12,5 +12,5 @@ void main()
fragTexCoord = vertexTexCoord;
// Calculate final vertex position
gl_Position = vec4(vertexPosition, 1.0);
gl_Position = vec4(vertexPosition, 1.0);
}

View File

@ -1,5 +1,5 @@
#version 100
#extension GL_EXT_frag_depth : enable
#extension GL_EXT_frag_depth : enable
precision mediump float;
@ -14,7 +14,7 @@ uniform vec4 colDiffuse;
void main()
{
vec4 texelColor = texture2D(texture0, fragTexCoord);
gl_FragColor = texelColor*colDiffuse*fragColor;
gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
}

View File

@ -24,13 +24,13 @@ void main()
{
// Store the fragment position vector in the first gbuffer texture
//gPosition = fragPosition;
// Store the per-fragment normals into the gbuffer
//gNormal = normalize(fragNormal);
// Store the diffuse per-fragment color
gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
// Store specular intensity in gAlbedoSpec's alpha component
gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
}

View File

@ -48,7 +48,7 @@ void main()
{
// Calculate vertex attributes for fragment shader
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
fragPosition = worldPos.xyz;
fragPosition = worldPos.xyz;
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;

View File

@ -1,7 +1,7 @@
#version 100
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
varying vec2 fragTexCoord;

View File

@ -32,12 +32,12 @@ float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
{
p.x = abs(p.x);
float l = length(p.xy);
p.xy = mat2(-c.x, c.y,
p.xy = mat2(-c.x, c.y,
c.y, c.x)*p.xy;
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
(p.x>0.0)?p.y:l);
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
vec2 d = abs(q) - w;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
@ -56,9 +56,9 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
}
vec2 q = vec2(length(ap.yz), ap.x);
float w = sqrt(r*r-h*h);
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : abs(length(q)-r)) - t;
}
@ -110,8 +110,8 @@ vec2 raycast(in vec3 ro, in vec3 rd)
if (t>tmax) break;
vec2 h = map(ro+rd*t);
if (abs(h.x) < (0.0001*t))
{
res = vec2(t,h.y);
{
res = vec2(t,h.y);
break;
}
t += h.x;
@ -146,9 +146,9 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
vec3 calcNormal(in vec3 pos)
{
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map(pos + e.yyx).x +
e.yxy*map(pos + e.yxy).x +
return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map(pos + e.yyx).x +
e.yxy*map(pos + e.yxy).x +
e.xxx*map(pos + e.xxx).x);
}
@ -176,15 +176,15 @@ float checkersGradBox(in vec2 p)
// analytical integral (box filter)
vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
// xor pattern
return 0.5 - 0.5*i.x*i.y;
return 0.5 - 0.5*i.x*i.y;
}
// https://www.shadertoy.com/view/tdS3DG
vec4 render(in vec3 ro, in vec3 rd)
{
{
// background
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
// raycast scene
vec2 res = raycast(ro,rd);
float t = res.x;
@ -194,11 +194,11 @@ vec4 render(in vec3 ro, in vec3 rd)
vec3 pos = ro + t*rd;
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
vec3 ref = reflect(rd, nor);
// material
// material
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
float ks = 1.0;
if (m<1.5)
{
float f = checkersGradBox(3.0*pos.xz);
@ -208,7 +208,7 @@ vec4 render(in vec3 ro, in vec3 rd)
// lighting
float occ = calcAO(pos, nor);
vec3 lin = vec3(0.0);
// sun
@ -249,7 +249,7 @@ vec4 render(in vec3 ro, in vec3 rd)
dif *= occ;
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
}
col = lin;
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
@ -289,7 +289,7 @@ void main()
color = res.xyz;
depth = CalcDepth(rd,res.w);
}
gl_FragColor = vec4(color , 1.0);
gl_FragDepthEXT = depth;
}

View File

@ -48,7 +48,7 @@ void main()
float normR = float(iter - (iter/55)*55)/55.0;
float normG = float(iter - (iter/69)*69)/69.0;
float normB = float(iter - (iter/40)*40)/40.0;
gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
return;
}

View File

@ -52,7 +52,7 @@ void main()
float specCo = 0.0;
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
specular += specCo;

View File

@ -21,7 +21,7 @@ void main()
// Convert the (normalized) texel color RED component (GB would work, too)
// to the palette index by scaling up from [0..1] to [0..255]
int index = int(texelColor.r*255.0);
ivec3 color = ivec3(0);
// NOTE: On GLSL 100 we are not allowed to index a uniform array by a variable value,
@ -34,7 +34,7 @@ void main()
else if (index == 5) color = palette[5];
else if (index == 6) color = palette[6];
else if (index == 7) color = palette[7];
//gl_FragColor = texture2D(palette, texelColor.xy); // Alternative to ivec3
// Calculate final fragment color. Note that the palette color components

View File

@ -83,11 +83,11 @@ vec3 ComputePBR()
{
vec3 albedo = texture2D(albedoMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
float metallic = clamp(metallicValue, 0.0, 1.0);
float roughness = clamp(roughnessValue, 0.0, 1.0);
float ao = clamp(aoValue, 0.0, 1.0);
if (useTexMRA == 1)
{
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
@ -132,18 +132,18 @@ vec3 ComputePBR()
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
// Difuse and spec light can't be above 1.0
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
vec3 kD = vec3(1.0) - F;
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
kD *= 1.0 - metallic;
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result
}
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
return (ambientFinal + lightAccum*ao + emissive);
}
@ -153,7 +153,7 @@ void main()
// HDR tonemapping
color = pow(color, color + vec3(1.0));
// Gamma correction
color = pow(color, vec3(1.0/2.2));

View File

@ -60,7 +60,7 @@ void main()
float bias = max(0.0008*(1.0 - dot(normal, l)), 0.00008);
int shadowCounter = 0;
const int numSamples = 9;
// PCF (percentage-closer filtering) algorithm:
// Instead of testing if just one point is closer to the current point,
// we test the surrounding points as well
@ -74,7 +74,7 @@ void main()
if (curDepth - bias > sampleDepth) shadowCounter++;
}
}
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
// Add ambient lighting whether in shadow or not

View File

@ -56,12 +56,12 @@ void main()
float gray = GreyScale(cellColor);
float n = 4096.0;
// Character set from https://www.shadertoy.com/view/lssGDj
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
if (gray > 0.2) n = 65600.0; // :
if (gray > 0.3) n = 18725316.0; // v
if (gray > 0.4) n = 15255086.0; // o
if (gray > 0.4) n = 15255086.0; // o
if (gray > 0.5) n = 13121101.0; // &
if (gray > 0.6) n = 15252014.0; // 8
if (gray > 0.7) n = 13195790.0; // @

View File

@ -12,5 +12,5 @@ void main()
fragTexCoord = vertexTexCoord;
// Calculate final vertex position
gl_Position = vec4(vertexPosition, 1.0);
gl_Position = vec4(vertexPosition, 1.0);
}

View File

@ -1,6 +1,6 @@
#version 120
#extension GL_EXT_frag_depth : enable
#extension GL_EXT_frag_depth : enable
varying vec2 fragTexCoord;
varying vec4 fragColor;
@ -11,7 +11,7 @@ uniform vec4 colDiffuse;
void main()
{
vec4 texelColor = texture2D(texture0, fragTexCoord);
gl_FragColor = texelColor*colDiffuse*fragColor;
gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
}

View File

@ -22,13 +22,13 @@ void main()
{
// Store the fragment position vector in the first gbuffer texture
//gPosition = fragPosition;
// Store the per-fragment normals into the gbuffer
//gNormal = normalize(fragNormal);
// Store the diffuse per-fragment color
gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
// Store specular intensity in gAlbedoSpec's alpha component
gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
}

View File

@ -48,7 +48,7 @@ void main()
{
// Calculate vertex attributes for fragment shader
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
fragPosition = worldPos.xyz;
fragPosition = worldPos.xyz;
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;

View File

@ -1,6 +1,6 @@
#version 120
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
varying vec2 fragTexCoord;
varying vec4 fragColor;

View File

@ -30,12 +30,12 @@ float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
{
p.x = abs(p.x);
float l = length(p.xy);
p.xy = mat2(-c.x, c.y,
p.xy = mat2(-c.x, c.y,
c.y, c.x)*p.xy;
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
(p.x>0.0)?p.y:l);
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
vec2 d = abs(q) - w;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
@ -54,9 +54,9 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
}
vec2 q = vec2(length(ap.yz), ap.x);
float w = sqrt(r*r-h*h);
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : abs(length(q)-r)) - t;
}
@ -108,8 +108,8 @@ vec2 raycast(in vec3 ro, in vec3 rd)
if (t>tmax) break;
vec2 h = map(ro+rd*t);
if (abs(h.x) < (0.0001*t))
{
res = vec2(t,h.y);
{
res = vec2(t,h.y);
break;
}
t += h.x;
@ -144,9 +144,9 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
vec3 calcNormal(in vec3 pos)
{
vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map(pos + e.yyx).x +
e.yxy*map(pos + e.yxy).x +
return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map(pos + e.yyx).x +
e.yxy*map(pos + e.yxy).x +
e.xxx*map(pos + e.xxx).x);
}
@ -174,15 +174,15 @@ float checkersGradBox(in vec2 p)
// analytical integral (box filter)
vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
// xor pattern
return 0.5 - 0.5*i.x*i.y;
return 0.5 - 0.5*i.x*i.y;
}
// https://www.shadertoy.com/view/tdS3DG
vec4 render(in vec3 ro, in vec3 rd)
{
{
// background
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
// raycast scene
vec2 res = raycast(ro,rd);
float t = res.x;
@ -192,11 +192,11 @@ vec4 render(in vec3 ro, in vec3 rd)
vec3 pos = ro + t*rd;
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
vec3 ref = reflect(rd, nor);
// material
// material
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
float ks = 1.0;
if (m<1.5)
{
float f = checkersGradBox(3.0*pos.xz);
@ -206,7 +206,7 @@ vec4 render(in vec3 ro, in vec3 rd)
// lighting
float occ = calcAO(pos, nor);
vec3 lin = vec3(0.0);
// sun
@ -247,7 +247,7 @@ vec4 render(in vec3 ro, in vec3 rd)
dif *= occ;
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
}
col = lin;
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));

View File

@ -50,7 +50,7 @@ void main()
float specCo = 0.0;
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
specular += specCo;

View File

@ -81,11 +81,11 @@ vec3 ComputePBR()
{
vec3 albedo = texture2D(albedoMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
float metallic = clamp(metallicValue, 0.0, 1.0);
float roughness = clamp(roughnessValue, 0.0, 1.0);
float ao = clamp(aoValue, 0.0, 1.0);
if (useTexMRA == 1)
{
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
@ -130,18 +130,18 @@ vec3 ComputePBR()
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
// Difuse and spec light can't be above 1.0
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
vec3 kD = vec3(1.0) - F;
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
kD *= 1.0 - metallic;
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result
}
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
return (ambientFinal + lightAccum*ao + emissive);
}
@ -151,7 +151,7 @@ void main()
// HDR tonemapping
color = pow(color, color + vec3(1.0));
// Gamma correction
color = pow(color, vec3(1.0/2.2));

View File

@ -58,7 +58,7 @@ void main()
float bias = max(0.0008*(1.0 - dot(normal, l)), 0.00008);
int shadowCounter = 0;
const int numSamples = 9;
// PCF (percentage-closer filtering) algorithm:
// Instead of testing if just one point is closer to the current point,
// we test the surrounding points as well
@ -72,7 +72,7 @@ void main()
if (curDepth - bias > sampleDepth) shadowCounter++;
}
}
finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
// Add ambient lighting whether in shadow or not

View File

@ -52,12 +52,12 @@ void main()
float gray = GreyScale(cellColor);
int n = 4096;
// Character set from https://www.shadertoy.com/view/lssGDj
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
if (gray > 0.2) n = 65600; // :
if (gray > 0.3) n = 18725316; // v
if (gray > 0.4) n = 15255086; // o
if (gray > 0.4) n = 15255086; // o
if (gray > 0.5) n = 13121101; // &
if (gray > 0.6) n = 15252014; // 8
if (gray > 0.7) n = 13195790; // @

View File

@ -20,7 +20,7 @@ void main()
// NOTE: Implement here your fragment shader code
// final color is the color from the texture
// final color is the color from the texture
// times the tint color (colDiffuse)
// times the fragment color (interpolated vertex color)
finalColor = texelColor*colDiffuse*fragColor;

View File

@ -14,7 +14,7 @@ out vec4 finalColor;
void main()
{
vec4 texelColor = texture(texture0, fragTexCoord);
finalColor = texelColor*colDiffuse*fragColor;
gl_FragDepth = 1.0 - finalColor.z;
}

View File

@ -14,7 +14,7 @@ uniform mat4 matProjection;
void main()
{
vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
fragPosition = worldPos.xyz;
fragPosition = worldPos.xyz;
fragTexCoord = vertexTexCoord;
mat3 normalMatrix = transpose(inverse(mat3(matModel)));

View File

@ -16,7 +16,7 @@ out vec4 finalColor;
void main()
{
vec4 texelColor = texture(texture0, fragTexCoord);
finalColor = texelColor*colDiffuse*fragColor;
gl_FragDepth = finalColor.z;
}

View File

@ -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 = vec2(((p.y > 0.0) || (p.x > 0.0))? p.x : l*sign(-c.x), (p.x>0.0)? p.y : l);
p.xy = vec2(p.x, abs(p.y - r)) - vec2(le, 0.0);
vec2 q = vec2(length(max(p.xy, 0.0)) + min(0.0, max(p.x, p.y)), p.z);
vec2 d = abs(q) - w;
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
@ -54,7 +54,7 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
vec2 q = vec2(length(ap.yz), ap.x);
float w = sqrt(r*r-h*h);
return ((h*q.x < w*q.y)? length(q - vec2(w, h)) : abs(length(q) - r)) - t;
}
@ -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);
res = opU(res, vec2(sdSixWayCutHollowSphere(pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5));
return res;
}
@ -105,8 +105,8 @@ vec2 raycast(in vec3 ro, in vec3 rd)
if (t > tmax) break;
vec2 h = map(ro + rd*t);
if (abs(h.x )< (0.0001*t))
{
res = vec2(t, h.y);
{
res = vec2(t, h.y);
break;
}
t += h.x;
@ -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);
if ((res < 0.004) || (t > tmax)) break;
}
res = clamp(res, 0.0, 1.0);
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)
{
vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map(pos + e.yyx).x +
e.yxy*map(pos + e.yxy).x +
return normalize(e.xyy*map(pos + e.xyy).x +
e.yyx*map(pos + e.yyx).x +
e.yxy*map(pos + e.yxy).x +
e.xxx*map(pos + e.xxx).x);
}
@ -160,7 +160,7 @@ float calcAO(in vec3 pos, in vec3 nor)
sca *= 0.95;
if (occ>0.35) break;
}
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)
vec2 i = 2.0*(abs(fract((p - 0.5*w)*0.5)-0.5) - abs(fract((p + 0.5*w)*0.5) - 0.5))/w;
// xor pattern
return (0.5 - 0.5*i.x*i.y);
return (0.5 - 0.5*i.x*i.y);
}
// https://www.shadertoy.com/view/tdS3DG
vec4 render(in vec3 ro, in vec3 rd)
{
{
// background
vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
// raycast scene
vec2 res = raycast(ro,rd);
float t = res.x;
@ -190,11 +190,11 @@ vec4 render(in vec3 ro, in vec3 rd)
vec3 pos = ro + t*rd;
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
vec3 ref = reflect(rd, nor);
// material
// material
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
float ks = 1.0;
if (m < 1.5)
{
float f = checkersGradBox(3.0*pos.xz);
@ -204,7 +204,7 @@ vec4 render(in vec3 ro, in vec3 rd)
// lighting
float occ = calcAO(pos, nor);
vec3 lin = vec3(0.0);
// sun
@ -245,7 +245,7 @@ vec4 render(in vec3 ro, in vec3 rd)
dif *= occ;
lin += col*0.25*dif*vec3(1.00,1.00,1.00);
}
col = lin;
col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
@ -285,7 +285,7 @@ void main()
color = res.xyz;
depth = CalcDepth(rd,res.w);
}
finalColor = vec4(color , 1.0);
gl_FragDepth = depth;
}

View File

@ -54,7 +54,7 @@ void main()
float specCo = 0.0;
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent); // 16 refers to shine
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewDir, reflect(-lightDir, normal))), specularExponent);
specular += specCo;

View File

@ -24,7 +24,7 @@ void main()
// to the palette index by scaling up from [0..1] to [0..255]
int index = int(texelColor.r*255.0);
ivec3 color = palette[index];
//finalColor = texture(palette, texelColor.xy); // Alternative to ivec3
// Calculate final fragment color. Note that the palette color components

View File

@ -84,11 +84,11 @@ vec3 ComputePBR()
{
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);
float metallic = clamp(metallicValue, 0.0, 1.0);
float roughness = clamp(roughnessValue, 0.0, 1.0);
float ao = clamp(aoValue, 0.0, 1.0);
if (useTexMRA == 1)
{
vec4 mra = 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 spec = (D*G*F)/(4.0*nDotV*nDotL);
// Difuse and spec light can't be above 1.0
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
vec3 kD = vec3(1.0) - F;
// Mult kD by the inverse of metallnes, only non-metals should have diffuse light
kD *= 1.0 - metallic;
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*lights[i].enabled; // Angle of light has impact on result
}
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
return (ambientFinal + lightAccum*ao + emissive);
}
@ -154,7 +154,7 @@ void main()
// HDR tonemapping
color = pow(color, color + vec3(1.0));
// Gamma correction
color = pow(color, vec3(1.0/2.2));

View File

@ -11,7 +11,7 @@ uniform mat4 mvp;
uniform mat4 matModel;
uniform mat4 matNormal;
uniform float time;
uniform float time;
uniform sampler2D perlinNoiseMap;

View File

@ -52,7 +52,7 @@ int main(void)
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
camera.fovy = 45.0f;
camera.projection = CAMERA_PERSPECTIVE;
// Load model
Model model = LoadModel("resources/models/old_car_new.glb");
@ -61,7 +61,7 @@ int main(void)
TextFormat("resources/shaders/glsl%i/cel.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/cel.fs", GLSL_VERSION));
celShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(celShader, "viewPos");
// Apply cel shader to model, keep copy of default shader
Shader defaultShader = model.materials[0].shader;
model.materials[0].shader = celShader;
@ -134,16 +134,16 @@ int main(void)
// Outline pass: cull front faces, draw extruded back faces as silhouette
float thickness = 0.005f;
SetShaderValue(outlineShader, outlineThicknessLoc, &thickness, SHADER_UNIFORM_FLOAT);
rlSetCullFace(RL_CULL_FACE_FRONT);
model.materials[0].shader = outlineShader;
DrawModel(model, Vector3Zero(), 0.75f, WHITE);
if (celEnabled) model.materials[0].shader = celShader; // Apply cel shader to model
else model.materials[0].shader = defaultShader; // Apply default shader to model
rlSetCullFace(RL_CULL_FACE_BACK);
}
@ -167,7 +167,7 @@ int main(void)
UnloadModel(model);
UnloadShader(celShader);
UnloadShader(outlineShader);
CloseWindow();
//--------------------------------------------------------------------------------------

View File

@ -210,7 +210,7 @@ int main(void)
rlClearColor(0, 0, 0, 0);
rlClearScreenBuffers(); // Clear color and depth buffer
rlDisableColorBlend();
BeginMode3D(camera);
// NOTE: We have to use rlEnableShader here. `BeginShaderMode` or thus `rlSetShader`
// will not work, as they won't immediately load the shader program
@ -226,7 +226,7 @@ int main(void)
}
rlDisableShader();
EndMode3D();
rlEnableColorBlend();
// Go back to the default framebufferId (0) and draw our deferred shading

View File

@ -59,7 +59,7 @@ int main(void)
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - game of life");
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 } },
{ "Random", { 0.5f, 0.5f } }
};
const int numberOfPresets = sizeof(presetPatterns)/sizeof(presetPatterns[0]);
int zoom = 1;
@ -90,7 +90,7 @@ int main(void)
int framesPerStep = 1;
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
bool buttonZoomIn = false; // Button states: false not pressed
bool buttonZomOut = false;
@ -185,7 +185,7 @@ int main(void)
EndTextureMode();
imageToDraw = (Image*)RL_MALLOC(sizeof(Image));
*imageToDraw = LoadImageFromTexture(worldOnScreen.texture);
UnloadRenderTexture(worldOnScreen);
}
@ -199,9 +199,9 @@ int main(void)
if (mouseY >= sizeInWorldY) mouseY = sizeInWorldY - 1;
if (firstColor == -1) firstColor = (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);
if (prevColor != firstColor) UpdateTextureRec(currentWorld->texture, (Rectangle){ floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), (float)(sizeInWorldY) }, imageToDraw->data);
}
else firstColor = -1;
@ -228,7 +228,7 @@ int main(void)
BeginTextureMode(*currentWorld);
ClearBackground(RAYWHITE);
EndTextureMode();
UpdateTextureRec(currentWorld->texture, (Rectangle){ worldWidth*presetPatterns[preset].position.x - pattern.width/2.0f,
worldHeight*presetPatterns[preset].position.y - pattern.height/2.0f,
(float)(pattern.width), (float)(pattern.height) }, pattern.data);
@ -256,7 +256,7 @@ int main(void)
}
UnloadImage(pattern);
mode = MODE_PAUSE;
offsetX = worldWidth*presetPatterns[preset].position.x - (float)windowWidth/zoom/2.0f;
offsetY = worldHeight*presetPatterns[preset].position.y - (float)windowHeight/zoom/2.0f;
@ -293,7 +293,7 @@ int main(void)
// Draw to screen
//----------------------------------------------------------------------------------
BeginDrawing();
DrawTexturePro(currentWorld->texture, textureSourceToScreen, textureOnScreen, (Vector2){ 0, 0 }, 0.0f, WHITE);
DrawLine(windowWidth, 0, windowWidth, screenHeight, (Color){ 218, 218, 218, 255 });

View File

@ -69,7 +69,7 @@ int main(void)
DrawText("USING DEFAULT SHADER", 20, 40, 10, RED);
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);

View File

@ -56,6 +56,7 @@ int main(void)
// Set the texture tiling using a shader
float tiling[2] = { 3.0f, 3.0f };
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);
model.materials[0].shader = shader;

View File

@ -17,17 +17,21 @@
#include "raylib.h"
#include <stdlib.h>
#include <math.h>
#include <stdlib.h> // Required for: malloc(), free()
#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 {
Vector2 pos; // Position
Vector2 vel; // Velocity
Vector2 ppos; // Previous position
Vector2 position;
Vector2 speed;
Vector2 prevPosition;
float radius;
float friction;
float friction;
float elasticity;
Color color;
bool grabbed;
@ -45,24 +49,27 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
Ball balls[MAX_BALLS] = {{
.pos = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
.vel = { 200, 200 },
.ppos = { 0 },
Ball *balls = (Ball*)RL_MALLOC(sizeof(Ball)*MAX_BALLS);
// Init first ball in the array
balls[0] = (Ball){
.position = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f },
.speed = { 200, 200 },
.prevPosition = { 0 },
.radius = 40,
.friction = 0.99f,
.elasticity = 0.9f,
.color = BLUE,
.grabbed = false
}};
};
int ballCount = 1;
Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed
Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd
Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed
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
@ -79,8 +86,8 @@ int main(void)
for (int i = ballCount - 1; i >= 0; i--)
{
Ball *ball = &balls[i];
pressOffset.x = mousePos.x - ball->pos.x;
pressOffset.y = mousePos.y - ball->pos.y;
pressOffset.x = mousePos.x - ball->position.x;
pressOffset.y = mousePos.y - ball->position.y;
// 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
@ -109,9 +116,9 @@ int main(void)
if (ballCount < MAX_BALLS)
{
balls[ballCount++] = (Ball){
.pos = mousePos,
.vel = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) },
.ppos = { 0 },
.position = mousePos,
.speed = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) },
.prevPosition = { 0 },
.radius = 20.0f + (float)GetRandomValue(0, 30),
.friction = 0.99f,
.elasticity = 0.9f,
@ -126,7 +133,7 @@ int main(void)
{
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)
{
// Ball repositioning using the velocity
ball->pos.x += ball->vel.x * delta;
ball->pos.y += ball->vel.y * delta;
ball->position.x += ball->speed.x * delta;
ball->position.y += ball->speed.y * delta;
// 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->vel.x = -ball->vel.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit
}
ball->position.x = screenWidth - ball->radius; // Ball repositioning
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?
else if ((ball->pos.x - ball->radius) <= 0)
{
ball->pos.x = ball->radius;
ball->vel.x = -ball->vel.x*ball->elasticity;
else if ((ball->position.x - ball->radius) <= 0)
{
ball->position.x = ball->radius;
ball->speed.x = -ball->speed.x*ball->elasticity;
}
// 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->vel.y = -ball->vel.y*ball->elasticity;
}
else if ((ball->pos.y - ball->radius) <= 0)
{
ball->pos.y = ball->radius;
ball->vel.y = -ball->vel.y*ball->elasticity;
ball->position.y = screenHeight - ball->radius;
ball->speed.y = -ball->speed.y*ball->elasticity;
}
else if ((ball->position.y - ball->radius) <= 0)
{
ball->position.y = ball->radius;
ball->speed.y = -ball->speed.y*ball->elasticity;
}
// 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
ball->vel.y = ball->vel.y*ball->friction + gravity;
ball->speed.y = ball->speed.y*ball->friction + gravity;
}
else
{
// Ball repositioning using the mouse position
ball->pos.x = mousePos.x - pressOffset.x;
ball->pos.y = mousePos.y - pressOffset.y;
ball->position.x = mousePos.x - pressOffset.x;
ball->position.y = mousePos.y - pressOffset.y;
// While the ball is grabbed, recalculates its velocity
ball->vel.x = (ball->pos.x - ball->ppos.x)/delta;
ball->vel.y = (ball->pos.y - ball->ppos.y)/delta;
ball->ppos = ball->pos;
ball->speed.x = (ball->position.x - ball->prevPosition.x)/delta;
ball->speed.y = (ball->position.y - ball->prevPosition.y)/delta;
ball->prevPosition = ball->position;
}
}
//----------------------------------------------------------------------------------
@ -197,8 +204,8 @@ int main(void)
for (int i = 0; i < ballCount; i++)
{
DrawCircleV(balls[i].pos, balls[i].radius, balls[i].color);
DrawCircleLinesV(balls[i].pos, balls[i].radius, BLACK);
DrawCircleV(balls[i].position, balls[i].radius, balls[i].color);
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);
@ -214,6 +221,7 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
RL_FREE(balls);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -50,7 +50,7 @@ int main(void)
// Circle shapes and lines
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);
DrawEllipse(screenWidth/5, 120, 25, 20, 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

View File

@ -72,7 +72,7 @@ typedef struct EasingFuncs {
// Module Functions Declaration
//------------------------------------------------------------------------------------
// 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

View File

@ -46,13 +46,13 @@ int main(void)
float size = (float)GetScreenHeight();
int strokeCount = 0;
Vector2 *hilbertPath = LoadHilbertPath(order, size, &strokeCount);
int prevOrder = order;
int prevSize = (int)size; // NOTE: Size from slider is float but for comparison we use int
int counter = 0;
float thick = 2.0f;
bool animate = true;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -68,19 +68,19 @@ int main(void)
{
UnloadHilbertPath(hilbertPath);
hilbertPath = LoadHilbertPath(order, size, &strokeCount);
if (animate) counter = 0;
else counter = strokeCount;
prevOrder = order;
prevSize = (int)size;
}
//----------------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
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));
}
counter += 1;
}
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));
}
}
// Draw UI using raygui
GuiCheckBox((Rectangle){ 450, 50, 20, 20 }, "ANIMATE GENERATION ON CHANGE", &animate);
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, 190, 240, 24 }, "TOTAL SIZE: ", NULL, &size, 10.0f, GetScreenHeight()*1.5f);
EndDrawing();
//--------------------------------------------------------------------------
}
@ -116,7 +116,7 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadHilbertPath(hilbertPath);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
@ -133,14 +133,14 @@ static Vector2 *LoadHilbertPath(int order, float size, int *strokeCount)
*strokeCount = N*N;
Vector2 *hilbertPath = (Vector2 *)RL_CALLOC(*strokeCount, sizeof(Vector2));
for (int i = 0; i < *strokeCount; i++)
{
hilbertPath[i] = ComputeHilbertStep(order, i);
hilbertPath[i].x = hilbertPath[i].x*len + len/2.0f;
hilbertPath[i].y = hilbertPath[i].y*len + len/2.0f;
}
return hilbertPath;
}
@ -160,7 +160,7 @@ static Vector2 ComputeHilbertStep(int order, int index)
[2] = { .x = 1, .y = 1 },
[3] = { .x = 1, .y = 0 },
};
int hilbertIndex = index&3;
Vector2 vect = hilbertPoints[hilbertIndex];
float temp = 0.0f;
@ -171,7 +171,7 @@ static Vector2 ComputeHilbertStep(int order, int index)
index = index >> 2;
hilbertIndex = index&3;
len = 1 << j;
switch (hilbertIndex)
{
case 0:
@ -191,6 +191,6 @@ static Vector2 ComputeHilbertStep(int order, int index)
default: break;
}
}
return vect;
}

View File

@ -106,7 +106,7 @@ int main(void)
if (generations > 0) rebuild = true;
}
}
if (rebuild)
{
RL_FREE(ls.production); // Free previous production for re-creation
@ -118,15 +118,15 @@ int main(void)
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground( RAYWHITE );
if (generations > 0) DrawPenroseLSystem(&ls);
DrawText("penrose l-system", 10, 10, 20, DARKGRAY);
DrawText("press up or down to change generations", 10, 30, 20, DARKGRAY);
DrawText(TextFormat("generations: %d", generations), 10, 50, 20, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
@ -171,11 +171,11 @@ static PenroseLSystem CreatePenroseLSystem(float drawLength)
.drawLength = drawLength,
.theta = 36.0f // Degrees
};
ls.production = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
ls.production[0] = '\0';
strncpy(ls.production, "[X]++[X]++[X]++[X]++[X]", STR_MAX_SIZE);
return ls;
}
@ -211,7 +211,7 @@ static void BuildProductionStep(PenroseLSystem *ls)
ls->drawLength *= 0.5f;
strncpy(ls->production, newProduction, STR_MAX_SIZE);
RL_FREE(newProduction);
}
@ -228,9 +228,9 @@ static void DrawPenroseLSystem(PenroseLSystem *ls)
int repeats = 1;
int productionLength = (int)strnlen(ls->production, STR_MAX_SIZE);
ls->steps += 12;
if (ls->steps > productionLength) ls->steps = productionLength;
for (int i = 0; i < ls->steps; i++)
{
char step = ls->production[i];
@ -244,24 +244,24 @@ static void DrawPenroseLSystem(PenroseLSystem *ls)
turtle.origin.y += ls->drawLength*sinf(radAngle);
Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y };
Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y };
DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2f));
}
repeats = 1;
}
}
else if (step == '+')
{
for (int j = 0; j < repeats; j++) turtle.angle += ls->theta;
repeats = 1;
}
}
else if (step == '-')
{
for (int j = 0; j < repeats; j++) turtle.angle += -ls->theta;
repeats = 1;
}
}
else if (step == '[') PushTurtleState(turtle);
else if (step == ']') turtle = PopTurtleState();
else if ((step >= 48) && (step <= 57)) repeats = (int) step - 48;

View File

@ -341,7 +341,7 @@ static void DrawLightMask(int slot)
rlSetBlendMode(BLEND_CUSTOM);
// 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();

View File

@ -61,7 +61,7 @@ int main(void)
SetTextLineSpacing(20); // Set line spacing for multiline text (when line breaks are included '\n')
// Free codepoints, atlas has already been generated
free(codepointsNoDups);
RL_FREE(codepointsNoDups);
bool showFontAtlas = false;
@ -139,7 +139,7 @@ int main(void)
static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointsResultCount)
{
int codepointsNoDupsCount = codepointCount;
int *codepointsNoDups = (int *)calloc(codepointCount, sizeof(int));
int *codepointsNoDups = (int *)RL_CALLOC(codepointCount, sizeof(int));
memcpy(codepointsNoDups, codepoints, codepointCount*sizeof(int));
// Remove duplicates

View File

@ -38,12 +38,12 @@ int main(void)
// Define characters to draw
// 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)
// 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
// NOTE: We define a font base size of 32 pixels tall and up-to 250 characters

View File

@ -33,7 +33,7 @@ typedef struct TextParticle {
Vector2 ppos; // Previous position
float padding;
float borderWidth;
float friction;
float friction;
float elasticity;
Color color;
bool grabbed;
@ -118,7 +118,7 @@ int main(void)
if (IsKeyDown(KEY_LEFT_SHIFT))
{
ShatterTextParticle(tp, i, textParticles, &particleCount);
}
}
else
{
SliceTextParticle(tp, i, TextLength(tp->text)/2, textParticles, &particleCount);
@ -158,33 +158,33 @@ int main(void)
TextParticle *tp = &textParticles[i];
// The text particle is not grabbed
if (!tp->grabbed)
if (!tp->grabbed)
{
// text particle repositioning using the velocity
tp->rect.x += tp->vel.x * delta;
tp->rect.y += tp->vel.y * delta;
// 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->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?
else if (tp->rect.x <= 0)
{
{
tp->rect.x = 0.0f;
tp->vel.x = -tp->vel.x*tp->elasticity;
}
// 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->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->vel.y = -tp->vel.y*tp->elasticity;
}
@ -264,9 +264,9 @@ int main(void)
void PrepareFirstTextParticle(const char* text, TextParticle *tps, int *particleCount)
{
tps[0] = CreateTextParticle(
text,
GetScreenWidth()/2.0f,
GetScreenHeight()/2.0f,
text,
GetScreenWidth()/2.0f,
GetScreenHeight()/2.0f,
RAYWHITE
);
*particleCount = 1;
@ -317,7 +317,7 @@ void SliceTextParticleByChar(TextParticle *tp, char charToSlice, TextParticle *t
{
int tokenCount = 0;
char **tokens = TextSplit(tp->text, charToSlice, &tokenCount);
if (tokenCount > 1)
{
int textLength = TextLength(tp->text);

View File

@ -47,7 +47,7 @@ int main(void)
// Load bunny texture
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
@ -126,7 +126,7 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
free(bunnies); // Unload bunnies data array
RL_FREE(bunnies); // Unload bunnies data array
UnloadTexture(texBunny); // Unload bunny texture

View File

@ -165,7 +165,7 @@ int main(void)
// If the mouse is on this preset, highlight it
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),
presetsSizeX + 4.0f, presetsSizeY + 4.0f }, 3, RED);
}

View File

@ -51,7 +51,7 @@ int main(void)
{
// Unload textures to avoid memory leaks
for (int i = 0; i < MAX_TEXTURE_COLLECTION; i++) UnloadTexture(collection[i].texture);
currentCollectionIndex = 0;
}
@ -59,7 +59,7 @@ int main(void)
(currentCollectionIndex < MAX_TEXTURE_COLLECTION))
{
Image image = GetClipboardImage();
if (IsImageValid(image))
{
collection[currentCollectionIndex].texture = LoadTextureFromImage(image);
@ -76,15 +76,15 @@ int main(void)
BeginDrawing();
ClearBackground(RAYWHITE);
for (int i = 0; i < currentCollectionIndex; i++)
{
if (IsTextureValid(collection[i].texture))
{
DrawTexturePro(collection[i].texture,
(Rectangle){0,0,collection[i].texture.width, collection[i].texture.height},
DrawTexturePro(collection[i].texture,
(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},
(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);
}
}

View File

@ -51,8 +51,8 @@ int main(void)
// 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
// 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.tileFog = (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 *)RL_CALLOC(map.tilesX*map.tilesY, sizeof(unsigned char));
// Load map tiles (generating 2 random tile ids for testing)
// NOTE: Map tile ids should be probably loaded from an external map file
@ -149,8 +149,8 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
free(map.tileIds); // Free allocated map tile ids
free(map.tileFog); // Free allocated map tile fog state
RL_FREE(map.tileIds); // Free allocated map tile ids
RL_FREE(map.tileFog); // Free allocated map tile fog state
UnloadRenderTexture(fogOfWar); // Unload render texture

View File

@ -3,7 +3,7 @@
* raylib textures example - magnifying glass
*
* Example complexity rating: [★★★☆] 3/4
*
*
* 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)
@ -29,18 +29,18 @@ int main(void)
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - magnifying glass");
Texture2D bunny = LoadTexture("resources/raybunny.png");
Texture2D parrots = LoadTexture("resources/parrots.png");
// Use image draw to generate a mask texture instead of loading it from a file.
Image circle = GenImageColor(256, 256, BLANK);
ImageDrawCircle(&circle, 128, 128, 128, WHITE);
Texture2D mask = LoadTextureFromImage(circle); // Copy the mask image from RAM to VRAM
UnloadImage(circle); // Unload the image from RAM
RenderTexture2D magnifiedWorld = LoadRenderTexture(256, 256);
Camera2D camera = { 0 };
// Set magnifying glass zoom
camera.zoom = 2;
@ -71,7 +71,7 @@ int main(void)
DrawTexture(parrots, 144, 33, WHITE);
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);
ClearBackground(RAYWHITE);

View File

@ -17,8 +17,6 @@
#include "raylib.h"
#include <stdlib.h> // Required for: malloc() and free()
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@ -39,26 +37,31 @@ int main(void)
UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data
// Generate a checked texture by code
int width = 960;
int height = 480;
int imWidth = 960;
int imHeight = 480;
// 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;
else pixels[y*width + x] = GOLD;
if (((x/32+y/32)/1)%2 == 0) pixels[y*imWidth + x] = ORANGE;
else pixels[y*imWidth + x] = GOLD;
}
}
// 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 = {
.data = pixels, // We can assign pixels directly to data
.width = width,
.height = height,
.data = pixels,
.width = imWidth,
.height = imHeight,
.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8,
.mipmaps = 1
};

View File

@ -52,7 +52,7 @@ int main(void)
float hue = t*t;
float saturation = t;
float value = t;
palette[i] = ColorFromHSV(250.0f + 150.0f*hue, saturation, value);
}
@ -92,14 +92,14 @@ int main(void)
{
unsigned int i = x + y*imageWidth;
unsigned char colorIndex = indexBuffer[i];
if (colorIndex != 0)
{
// Move pixel a row above
indexBuffer[i] = 0;
int moveX = GetRandomValue(0, 2) - 1;
int newX = x + moveX;
if ((newX > 0) && (newX < imageWidth))
{
unsigned int iabove = i - imageWidth + moveX;
@ -130,7 +130,7 @@ int main(void)
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTextureEx(screenTexture, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);

View File

@ -34,7 +34,7 @@ int main()
DrawFPS(10, 10);
EndDrawing();
}
CloseWindow();
return 0;
}

View File

@ -19,7 +19,7 @@ int main()
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
@ -44,7 +44,7 @@ int main()
}
// De-Initialization
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

View File

@ -2960,24 +2960,6 @@
<Param name="Color tint" />
</Overload>
</KeyWord>
<KeyWord name="DrawModelPoints" func="yes">
<Overload retVal="void" descr="Draw a model as points">
<Param name="Model model" />
<Param name="Vector3 position" />
<Param name="float scale" />
<Param name="Color tint" />
</Overload>
</KeyWord>
<KeyWord name="DrawModelPointsEx" func="yes">
<Overload retVal="void" descr="Draw a model as points with extended parameters">
<Param name="Model model" />
<Param name="Vector3 position" />
<Param name="Vector3 rotationAxis" />
<Param name="float rotationAngle" />
<Param name="Vector3 scale" />
<Param name="Color tint" />
</Overload>
</KeyWord>
<KeyWord name="DrawBoundingBox" func="yes">
<Overload retVal="void" descr="Draw bounding box (wires)">
<Param name="BoundingBox box" />
@ -3013,7 +2995,7 @@
<Param name="Vector2 size" />
<Param name="Vector2 origin" />
<Param name="float rotation" />
<Param name="<22><>_)% " />
<Param name="<22><>_)% " />
</Overload>
</KeyWord>

View File

@ -15,9 +15,9 @@
<Param name="float alpha" />
</Overload>
</KeyWord>
NOTE: Generated XML text should be copied inside raylib\Notepad++\plugins\APIs\c.xml
WARNING: Be careful with functions that split parameters into several lines, it breaks the process!
LICENSE: zlib/libpng
@ -42,13 +42,13 @@ int main(int argc, char *argv[])
{
FILE *rFile = fopen(argv[1], "rt");
FILE *rxmlFile = fopen("raylib_npp.xml", "wt");
if ((rFile == NULL) || (rxmlFile == NULL))
{
printf("File could not be opened.\n");
return 0;
}
char *buffer = (char *)calloc(MAX_BUFFER_SIZE, 1);
int count = 0;
@ -56,7 +56,7 @@ int main(int argc, char *argv[])
{
// Read one full line
fgets(buffer, MAX_BUFFER_SIZE, rFile);
if (buffer[0] == '/') fprintf(rxmlFile, " <!--%.*s -->\n", strlen(buffer) - 3, buffer + 2);
else if (buffer[0] == '\n') fprintf(rxmlFile, "%s", buffer); // Direct copy of code comments
else if (strncmp(buffer, "RLAPI", 5) == 0) // raylib function declaration
@ -65,33 +65,33 @@ int main(int argc, char *argv[])
char funcTypeAux[64];
char funcName[64];
char funcDesc[256];
char params[128];
char paramType[16][16];
char paramName[16][32];
int index = 0;
char *ptr = NULL;
sscanf(buffer, "RLAPI %s %[^(]s", funcType, funcName);
if (strcmp(funcType, "const") == 0)
{
{
sscanf(buffer, "RLAPI %s %s %[^(]s", funcType, funcTypeAux, funcName);
strcat(funcType, " ");
strcat(funcType, funcTypeAux);
}
ptr = strchr(buffer, '/');
index = (int)(ptr - buffer);
sscanf(buffer + index, "%[^\n]s", funcDesc); // Read function comment after declaration
ptr = strchr(buffer, '(');
if (ptr != NULL) index = (int)(ptr - buffer);
else printf("Character not found!\n");
sscanf(buffer + (index + 1), "%[^)]s", params); // Read what's inside '(' and ')'
// Scan params string for number of func params, type and name
@ -102,23 +102,23 @@ int main(int argc, char *argv[])
if ((funcName[0] == '*') && (funcName[1] == '*')) fprintf(rxmlFile, " <KeyWord name=\"%s\" func=\"yes\">\n", funcName + 2);
else if (funcName[0] == '*') fprintf(rxmlFile, " <KeyWord name=\"%s\" func=\"yes\">\n", funcName + 1);
else fprintf(rxmlFile, " <KeyWord name=\"%s\" func=\"yes\">\n", funcName);
fprintf(rxmlFile, " <Overload retVal=\"%s\" descr=\"%s\">", funcType, funcDesc + 3);
bool paramsVoid = false;
char paramConst[8][16];
while (paramPtr[paramsCount] != NULL)
{
sscanf(paramPtr[paramsCount], "%s %s\n", paramType[paramsCount], paramName[paramsCount]);
if (strcmp(paramType[paramsCount], "void") == 0)
{
paramsVoid = true;
break;
}
if ((strcmp(paramType[paramsCount], "const") == 0) || (strcmp(paramType[paramsCount], "unsigned") == 0))
{
sscanf(paramPtr[paramsCount], "%s %s %s\n", paramConst[paramsCount], paramType[paramsCount], paramName[paramsCount]);
@ -130,17 +130,17 @@ int main(int argc, char *argv[])
paramsCount++;
paramPtr[paramsCount] = strtok(NULL, ",");
}
fprintf(rxmlFile, "%s</Overload>\n", paramsVoid ? "" : "\n ");
fprintf(rxmlFile, " </KeyWord>\n");
count++;
printf("Function processed %02i: %s\n", count, funcName);
memset(buffer, 0, MAX_BUFFER_SIZE);
}
}
free(buffer);
fclose(rFile);
fclose(rxmlFile);

View File

@ -600,8 +600,6 @@ RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint);
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points
RLAPI void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source

211
src/external/cgltf.h vendored
View File

@ -1,7 +1,7 @@
/**
* cgltf - a single-file glTF 2.0 parser written in C99.
*
* Version: 1.14
* Version: 1.15
*
* Website: https://github.com/jkuhlmann/cgltf
*
@ -141,7 +141,7 @@ typedef struct cgltf_memory_options
typedef struct cgltf_file_options
{
cgltf_result(*read)(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, const char* path, cgltf_size* size, void** data);
void (*release)(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data);
void (*release)(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data, cgltf_size size);
void* user_data;
} cgltf_file_options;
@ -296,6 +296,7 @@ typedef enum cgltf_meshopt_compression_filter {
cgltf_meshopt_compression_filter_octahedral,
cgltf_meshopt_compression_filter_quaternion,
cgltf_meshopt_compression_filter_exponential,
cgltf_meshopt_compression_filter_color,
cgltf_meshopt_compression_filter_max_enum
} cgltf_meshopt_compression_filter;
@ -308,6 +309,7 @@ typedef struct cgltf_meshopt_compression
cgltf_size count;
cgltf_meshopt_compression_mode mode;
cgltf_meshopt_compression_filter filter;
cgltf_bool is_khr;
} cgltf_meshopt_compression;
typedef struct cgltf_buffer_view
@ -376,13 +378,29 @@ typedef struct cgltf_image
cgltf_extension* extensions;
} cgltf_image;
typedef enum cgltf_filter_type {
cgltf_filter_type_undefined = 0,
cgltf_filter_type_nearest = 9728,
cgltf_filter_type_linear = 9729,
cgltf_filter_type_nearest_mipmap_nearest = 9984,
cgltf_filter_type_linear_mipmap_nearest = 9985,
cgltf_filter_type_nearest_mipmap_linear = 9986,
cgltf_filter_type_linear_mipmap_linear = 9987
} cgltf_filter_type;
typedef enum cgltf_wrap_mode {
cgltf_wrap_mode_clamp_to_edge = 33071,
cgltf_wrap_mode_mirrored_repeat = 33648,
cgltf_wrap_mode_repeat = 10497
} cgltf_wrap_mode;
typedef struct cgltf_sampler
{
char* name;
cgltf_int mag_filter;
cgltf_int min_filter;
cgltf_int wrap_s;
cgltf_int wrap_t;
cgltf_filter_type mag_filter;
cgltf_filter_type min_filter;
cgltf_wrap_mode wrap_s;
cgltf_wrap_mode wrap_t;
cgltf_extras extras;
cgltf_size extensions_count;
cgltf_extension* extensions;
@ -500,6 +518,14 @@ typedef struct cgltf_iridescence
cgltf_texture_view iridescence_thickness_texture;
} cgltf_iridescence;
typedef struct cgltf_diffuse_transmission
{
cgltf_texture_view diffuse_transmission_texture;
cgltf_float diffuse_transmission_factor;
cgltf_float diffuse_transmission_color_factor[3];
cgltf_texture_view diffuse_transmission_color_texture;
} cgltf_diffuse_transmission;
typedef struct cgltf_anisotropy
{
cgltf_float anisotropy_strength;
@ -525,6 +551,7 @@ typedef struct cgltf_material
cgltf_bool has_sheen;
cgltf_bool has_emissive_strength;
cgltf_bool has_iridescence;
cgltf_bool has_diffuse_transmission;
cgltf_bool has_anisotropy;
cgltf_bool has_dispersion;
cgltf_pbr_metallic_roughness pbr_metallic_roughness;
@ -537,6 +564,7 @@ typedef struct cgltf_material
cgltf_volume volume;
cgltf_emissive_strength emissive_strength;
cgltf_iridescence iridescence;
cgltf_diffuse_transmission diffuse_transmission;
cgltf_anisotropy anisotropy;
cgltf_dispersion dispersion;
cgltf_texture_view normal_texture;
@ -743,6 +771,7 @@ typedef struct cgltf_data
{
cgltf_file_type file_type;
void* file_data;
cgltf_size file_size;
cgltf_asset asset;
@ -844,6 +873,8 @@ void cgltf_node_transform_world(const cgltf_node* node, cgltf_float* out_matrix)
const uint8_t* cgltf_buffer_view_data(const cgltf_buffer_view* view);
const cgltf_accessor* cgltf_find_accessor(const cgltf_primitive* prim, cgltf_attribute_type type, cgltf_int index);
cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size);
cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor* accessor, cgltf_size index, cgltf_uint* out, cgltf_size element_size);
cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size index);
@ -1071,9 +1102,10 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m
return cgltf_result_success;
}
static void cgltf_default_file_release(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data)
static void cgltf_default_file_release(const struct cgltf_memory_options* memory_options, const struct cgltf_file_options* file_options, void* data, cgltf_size size)
{
(void)file_options;
(void)size;
void (*memfree)(void*, void*) = memory_options->free_func ? memory_options->free_func : &cgltf_default_free;
memfree(memory_options->user_data, data);
}
@ -1220,7 +1252,7 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg
}
cgltf_result (*file_read)(const struct cgltf_memory_options*, const struct cgltf_file_options*, const char*, cgltf_size*, void**) = options->file.read ? options->file.read : &cgltf_default_file_read;
void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data) = options->file.release ? options->file.release : cgltf_default_file_release;
void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data, cgltf_size size) = options->file.release ? options->file.release : cgltf_default_file_release;
void* file_data = NULL;
cgltf_size file_size = 0;
@ -1234,11 +1266,12 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg
if (result != cgltf_result_success)
{
file_release(&options->memory, &options->file, file_data);
file_release(&options->memory, &options->file, file_data, file_size);
return result;
}
(*out_data)->file_data = file_data;
(*out_data)->file_size = file_size;
return cgltf_result_success;
}
@ -1630,8 +1663,8 @@ cgltf_result cgltf_validate(cgltf_data* data)
CGLTF_ASSERT_IF((mc->mode == cgltf_meshopt_compression_mode_triangles || mc->mode == cgltf_meshopt_compression_mode_indices) && mc->filter != cgltf_meshopt_compression_filter_none, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_octahedral && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_quaternion && mc->stride != 8, cgltf_result_invalid_gltf);
CGLTF_ASSERT_IF(mc->filter == cgltf_meshopt_compression_filter_color && mc->stride != 4 && mc->stride != 8, cgltf_result_invalid_gltf);
}
}
@ -1822,7 +1855,7 @@ void cgltf_free(cgltf_data* data)
return;
}
void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data) = data->file.release ? data->file.release : cgltf_default_file_release;
void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data, cgltf_size size) = data->file.release ? data->file.release : cgltf_default_file_release;
data->memory.free_func(data->memory.user_data, data->asset.copyright);
data->memory.free_func(data->memory.user_data, data->asset.generator);
@ -1857,7 +1890,7 @@ void cgltf_free(cgltf_data* data)
if (data->buffers[i].data_free_method == cgltf_data_free_method_file_release)
{
file_release(&data->memory, &data->file, data->buffers[i].data);
file_release(&data->memory, &data->file, data->buffers[i].data, data->buffers[i].size);
}
else if (data->buffers[i].data_free_method == cgltf_data_free_method_memory_free)
{
@ -2096,7 +2129,7 @@ void cgltf_free(cgltf_data* data)
data->memory.free_func(data->memory.user_data, data->extensions_required);
file_release(&data->memory, &data->file, data->file_data);
file_release(&data->memory, &data->file, data->file_data, data->file_size);
data->memory.free_func(data->memory.user_data, data);
}
@ -2312,11 +2345,58 @@ const uint8_t* cgltf_buffer_view_data(const cgltf_buffer_view* view)
return result;
}
const cgltf_accessor* cgltf_find_accessor(const cgltf_primitive* prim, cgltf_attribute_type type, cgltf_int index)
{
for (cgltf_size i = 0; i < prim->attributes_count; ++i)
{
const cgltf_attribute* attr = &prim->attributes[i];
if (attr->type == type && attr->index == index)
return attr->data;
}
return NULL;
}
static const uint8_t* cgltf_find_sparse_index(const cgltf_accessor* accessor, cgltf_size needle)
{
const cgltf_accessor_sparse* sparse = &accessor->sparse;
const uint8_t* index_data = cgltf_buffer_view_data(sparse->indices_buffer_view);
const uint8_t* value_data = cgltf_buffer_view_data(sparse->values_buffer_view);
if (index_data == NULL || value_data == NULL)
return NULL;
index_data += sparse->indices_byte_offset;
value_data += sparse->values_byte_offset;
cgltf_size index_stride = cgltf_component_size(sparse->indices_component_type);
cgltf_size offset = 0;
cgltf_size length = sparse->count;
while (length)
{
cgltf_size rem = length % 2;
length /= 2;
cgltf_size index = cgltf_component_read_index(index_data + (offset + length) * index_stride, sparse->indices_component_type);
offset += index < needle ? length + rem : 0;
}
if (offset == sparse->count)
return NULL;
cgltf_size index = cgltf_component_read_index(index_data + offset * index_stride, sparse->indices_component_type);
return index == needle ? value_data + offset * accessor->stride : NULL;
}
cgltf_bool cgltf_accessor_read_float(const cgltf_accessor* accessor, cgltf_size index, cgltf_float* out, cgltf_size element_size)
{
if (accessor->is_sparse)
{
return 0;
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
if (element)
return cgltf_element_read_float(element, accessor->type, accessor->component_type, accessor->normalized, out, element_size);
}
if (accessor->buffer_view == NULL)
{
@ -2460,11 +2540,13 @@ cgltf_bool cgltf_accessor_read_uint(const cgltf_accessor* accessor, cgltf_size i
{
if (accessor->is_sparse)
{
return 0;
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
if (element)
return cgltf_element_read_uint(element, accessor->type, accessor->component_type, out, element_size);
}
if (accessor->buffer_view == NULL)
{
memset(out, 0, element_size * sizeof( cgltf_uint ));
memset(out, 0, element_size * sizeof(cgltf_uint));
return 1;
}
const uint8_t* element = cgltf_buffer_view_data(accessor->buffer_view);
@ -2480,7 +2562,9 @@ cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size
{
if (accessor->is_sparse)
{
return 0; // This is an error case, but we can't communicate the error with existing interface.
const uint8_t* element = cgltf_find_sparse_index(accessor, index);
if (element)
return cgltf_component_read_index(element, accessor->component_type);
}
if (accessor->buffer_view == NULL)
{
@ -2598,7 +2682,10 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* o
return accessor->count;
}
index_count = accessor->count < index_count ? accessor->count : index_count;
cgltf_size numbers_per_element = cgltf_num_components(accessor->type);
cgltf_size available_numbers = accessor->count * numbers_per_element;
index_count = available_numbers < index_count ? available_numbers : index_count;
cgltf_size index_component_size = cgltf_component_size(accessor->component_type);
if (accessor->is_sparse)
@ -2620,15 +2707,23 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* o
}
element += accessor->offset;
if (index_component_size == out_component_size && accessor->stride == out_component_size)
if (index_component_size == out_component_size && accessor->stride == out_component_size * numbers_per_element)
{
memcpy(out, element, index_count * index_component_size);
return index_count;
}
// Data couldn't be copied with memcpy due to stride being larger than the component size.
// OR
// The component size of the output array is larger than the component size of the index data, so index data will be padded.
switch (out_component_size)
{
case 1:
for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
{
((uint8_t*)out)[index] = (uint8_t)cgltf_component_read_index(element, accessor->component_type);
}
break;
case 2:
for (cgltf_size index = 0; index < index_count; index++, element += accessor->stride)
{
@ -2642,7 +2737,7 @@ cgltf_size cgltf_accessor_unpack_indices(const cgltf_accessor* accessor, void* o
}
break;
default:
break;
return 0;
}
return index_count;
@ -4278,6 +4373,52 @@ static int cgltf_parse_json_iridescence(cgltf_options* options, jsmntok_t const*
return i;
}
static int cgltf_parse_json_diffuse_transmission(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_diffuse_transmission* out_diff_transmission)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
int size = tokens[i].size;
++i;
// Defaults
cgltf_fill_float_array(out_diff_transmission->diffuse_transmission_color_factor, 3, 1.0f);
out_diff_transmission->diffuse_transmission_factor = 0.f;
for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_KEY(tokens[i]);
if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionFactor") == 0)
{
++i;
out_diff_transmission->diffuse_transmission_factor = cgltf_json_to_float(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_diff_transmission->diffuse_transmission_texture);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionColorFactor") == 0)
{
i = cgltf_parse_json_float_array(tokens, i + 1, json_chunk, out_diff_transmission->diffuse_transmission_color_factor, 3);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "diffuseTransmissionColorTexture") == 0)
{
i = cgltf_parse_json_texture_view(options, tokens, i + 1, json_chunk, &out_diff_transmission->diffuse_transmission_color_texture);
}
else
{
i = cgltf_skip_json(tokens, i + 1);
}
if (i < 0)
{
return i;
}
}
return i;
}
static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_anisotropy* out_anisotropy)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
@ -4406,8 +4547,8 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok
(void)options;
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);
out_sampler->wrap_s = 10497;
out_sampler->wrap_t = 10497;
out_sampler->wrap_s = cgltf_wrap_mode_repeat;
out_sampler->wrap_t = cgltf_wrap_mode_repeat;
int size = tokens[i].size;
++i;
@ -4424,28 +4565,28 @@ static int cgltf_parse_json_sampler(cgltf_options* options, jsmntok_t const* tok
{
++i;
out_sampler->mag_filter
= cgltf_json_to_int(tokens + i, json_chunk);
= (cgltf_filter_type)cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "minFilter") == 0)
{
++i;
out_sampler->min_filter
= cgltf_json_to_int(tokens + i, json_chunk);
= (cgltf_filter_type)cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapS") == 0)
{
++i;
out_sampler->wrap_s
= cgltf_json_to_int(tokens + i, json_chunk);
= (cgltf_wrap_mode)cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "wrapT") == 0)
{
++i;
out_sampler->wrap_t
= cgltf_json_to_int(tokens + i, json_chunk);
= (cgltf_wrap_mode)cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
@ -4766,6 +4907,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to
out_material->has_iridescence = 1;
i = cgltf_parse_json_iridescence(options, tokens, i + 1, json_chunk, &out_material->iridescence);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_diffuse_transmission") == 0)
{
out_material->has_diffuse_transmission = 1;
i = cgltf_parse_json_diffuse_transmission(options, tokens, i + 1, json_chunk, &out_material->diffuse_transmission);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_anisotropy") == 0)
{
out_material->has_anisotropy = 1;
@ -4974,6 +5120,10 @@ static int cgltf_parse_json_meshopt_compression(cgltf_options* options, jsmntok_
{
out_meshopt_compression->filter = cgltf_meshopt_compression_filter_exponential;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "COLOR") == 0)
{
out_meshopt_compression->filter = cgltf_meshopt_compression_filter_color;
}
++i;
}
else
@ -5084,6 +5234,12 @@ static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const*
out_buffer_view->has_meshopt_compression = 1;
i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->meshopt_compression);
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "KHR_meshopt_compression") == 0)
{
out_buffer_view->has_meshopt_compression = 1;
out_buffer_view->meshopt_compression.is_khr = 1;
i = cgltf_parse_json_meshopt_compression(options, tokens, i + 1, json_chunk, &out_buffer_view->meshopt_compression);
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_buffer_view->extensions[out_buffer_view->extensions_count++]));
@ -6629,6 +6785,9 @@ static int cgltf_fixup_pointers(cgltf_data* data)
CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].iridescence.iridescence_thickness_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].diffuse_transmission.diffuse_transmission_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].diffuse_transmission.diffuse_transmission_color_texture.texture, data->textures, data->textures_count);
CGLTF_PTRFIXUP(data->materials[i].anisotropy.anisotropy_texture.texture, data->textures, data->textures_count);
}

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