diff --git a/.github/workflows/codeql.yml b/.github/workflows/analyze_codeql.yml
similarity index 99%
rename from .github/workflows/codeql.yml
rename to .github/workflows/analyze_codeql.yml
index 5ad51a4d6..98d32a499 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/analyze_codeql.yml
@@ -3,7 +3,7 @@
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
-name: "CodeQL"
+name: Analyze raylib with CodeQL
on:
workflow_dispatch:
diff --git a/.github/workflows/android.yml b/.github/workflows/build_android.yml
similarity index 99%
rename from .github/workflows/android.yml
rename to .github/workflows/build_android.yml
index a3d2f9a5a..80520d0b2 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/build_android.yml
@@ -1,4 +1,4 @@
-name: Android
+name: Build raylib - Android
on:
workflow_dispatch:
diff --git a/.github/workflows/cmake.yml b/.github/workflows/build_cmake.yml
similarity index 99%
rename from .github/workflows/cmake.yml
rename to .github/workflows/build_cmake.yml
index 58ca7d5f4..0158fb510 100644
--- a/.github/workflows/cmake.yml
+++ b/.github/workflows/build_cmake.yml
@@ -1,4 +1,4 @@
-name: CMakeBuilds
+name: Build raylib CMake - Windows+Linux
on:
workflow_dispatch:
diff --git a/.github/workflows/linux_examples.yml b/.github/workflows/build_examples_linux.yml
similarity index 96%
rename from .github/workflows/linux_examples.yml
rename to .github/workflows/build_examples_linux.yml
index d7f3be2ea..5f029e73f 100644
--- a/.github/workflows/linux_examples.yml
+++ b/.github/workflows/build_examples_linux.yml
@@ -1,4 +1,4 @@
-name: Linux Examples
+name: Build raylib examples - Linux
on:
workflow_dispatch:
diff --git a/.github/workflows/windows_examples.yml b/.github/workflows/build_examples_windows.yml
similarity index 94%
rename from .github/workflows/windows_examples.yml
rename to .github/workflows/build_examples_windows.yml
index 6171d6dd9..6530931e6 100644
--- a/.github/workflows/windows_examples.yml
+++ b/.github/workflows/build_examples_windows.yml
@@ -1,4 +1,4 @@
-name: Windows Examples
+name: Build raylib examples - Windows
on:
workflow_dispatch:
diff --git a/.github/workflows/linux.yml b/.github/workflows/build_linux.yml
similarity index 99%
rename from .github/workflows/linux.yml
rename to .github/workflows/build_linux.yml
index d31acc854..a76345b90 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -1,4 +1,4 @@
-name: Linux
+name: Build raylib - Linux
on:
workflow_dispatch:
diff --git a/.github/workflows/macos.yml b/.github/workflows/build_macos.yml
similarity index 99%
rename from .github/workflows/macos.yml
rename to .github/workflows/build_macos.yml
index 8b9f59d2c..965efe249 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/build_macos.yml
@@ -1,4 +1,4 @@
-name: macOS
+name: Build raylib - macOS
on:
workflow_dispatch:
diff --git a/.github/workflows/webassembly.yml b/.github/workflows/build_webassembly.yml
similarity index 98%
rename from .github/workflows/webassembly.yml
rename to .github/workflows/build_webassembly.yml
index c3a392215..32ae94215 100644
--- a/.github/workflows/webassembly.yml
+++ b/.github/workflows/build_webassembly.yml
@@ -1,4 +1,4 @@
-name: WebAssembly
+name: Build raylib - WebAssembly
on:
workflow_dispatch:
diff --git a/.github/workflows/windows.yml b/.github/workflows/build_windows.yml
similarity index 99%
rename from .github/workflows/windows.yml
rename to .github/workflows/build_windows.yml
index 876338de1..9e87b5870 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/build_windows.yml
@@ -1,4 +1,4 @@
-name: Windows
+name: Build raylib - Windows
on:
workflow_dispatch:
diff --git a/.github/workflows/parse.yml b/.github/workflows/parse_api.yml
similarity index 83%
rename from .github/workflows/parse.yml
rename to .github/workflows/parse_api.yml
index 4491b142e..ec76532ba 100644
--- a/.github/workflows/parse.yml
+++ b/.github/workflows/parse_api.yml
@@ -1,37 +1,37 @@
-name: Parse raylib API
-
-on:
- workflow_dispatch:
- push:
- paths:
- - "src/raylib.h"
-
-jobs:
- build:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v4
-
- - name: Update parse files
- working-directory: tools/parser
- run: |
- make raylib_api
- mv raylib_api.* output
-
- - name: Diff parse files
- id: diff
- run: |
- git add -N parser
- git diff --name-only --exit-code
- continue-on-error: true
-
- - name: Commit parse files
- if: steps.diff.outcome == 'failure'
- run: |
- set -x
- git config user.email "github-actions[bot]@users.noreply.github.com"
- git config user.name "github-actions[bot]"
- git add parser
- git commit -m "Update raylib_api.* by CI"
- git push
+name: Parse raylib API
+
+on:
+ workflow_dispatch:
+ push:
+ paths:
+ - "src/raylib.h"
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Update parse files
+ working-directory: tools/parser
+ run: |
+ make raylib_api
+ mv raylib_api.* output
+
+ - name: Diff parse files
+ id: diff
+ run: |
+ git add -N parser
+ git diff --name-only --exit-code
+ continue-on-error: true
+
+ - name: Commit parse files
+ if: steps.diff.outcome == 'failure'
+ run: |
+ set -x
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add tools/parser
+ git commit -m "Update raylib_api.* by CI"
+ git push
diff --git a/.github/workflows/update_examples.yml b/.github/workflows/update_examples.yml
new file mode 100644
index 000000000..7feba7d89
--- /dev/null
+++ b/.github/workflows/update_examples.yml
@@ -0,0 +1,72 @@
+name: Update examples collection
+
+on:
+ workflow_dispatch:
+ push:
+ paths:
+ - 'examples/**'
+ pull_request:
+ paths:
+ - 'examples/**'
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup emsdk
+ uses: mymindstorm/setup-emsdk@v14
+ with:
+ version: 'latest'
+ actions-cache-folder: 'emsdk-cache'
+
+ - name: Clone raylib.com repo to update files
+ run: |
+ git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/raysan5/raylib.com.git
+ shell: bash
+
+ - name: Build and run rexm tool (requires GNU Makefile)
+ # "rexm update" validates and updates all required examples in raylib and even raylib.com repos,
+ # note that it calls examples/Makefile.Web internally, so it requires [make] tool available
+ run: |
+ sudo apt-get update && sudo apt-get install -y libopengl0 libglu1-mesa libx11-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libgl1-mesa-dev libglu1-mesa-dev
+ cd "${{ github.workspace }}/src"
+ make PLATFORM=PLATFORM_DESKTOP
+ sudo make install
+ make clean
+ make PLATFORM=PLATFORM_WEB
+ cd ../tools/rexm/
+ make
+ export REXM_EXAMPLES_BASE_PATH="${{ github.workspace }}/examples"
+ export REXM_EXAMPLES_WEB_PATH="${{ github.workspace }}/raylib.com/examples"
+ export REXM_EXAMPLES_TEMPLATE_FILE_PATH="${{ github.workspace }}/examples/examples_template.c"
+ export REXM_EXAMPLES_TEMPLATE_SCREENSHOT_PATH="${{ github.workspace }}/examples/examples_template.png"
+ export REXM_EXAMPLES_COLLECTION_FILE_PATH="${{ github.workspace }}/examples/examples_list.txt"
+ export REXM_EXAMPLES_VS2022_SLN_FILE="${{ github.workspace }}/projects/VS2022/raylib.sln"
+ export EMSDK_PATH="${{ github.workspace }}/emsdk-cache/emsdk-main"
+ ./rexm update
+ shell: bash
+
+ - name: Commit changes to raylib repo (DISABLED)
+ if: github.event_name == 'push' && false
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ git config --global user.name "github-actions[bot]"
+ git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add -A
+ git commit -m "Update examples collection" || echo "git exited with code 1, nothing changed"
+ git push
+ shell: bash
+
+ - name: Push changes to raylib.com repo (DISABLED)
+ if: github.event_name == 'push' && false
+ run: |
+ cd raylib.com
+ git add -A
+ git commit -m "Update web examples" || echo "git exited with code 1, nothing changed"
+ git push origin
+ shell: bash
diff --git a/.gitignore b/.gitignore
index 3a9197be3..ac4f016e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -113,5 +113,9 @@ docgen_tmp/
# Tools stuff
tools/parser/raylib_parser
-tools/rexm/VS2022
+tools/rexm/rexm.exe
tools/rexm/rexm
+
+# CI
+emsdk-cache/
+raylib.com/
diff --git a/BINDINGS.md b/BINDINGS.md
index e60638ac1..9d0fd5c5c 100644
--- a/BINDINGS.md
+++ b/BINDINGS.md
@@ -82,7 +82,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib |
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **5.0** | [Vala](https://vala.dev) | Zlib |
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
-| [raylib-zig](https://github.com/Not-Nik/raylib-zig) | **5.5** | [Zig](https://ziglang.org) | MIT |
+| [raylib-zig](https://github.com/raylib-zig/raylib-zig) | **5.6-dev** | [Zig](https://ziglang.org) | MIT |
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT |
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
diff --git a/CONVENTIONS.md b/CONVENTIONS.md
index 17c02e216..58cfa6270 100644
--- a/CONVENTIONS.md
+++ b/CONVENTIONS.md
@@ -11,7 +11,7 @@ Local variables | lowerCase | `Vector2 playerPosition = { 0 };`
Global variables | lowerCase | `bool windowReady = false;`
Constants | lowerCase | `const int maxValue = 8;`
Pointers | MyType *pointer | `Texture2D *array = NULL;`
-float values | always x.xf | `float gravity = 10.0f`
+float values | always x.xf | `float gravity = 10.0f` (avoid `10.f`)
Operators | value1*value2 | `int product = value*6;`
Operators | value1/value2 | `int division = value/4;`
Operators | value1 + value2 | `int sum = value + 10;`
@@ -72,19 +72,19 @@ void SomeFunction()
**If proposing new functions, please try to use a clear naming for function-name and functions-parameters, in case of doubt, open an issue for discussion.**
## Files and Directories Naming Conventions
-
+
- Directories will be named using `snake_case`: `resources/models`, `resources/fonts`
-
+
- Files will be named using `snake_case`: `main_title.png`, `cubicmap.png`, `sound.wav`
-
+
_NOTE: Avoid any space or special character in the files/dir naming!_
-
+
## Games/Examples Directories Organization Conventions
-
+
- Data files should be organized by context and usage in the game, think about the loading requirements for data and put all the resources that need to be loaded at the same time together.
- Use descriptive names for the files, it would be perfect if just reading the name of the file, it was possible to know what is that file and where fits in the game.
- Here is an example, note that some resources require to be loaded all at once while other require to be loaded only at initialization (gui, font).
-
+
```
resources/audio/fx/long_jump.wav
resources/audio/music/main_theme.ogg
diff --git a/build.zig b/build.zig
index 409c57ab5..f82ccc531 100644
--- a/build.zig
+++ b/build.zig
@@ -2,7 +2,7 @@ const std = @import("std");
const builtin = @import("builtin");
/// Minimum supported version of Zig
-const min_ver = "0.13.0";
+const min_ver = "0.15.1";
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
const emccOutputFile = "index.html";
@@ -99,26 +99,32 @@ const config_h_flags = outer: {
break :outer flags[0..i].*;
};
-fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
- var raylib_flags_arr = std.ArrayList([]const u8).init(b.allocator);
- defer raylib_flags_arr.deinit();
+pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
+ var raylib_flags_arr: std.ArrayList([]const u8) = .empty;
+ defer raylib_flags_arr.deinit(b.allocator);
- try raylib_flags_arr.appendSlice(&[_][]const u8{
- "-std=gnu99",
- "-D_GNU_SOURCE",
- "-DGL_SILENCE_DEPRECATION=199309L",
- "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
- });
+ try raylib_flags_arr.appendSlice(
+ b.allocator,
+ &[_][]const u8{
+ "-std=gnu99",
+ "-D_GNU_SOURCE",
+ "-DGL_SILENCE_DEPRECATION=199309L",
+ "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
+ },
+ );
if (options.shared) {
- try raylib_flags_arr.appendSlice(&[_][]const u8{
- "-fPIC",
- "-DBUILD_LIBTYPE_SHARED",
- });
+ try raylib_flags_arr.appendSlice(
+ b.allocator,
+ &[_][]const u8{
+ "-fPIC",
+ "-DBUILD_LIBTYPE_SHARED",
+ },
+ );
}
// Sets a flag indiciating the use of a custom `config.h`
- try raylib_flags_arr.append("-DEXTERNAL_CONFIG_FLAGS");
+ try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
if (options.config.len > 0) {
// Splits a space-separated list of config flags into multiple flags
//
@@ -128,7 +134,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
// Apply config flags supplied by the user
while (config_iter.next()) |config_flag|
- try raylib_flags_arr.append(config_flag);
+ try raylib_flags_arr.append(b.allocator, config_flag);
// Apply all relevant configs from `src/config.h` *except* the user-specified ones
//
@@ -146,11 +152,11 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
}
// Otherwise, append default value from config.h to compile flags
- try raylib_flags_arr.append(flag);
+ try raylib_flags_arr.append(b.allocator, flag);
}
} else {
// Set default config if no custome config got set
- try raylib_flags_arr.appendSlice(&config_h_flags);
+ try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
}
const raylib = b.addLibrary(.{
@@ -168,28 +174,28 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.addIncludePath(b.path("src/external/glfw/include"));
}
- var c_source_files = try std.ArrayList([]const u8).initCapacity(b.allocator, 2);
+ var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2);
c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c", "src/utils.c" });
if (options.rshapes) {
- try c_source_files.append("src/rshapes.c");
- try raylib_flags_arr.append("-DSUPPORT_MODULE_RSHAPES");
+ try c_source_files.append(b.allocator, "src/rshapes.c");
+ try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RSHAPES");
}
if (options.rtextures) {
- try c_source_files.append("src/rtextures.c");
- try raylib_flags_arr.append("-DSUPPORT_MODULE_RTEXTURES");
+ try c_source_files.append(b.allocator, "src/rtextures.c");
+ try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RTEXTURES");
}
if (options.rtext) {
- try c_source_files.append("src/rtext.c");
- try raylib_flags_arr.append("-DSUPPORT_MODULE_RTEXT");
+ try c_source_files.append(b.allocator, "src/rtext.c");
+ try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RTEXT");
}
if (options.rmodels) {
- try c_source_files.append("src/rmodels.c");
- try raylib_flags_arr.append("-DSUPPORT_MODULE_RMODELS");
+ try c_source_files.append(b.allocator, "src/rmodels.c");
+ try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RMODELS");
}
if (options.raudio) {
- try c_source_files.append("src/raudio.c");
- try raylib_flags_arr.append("-DSUPPORT_MODULE_RAUDIO");
+ try c_source_files.append(b.allocator, "src/raudio.c");
+ try raylib_flags_arr.append(b.allocator, "-DSUPPORT_MODULE_RAUDIO");
}
if (options.opengl_version != .auto) {
@@ -200,7 +206,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
switch (target.result.os.tag) {
.windows => {
switch (options.platform) {
- .glfw => try c_source_files.append("src/rglfw.c"),
+ .glfw => try c_source_files.append(b.allocator, "src/rglfw.c"),
.rgfw, .sdl, .drm, .android => {},
}
@@ -261,14 +267,14 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.addSystemIncludePath(.{ .cwd_relative = androidAsmPath });
raylib.addSystemIncludePath(.{ .cwd_relative = androidGluePath });
- var libcData = std.ArrayList(u8).init(b.allocator);
- const writer = libcData.writer();
+ var libcData: std.ArrayList(u8) = .empty;
+ var aw: std.Io.Writer.Allocating = .fromArrayList(b.allocator, &libcData);
try (std.zig.LibCInstallation{
.include_dir = androidIncludePath,
.sys_include_dir = androidIncludePath,
.crt_dir = androidApiSpecificPath,
- }).render(writer);
- const libcFile = b.addWriteFiles().add("android-libc.txt", try libcData.toOwnedSlice());
+ }).render(&aw.writer);
+ const libcFile = b.addWriteFiles().add("android-libc.txt", try libcData.toOwnedSlice(b.allocator));
raylib.setLibCFile(libcFile);
if (options.opengl_version == .auto) {
@@ -279,7 +285,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
setDesktopPlatform(raylib, .android);
} else {
- try c_source_files.append("src/rglfw.c");
+ try c_source_files.append(b.allocator, "src/rglfw.c");
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
raylib.root_module.addCMacro("_GLFW_X11", "");
@@ -320,7 +326,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
}
},
.freebsd, .openbsd, .netbsd, .dragonfly => {
- try c_source_files.append("rglfw.c");
+ try c_source_files.append(b.allocator, "rglfw.c");
raylib.linkSystemLibrary("GL");
raylib.linkSystemLibrary("rt");
raylib.linkSystemLibrary("dl");
@@ -343,7 +349,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
}
// On macos rglfw.c include Objective-C files.
- try raylib_flags_arr.append("-ObjC");
+ try raylib_flags_arr.append(b.allocator, "-ObjC");
raylib.root_module.addCSourceFile(.{
.file = b.path("src/rglfw.c"),
.flags = raylib_flags_arr.items,
diff --git a/build.zig.zon b/build.zig.zon
index 571550860..7037008ed 100644
--- a/build.zig.zon
+++ b/build.zig.zon
@@ -1,7 +1,7 @@
.{
.name = .raylib,
.version = "5.5.0",
- .minimum_zig_version = "0.14.0",
+ .minimum_zig_version = "0.15.1",
.fingerprint = 0x13035e5cb8bc1ac2, // Changing this has security and trust implications.
diff --git a/examples/Makefile b/examples/Makefile
index b838ffb9a..25baa9bbe 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -507,6 +507,7 @@ CORE = \
core/core_3d_camera_free \
core/core_3d_camera_mode \
core/core_3d_camera_split_screen \
+ core/core_3d_camera_fps \
core/core_3d_picking \
core/core_automation_events \
core/core_basic_screen_manager \
@@ -598,6 +599,7 @@ TEXT = \
text/text_raylib_fonts \
text/text_rectangle_bounds \
text/text_unicode \
+ text/text_unicode_ranges \
text/text_writing_anim
MODELS = \
@@ -639,7 +641,7 @@ SHADERS = \
shaders/shaders_mesh_instancing \
shaders/shaders_model_shader \
shaders/shaders_multi_sample2d \
- shaders/shaders_normalmap \
+ shaders/shaders_normal_map \
shaders/shaders_palette_switch \
shaders/shaders_postprocessing \
shaders/shaders_raymarching \
diff --git a/examples/Makefile.Web b/examples/Makefile.Web
index ef10840ee..74b94dd6f 100644
--- a/examples/Makefile.Web
+++ b/examples/Makefile.Web
@@ -104,7 +104,7 @@ USE_WAYLAND_DISPLAY ?= FALSE
BUILD_WEB_ASYNCIFY ?= TRUE
BUILD_WEB_SHELL ?= $(RAYLIB_PATH)/src/shell.html
BUILD_WEB_HEAP_SIZE ?= 134217728
-BUILD_WEB_RESOURCES ?= TRUE
+BUILD_WEB_RESOURCES ?= FALSE
BUILD_WEB_RESOURCES_PATH ?= $(dir $<)resources@resources
# Use WebGL2 backend (OpenGL 3.0)
# WARNING: Requires raylib compiled with GRAPHICS_API_OPENGL_ES3
@@ -507,6 +507,7 @@ CORE = \
core/core_3d_camera_free \
core/core_3d_camera_mode \
core/core_3d_camera_split_screen \
+ core/core_3d_camera_fps \
core/core_3d_picking \
core/core_automation_events \
core/core_basic_screen_manager \
@@ -598,6 +599,7 @@ TEXT = \
text/text_raylib_fonts \
text/text_rectangle_bounds \
text/text_unicode \
+ text/text_unicode_ranges \
text/text_writing_anim
MODELS = \
@@ -639,7 +641,7 @@ SHADERS = \
shaders/shaders_mesh_instancing \
shaders/shaders_model_shader \
shaders/shaders_multi_sample2d \
- shaders/shaders_normalmap \
+ shaders/shaders_normal_map \
shaders/shaders_palette_switch \
shaders/shaders_postprocessing \
shaders/shaders_raymarching \
@@ -702,6 +704,9 @@ core/core_3d_camera_mode: core/core_3d_camera_mode.c
core/core_3d_camera_split_screen: core/core_3d_camera_split_screen.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+core/core_3d_camera_fps: core/core_3d_camera_fps.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
core/core_3d_picking: core/core_3d_picking.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -916,8 +921,7 @@ textures/textures_logo_raylib: textures/textures_logo_raylib.c
--preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png
textures/textures_mouse_painting: textures/textures_mouse_painting.c
- $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
- --preload-file textures/my_amazing_texture_painting.png@my_amazing_texture_painting.png
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_npatch_drawing: textures/textures_npatch_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
@@ -996,14 +1000,14 @@ text/text_input_box: text/text_input_box.c
text/text_raylib_fonts: text/text_raylib_fonts.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
- --preload-file text/resources/fonts/alagard.png@resources/fonts/alagard.png \
- --preload-file text/resources/fonts/pixelplay.png@resources/fonts/pixelplay.png \
- --preload-file text/resources/fonts/mecha.png@resources/fonts/mecha.png \
- --preload-file text/resources/fonts/setback.png@resources/fonts/setback.png \
- --preload-file text/resources/fonts/romulus.png@resources/fonts/romulus.png \
- --preload-file text/resources/fonts/pixantiqua.png@resources/fonts/pixantiqua.png \
- --preload-file text/resources/fonts/alpha_beta.png@resources/fonts/alpha_beta.png \
- --preload-file text/resources/fonts/jupiter_crash.png@resources/fonts/jupiter_crash.png
+ --preload-file text/resources/sprite_fonts/alagard.png@resources/sprite_fonts/alagard.png \
+ --preload-file text/resources/sprite_fonts/pixelplay.png@resources/sprite_fonts/pixelplay.png \
+ --preload-file text/resources/sprite_fonts/mecha.png@resources/sprite_fonts/mecha.png \
+ --preload-file text/resources/sprite_fonts/setback.png@resources/sprite_fonts/setback.png \
+ --preload-file text/resources/sprite_fonts/romulus.png@resources/sprite_fonts/romulus.png \
+ --preload-file text/resources/sprite_fonts/pixantiqua.png@resources/sprite_fonts/pixantiqua.png \
+ --preload-file text/resources/sprite_fonts/alpha_beta.png@resources/sprite_fonts/alpha_beta.png \
+ --preload-file text/resources/sprite_fonts/jupiter_crash.png@resources/sprite_fonts/jupiter_crash.png
text/text_rectangle_bounds: text/text_rectangle_bounds.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -1014,6 +1018,10 @@ text/text_unicode: text/text_unicode.c
--preload-file text/resources/noto_cjk.fnt@resources/noto_cjk.fnt \
--preload-file text/resources/symbola.fnt@resources/symbola.fnt
+text/text_unicode_ranges: text/text_unicode_ranges.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
+ --preload-file text/resources/NotoSansTC-Regular.ttf@resources/NotoSansTC-Regular.ttf
+
text/text_writing_anim: text/text_writing_anim.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@@ -1202,7 +1210,7 @@ shaders/shaders_multi_sample2d: shaders/shaders_multi_sample2d.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/shaders/glsl100/color_mix.fs@resources/shaders/glsl100/color_mix.fs
-shaders/shaders_normalmap: shaders/shaders_normalmap.c
+shaders/shaders_normal_map: shaders/shaders_normal_map.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/shaders/glsl100/normalmap.vs@resources/shaders/glsl100/normalmap.vs \
--preload-file shaders/resources/shaders/glsl100/normalmap.fs@resources/shaders/glsl100/normalmap.fs \
diff --git a/examples/README.md b/examples/README.md
index cb17f8e84..b391732e9 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -16,9 +16,9 @@ You may find it easier to use than other toolchains, especially when it comes to
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
-## EXAMPLES COLLECTION [TOTAL: 160]
+## EXAMPLES COLLECTION [TOTAL: 162]
-### category: core [36]
+### category: core [37]
Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality.
@@ -40,6 +40,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
| [core_3d_camera_free](core/core_3d_camera_free.c) |
| ⭐☆☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_3d_camera_first_person](core/core_3d_camera_first_person.c) |
| ⭐⭐☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_3d_camera_split_screen](core/core_3d_camera_split_screen.c) |
| ⭐⭐⭐☆ | 3.7 | 4.0 | [Jeffery Myers](https://github.com/JeffM2501) |
+| [core_3d_camera_fps](core/core_3d_camera_fps.c) |
| ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) |
| [core_3d_picking](core/core_3d_picking.c) |
| ⭐⭐☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_world_screen](core/core_world_screen.c) |
| ⭐⭐☆☆ | 1.3 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_custom_logging](core/core_custom_logging.c) |
| ⭐⭐⭐☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) |
@@ -121,7 +122,7 @@ Examples using raylib textures functionality, including image/textures loading/g
| [textures_image_rotate](textures/textures_image_rotate.c) |
| ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [textures_textured_curve](textures/textures_textured_curve.c) |
| ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
-### category: text [12]
+### category: text [13]
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
@@ -139,6 +140,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat
| [text_unicode](text/text_unicode.c) |
| ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
| [text_draw_3d](text/text_draw_3d.c) |
| ⭐⭐⭐⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
| [text_codepoints_loading](text/text_codepoints_loading.c) |
| ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
+| [text_unicode_ranges](text/text_unicode_ranges.c) |
| ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
### category: models [23]
@@ -193,7 +195,7 @@ Examples using raylib shaders functionality, including shaders loading, paramete
| [shaders_hot_reloading](shaders/shaders_hot_reloading.c) |
| ⭐⭐⭐☆ | 3.0 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
| [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) |
| ⭐⭐⭐⭐️ | 3.7 | 4.2 | [seanpringle](https://github.com/seanpringle) |
| [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) |
| ⭐⭐☆☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
-| [shaders_normalmap](shaders/shaders_normalmap.c) |
| ⭐⭐⭐⭐️ | 5.6 | 5.6 | [Jeremy Montgomery](https://github.com/Sir_Irk) |
+| [shaders_normal_map](shaders/shaders_normal_map.c) |
| ⭐⭐⭐⭐️ | 5.6 | 5.6 | [Jeremy Montgomery](https://github.com/Sir_Irk) |
| [shaders_spotlight](shaders/shaders_spotlight.c) |
| ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
| [shaders_deferred_render](shaders/shaders_deferred_render.c) |
| ⭐⭐⭐⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
| [shaders_hybrid_render](shaders/shaders_hybrid_render.c) |
| ⭐⭐⭐⭐️ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
diff --git a/examples/audio/audio_mixed_processor.c b/examples/audio/audio_mixed_processor.c
index e761993ff..973c6e26b 100644
--- a/examples/audio/audio_mixed_processor.c
+++ b/examples/audio/audio_mixed_processor.c
@@ -55,7 +55,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [audio] example - processing mixed output");
+ InitWindow(screenWidth, screenHeight, "raylib [audio] example - mixed audio processing");
InitAudioDevice(); // Initialize audio device
diff --git a/examples/audio/audio_module_playing.c b/examples/audio/audio_module_playing.c
index 0d6c48981..2d0834e2b 100644
--- a/examples/audio/audio_module_playing.c
+++ b/examples/audio/audio_module_playing.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [audio] example - Module playing (streaming)
+* raylib [audio] example - module playing (streaming)
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/audio/audio_music_stream.c b/examples/audio/audio_music_stream.c
index b6efb3d2e..c0028a033 100644
--- a/examples/audio/audio_music_stream.c
+++ b/examples/audio/audio_music_stream.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [audio] example - Music playing (streaming)
+* raylib [audio] example - music playing (streaming)
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/audio/audio_raw_stream.c b/examples/audio/audio_raw_stream.c
index 84c8963e3..01a125f4c 100644
--- a/examples/audio/audio_raw_stream.c
+++ b/examples/audio/audio_raw_stream.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [audio] example - Raw audio streaming
+* raylib [audio] example - raw audio streaming
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/audio/audio_sound_loading.c b/examples/audio/audio_sound_loading.c
index 45028839b..5fb356264 100644
--- a/examples/audio/audio_sound_loading.c
+++ b/examples/audio/audio_sound_loading.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [audio] example - Sound loading and playing
+* raylib [audio] example - sound loading and playing
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/audio/audio_sound_positioning.c b/examples/audio/audio_sound_positioning.c
index 4102a97f6..5bef2d671 100644
--- a/examples/audio/audio_sound_positioning.c
+++ b/examples/audio/audio_sound_positioning.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [audio] example - spatialized 3D sound
+* raylib [audio] example - 3d sound positioning
*
* Example complexity rating: [★★☆☆] 2/4
*
@@ -32,7 +32,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [audio] example - spatialized 3D sound");
+ InitWindow(screenWidth, screenHeight, "raylib [audio] example - 3d sound positioning");
InitAudioDevice();
diff --git a/examples/audio/audio_stream_effects.c b/examples/audio/audio_stream_effects.c
index 435e7b878..29186e20e 100644
--- a/examples/audio/audio_stream_effects.c
+++ b/examples/audio/audio_stream_effects.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [audio] example - Music stream processing effects
+* raylib [audio] example - stream effects
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/build_example_web.bat b/examples/build_example_web.bat
index 0fcdc6413..31625389f 100644
--- a/examples/build_example_web.bat
+++ b/examples/build_example_web.bat
@@ -2,27 +2,26 @@
:: .
:: Compile your examples for web using: build_example_web.bat /
:: .
-set "INPUT_FILE=%1"
+SET "INPUT_FILE=%1"
:: Change delimiter for the FOR loop
-for /f "tokens=1-10 delims=/" %%a in ("%INPUT_FILE%") do (
- set CATEGORY=%%a
- set FILENAME=%%b
+FOR /f "tokens=1-10 delims=/" %%a IN ("%INPUT_FILE%") DO (
+ SET CATEGORY=%%a
+ SET FILENAME=%%b
)
-:: > Setup required Environment
+:: > SETup required Environment
:: -------------------------------------
-set RAYLIB_PATH=C:\GitHub\raylib
-set EMSDK_PATH=C:\raylib\emsdk
+SET RAYLIB_PATH=C:\GitHub\raylib
+SET EMSDK_PATH=C:\raylib\emsdk
+SET COMPILER_PATH=C:\raylib\w64devkit\bin
+ENV_SET PATH=%COMPILER_PATH%
+SET MAKE=mingw32-make
echo
:: Set required web compilation options
:: -------------------------------------
-set CC=%EMSDK_PATH%\upstream\emscripten\emcc
-set CFLAGS=-Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result -O3 -I. -Iexternal -I%RAYLIB_PATH%\src -I%RAYLIB_PATH%\external -DPLATFORM_WEB
-set LDFLAGS=-L. -L$(RAYLIB_PATH)\src -sUSE_GLFW=3 -sEXPORTED_RUNTIME_METHODS=ccall -sASYNCIFY --shell-file %RAYLIB_PATH%\src\shell.html
-set LDLIBS=%RAYLIB_PATH%\src\libraylib.web.a
-:: TODO: If using some resources/assets, set the directory path as shown in the commented line!
-set RESOURCES=
-::set RESOURCES=--preload-file $(RESOURCES_PATH)
-cd %RAYLIB_PATH%\examples\%CATEGORY%
+::SET CC=%EMSDK_PATH%\upstream\emscripten\emcc
+::SET CFLAGS=-Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result -O3 -I. -Iexternal -I%RAYLIB_PATH%\src -I%RAYLIB_PATH%\external -DPLATFORM_WEB
+::SET LDFLAGS=-L. -L$(RAYLIB_PATH)\src -sUSE_GLFW=3 -sEXPORTED_RUNTIME_METHODS=ccall -sASYNCIFY --shell-file %RAYLIB_PATH%\src\shell.html
+::SET LDLIBS=%RAYLIB_PATH%\src\libraylib.web.a
echo
:: Clean latest build
:: ------------------------
@@ -38,6 +37,8 @@ echo on
:: Compile program
:: -----------------------
C:
-%CC% -o %FILENAME%.html %FILENAME%.c %CFLAGS% %LDFLAGS% %LDLIBS% %RESOURCES%
+cd %RAYLIB_PATH%\examples
+%MAKE% -f Makefile.Web %CATEGORY%/%FILENAME% PLATFORM=PLATFORM_WEB -B
+::%CC% -o %FILENAME%.html %FILENAME%.c %CFLAGS% %LDFLAGS% %LDLIBS% %RESOURCES%
cd ..
echo
diff --git a/examples/core/core_2d_camera.c b/examples/core/core_2d_camera.c
index 07766e0fb..b752a9640 100644
--- a/examples/core/core_2d_camera.c
+++ b/examples/core/core_2d_camera.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - 2D Camera system
+* raylib [core] example - 2d camera
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/core/core_2d_camera_platformer.c b/examples/core/core_2d_camera_platformer.c
index d4d46e295..b7e8553a3 100644
--- a/examples/core/core_2d_camera_platformer.c
+++ b/examples/core/core_2d_camera_platformer.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - 2D Camera platformer
+* raylib [core] example - 2d camera platformer
*
* Example complexity rating: [★★★☆] 3/4
*
@@ -54,7 +54,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera platformer");
Player player = { 0 };
player.position = (Vector2){ 400, 280 };
diff --git a/examples/core/core_3d_camera_fps.c b/examples/core/core_3d_camera_fps.c
new file mode 100644
index 000000000..4d8962654
--- /dev/null
+++ b/examples/core/core_3d_camera_fps.c
@@ -0,0 +1,330 @@
+/*******************************************************************************************
+*
+* raylib [core] example - 3d first-person camera controller
+*
+* Example complexity rating: [★★★☆] 3/4
+*
+* Example originally created with raylib 5.5, last time updated with raylib 5.5
+*
+* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2025-2025 Agnis Aldins (@nezvers)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "raymath.h"
+#include "rcamera.h"
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+// Movement constants
+#define GRAVITY 32.0f
+#define MAX_SPEED 20.0f
+#define CROUCH_SPEED 5.0f
+#define JUMP_FORCE 12.0f
+#define MAX_ACCEL 150.0f
+// Grounded drag
+#define FRICTION 0.86f
+// Increasing air drag, increases strafing speed
+#define AIR_DRAG 0.98f
+// Responsiveness for turning movement direction to looked direction
+#define CONTROL 15.0f
+#define CROUCH_HEIGHT 0.0f
+#define STAND_HEIGHT 1.0f
+#define BOTTOM_HEIGHT 0.5f
+
+#define NORMALIZE_INPUT 0
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+// Body structure
+typedef struct {
+ Vector3 position;
+ Vector3 velocity;
+ Vector3 dir;
+ bool isGrounded;
+} Body;
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+static Vector2 sensitivity = { 0.001f, 0.001f };
+
+static Body player = { 0 };
+static Vector2 lookRotation = { 0 };
+static float headTimer = 0.0f;
+static float walkLerp = 0.0f;
+static float headLerp = STAND_HEIGHT;
+static Vector2 lean = { 0 };
+
+//----------------------------------------------------------------------------------
+// Module functions declaration
+//----------------------------------------------------------------------------------
+static void DrawLevel(void);
+static void UpdateCameraAngle(Camera *camera);
+static void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed, bool crouchHold);
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d first-person camera controller");
+
+ // Initialize camera variables
+ // NOTE: UpdateCameraAngle() takes care of the rest
+ Camera camera = { 0 };
+ camera.fovy = 60.0f;
+ camera.projection = CAMERA_PERSPECTIVE;
+ camera.position = (Vector3){
+ player.position.x,
+ player.position.y + (BOTTOM_HEIGHT + headLerp),
+ player.position.z,
+ };
+
+ UpdateCameraAngle(&camera); // Update camera parameters
+
+ DisableCursor(); // Limit cursor to relative movement inside the window
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ Vector2 mouseDelta = GetMouseDelta();
+ lookRotation.x -= mouseDelta.x*sensitivity.x;
+ lookRotation.y += mouseDelta.y*sensitivity.y;
+
+ char sideway = (IsKeyDown(KEY_D) - IsKeyDown(KEY_A));
+ char forward = (IsKeyDown(KEY_W) - IsKeyDown(KEY_S));
+ bool crouching = IsKeyDown(KEY_LEFT_CONTROL);
+ UpdateBody(&player, lookRotation.x, sideway, forward, IsKeyPressed(KEY_SPACE), crouching);
+
+ float delta = GetFrameTime();
+ headLerp = Lerp(headLerp, (crouching ? CROUCH_HEIGHT : STAND_HEIGHT), 20.0f*delta);
+ camera.position = (Vector3){
+ player.position.x,
+ player.position.y + (BOTTOM_HEIGHT + headLerp),
+ player.position.z,
+ };
+
+ if (player.isGrounded && ((forward != 0) || (sideway != 0)))
+ {
+ headTimer += delta*3.0f;
+ walkLerp = Lerp(walkLerp, 1.0f, 10.0f*delta);
+ camera.fovy = Lerp(camera.fovy, 55.0f, 5.0f*delta);
+ }
+ else
+ {
+ walkLerp = Lerp(walkLerp, 0.0f, 10.0f*delta);
+ camera.fovy = Lerp(camera.fovy, 60.0f, 5.0f*delta);
+ }
+
+ lean.x = Lerp(lean.x, sideway*0.02f, 10.0f*delta);
+ lean.y = Lerp(lean.y, forward*0.015f, 10.0f*delta);
+
+ UpdateCameraAngle(&camera);
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+ DrawLevel();
+ EndMode3D();
+
+ // Draw info box
+ DrawRectangle(5, 5, 330, 75, Fade(SKYBLUE, 0.5f));
+ DrawRectangleLines(5, 5, 330, 75, BLUE);
+
+ DrawText("Camera controls:", 15, 15, 10, BLACK);
+ DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, BLACK);
+ DrawText("- Look around: arrow keys or mouse", 15, 45, 10, BLACK);
+ DrawText(TextFormat("- Velocity Len: (%06.3f)", Vector2Length((Vector2){ player.velocity.x, player.velocity.z })), 15, 60, 10, BLACK);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------------
+// Module functions definition
+//----------------------------------------------------------------------------------
+void UpdateBody(Body* body, float rot, char side, char forward, bool jumpPressed, bool crouchHold)
+{
+ Vector2 input = (Vector2){ (float)side, (float)-forward };
+
+#if defined(NORMALIZE_INPUT)
+ // Slow down diagonal movement
+ if ((side != 0) && (forward != 0)) input = Vector2Normalize(input);
+#endif
+
+ float delta = GetFrameTime();
+
+ if (!body->isGrounded) body->velocity.y -= GRAVITY*delta;
+
+ if (body->isGrounded && jumpPressed)
+ {
+ body->velocity.y = JUMP_FORCE;
+ body->isGrounded = false;
+
+ // Sound can be played at this moment
+ //SetSoundPitch(fxJump, 1.0f + (GetRandomValue(-100, 100)*0.001));
+ //PlaySound(fxJump);
+ }
+
+ Vector3 front = (Vector3){ sin(rot), 0.f, cos(rot) };
+ Vector3 right = (Vector3){ cos(-rot), 0.f, sin(-rot) };
+
+ Vector3 desiredDir = (Vector3){ input.x*right.x + input.y*front.x, 0.0f, input.x*right.z + input.y*front.z, };
+ body->dir = Vector3Lerp(body->dir, desiredDir, CONTROL*delta);
+
+ float decel = (body->isGrounded ? FRICTION : AIR_DRAG);
+ Vector3 hvel = (Vector3){ body->velocity.x*decel, 0.0f, body->velocity.z*decel };
+
+ float hvelLength = Vector3Length(hvel); // Magnitude
+ if (hvelLength < (MAX_SPEED*0.01f)) hvel = (Vector3){ 0 };
+
+ // This is what creates strafing
+ float speed = Vector3DotProduct(hvel, body->dir);
+
+ // Whenever the amount of acceleration to add is clamped by the maximum acceleration constant,
+ // a Player can make the speed faster by bringing the direction closer to horizontal velocity angle
+ // More info here: https://youtu.be/v3zT3Z5apaM?t=165
+ float maxSpeed = (crouchHold? CROUCH_SPEED : MAX_SPEED);
+ float accel = Clamp(maxSpeed - speed, 0.f, MAX_ACCEL*delta);
+ hvel.x += body->dir.x*accel;
+ hvel.z += body->dir.z*accel;
+
+ body->velocity.x = hvel.x;
+ body->velocity.z = hvel.z;
+
+ body->position.x += body->velocity.x*delta;
+ body->position.y += body->velocity.y*delta;
+ body->position.z += body->velocity.z*delta;
+
+ // Fancy collision system against the floor
+ if (body->position.y <= 0.0f)
+ {
+ body->position.y = 0.0f;
+ body->velocity.y = 0.0f;
+ body->isGrounded = true; // Enable jumping
+ }
+}
+
+// Update camera
+static void UpdateCameraAngle(Camera *camera)
+{
+ const Vector3 up = (Vector3){ 0.0f, 1.0f, 0.0f };
+ const Vector3 targetOffset = (Vector3){ 0.0f, 0.0f, -1.0f };
+
+ // Left and right
+ Vector3 yaw = Vector3RotateByAxisAngle(targetOffset, up, lookRotation.x);
+
+ // Clamp view up
+ float maxAngleUp = Vector3Angle(up, yaw);
+ maxAngleUp -= 0.001f; // Avoid numerical errors
+ if ( -(lookRotation.y) > maxAngleUp) { lookRotation.y = -maxAngleUp; }
+
+ // Clamp view down
+ float maxAngleDown = Vector3Angle(Vector3Negate(up), yaw);
+ maxAngleDown *= -1.0f; // Downwards angle is negative
+ maxAngleDown += 0.001f; // Avoid numerical errors
+ if ( -(lookRotation.y) < maxAngleDown) { lookRotation.y = -maxAngleDown; }
+
+ // Up and down
+ Vector3 right = Vector3Normalize(Vector3CrossProduct(yaw, up));
+
+ // Rotate view vector around right axis
+ float pitchAngle = -lookRotation.y -
+ lean.y;
+ pitchAngle = Clamp(pitchAngle, -PI / 2 + 0.0001f, PI / 2 - 0.0001f); // Clamp angle so it doesn't go past straight up or straight down
+ Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, pitchAngle);
+
+ // Head animation
+ // Rotate up direction around forward axis
+ float headSin = sin(headTimer*PI);
+ float headCos = cos(headTimer*PI);
+ const float stepRotation = 0.01f;
+ camera->up = Vector3RotateByAxisAngle(up, pitch, headSin*stepRotation + lean.x);
+
+ // Camera BOB
+ const float bobSide = 0.1f;
+ const float bobUp = 0.15f;
+ Vector3 bobbing = Vector3Scale(right, headSin*bobSide);
+ bobbing.y = fabsf(headCos*bobUp);
+
+ camera->position = Vector3Add(camera->position, Vector3Scale(bobbing, walkLerp));
+ camera->target = Vector3Add(camera->position, pitch);
+}
+
+// Draw game level
+static void DrawLevel(void)
+{
+ const int floorExtent = 25;
+ const float tileSize = 5.0f;
+ const Color tileColor1 = (Color){ 150, 200, 200, 255 };
+
+ // Floor tiles
+ for (int y = -floorExtent; y < floorExtent; y++)
+ {
+ for (int x = -floorExtent; x < floorExtent; x++)
+ {
+ if ((y & 1) && (x & 1))
+ {
+ DrawPlane((Vector3){ x*tileSize, 0.0f, y*tileSize}, (Vector2){ tileSize, tileSize }, tileColor1);
+ }
+ else if (!(y & 1) && !(x & 1))
+ {
+ DrawPlane((Vector3){ x*tileSize, 0.0f, y*tileSize}, (Vector2){ tileSize, tileSize }, LIGHTGRAY);
+ }
+ }
+ }
+
+ const Vector3 towerSize = (Vector3){ 16.0f, 32.0f, 16.0f };
+ const Color towerColor = (Color){ 150, 200, 200, 255 };
+
+ Vector3 towerPos = (Vector3){ 16.0f, 16.0f, 16.0f };
+ DrawCubeV(towerPos, towerSize, towerColor);
+ DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
+
+ towerPos.x *= -1;
+ DrawCubeV(towerPos, towerSize, towerColor);
+ DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
+
+ towerPos.z *= -1;
+ DrawCubeV(towerPos, towerSize, towerColor);
+ DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
+
+ towerPos.x *= -1;
+ DrawCubeV(towerPos, towerSize, towerColor);
+ DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
+
+ // Red sun
+ DrawSphere((Vector3){ 300.0f, 300.0f, 0.0f }, 100.0f, (Color){ 255, 0, 0, 255 });
+}
diff --git a/examples/core/core_3d_camera_fps.png b/examples/core/core_3d_camera_fps.png
new file mode 100644
index 000000000..d4f83482f
Binary files /dev/null and b/examples/core/core_3d_camera_fps.png differ
diff --git a/examples/core/core_3d_camera_free.c b/examples/core/core_3d_camera_free.c
index b490575db..dde6a6c7d 100644
--- a/examples/core/core_3d_camera_free.c
+++ b/examples/core/core_3d_camera_free.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Initialize 3d camera free
+* raylib [core] example - 3d camera free
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_3d_camera_mode.c b/examples/core/core_3d_camera_mode.c
index 372fd5923..e265b7eb0 100644
--- a/examples/core/core_3d_camera_mode.c
+++ b/examples/core/core_3d_camera_mode.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Initialize 3d camera mode
+* raylib [core] example - 3d camera mode
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_3d_camera_split_screen.c b/examples/core/core_3d_camera_split_screen.c
index b0cb0a18d..7f3d9de42 100644
--- a/examples/core/core_3d_camera_split_screen.c
+++ b/examples/core/core_3d_camera_split_screen.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - 3d cmaera split screen
+* raylib [core] example - 3d camera split screen
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/core/core_3d_picking.c b/examples/core/core_3d_picking.c
index 8a6fbd156..f62c9331b 100644
--- a/examples/core/core_3d_picking.c
+++ b/examples/core/core_3d_picking.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Picking in 3d mode
+* raylib [core] example - 3d picking
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/core/core_basic_screen_manager.c b/examples/core/core_basic_screen_manager.c
index 67de31159..c2d37818f 100644
--- a/examples/core/core_basic_screen_manager.c
+++ b/examples/core/core_basic_screen_manager.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] examples - basic screen manager
+* raylib [core] example - basic screen manager
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_basic_window.c b/examples/core/core_basic_window.c
index b3f20367a..73d75683a 100644
--- a/examples/core/core_basic_window.c
+++ b/examples/core/core_basic_window.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Basic window
+* raylib [core] example - basic window
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_basic_window_web.c b/examples/core/core_basic_window_web.c
index e8607432b..c4aa18177 100644
--- a/examples/core/core_basic_window_web.c
+++ b/examples/core/core_basic_window_web.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Basic window (adapted for HTML5 platform)
+* raylib [core] example - basic window
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_custom_logging.c b/examples/core/core_custom_logging.c
index d27c9fd6b..5ea2a4762 100644
--- a/examples/core/core_custom_logging.c
+++ b/examples/core/core_custom_logging.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Custom logging
+* raylib [core] example - custom logging
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/core/core_drop_files.c b/examples/core/core_drop_files.c
index 4aafbb8c9..0dc9ea929 100644
--- a/examples/core/core_drop_files.c
+++ b/examples/core/core_drop_files.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Windows drop files
+* raylib [core] example - drop files
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/core/core_high_dpi.c b/examples/core/core_high_dpi.c
index 05661f50e..23ae235a5 100644
--- a/examples/core/core_high_dpi.c
+++ b/examples/core/core_high_dpi.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - HighDPI
+* raylib [core] example - high dpi
*
* Example complexity rating: [★☆☆☆] e/4
*
@@ -29,7 +29,7 @@ int main(void)
const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
- InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi");
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - high dpi");
SetWindowMinSize(450, 450);
int logicalGridDescY = 120;
diff --git a/examples/core/core_input_gamepad.c b/examples/core/core_input_gamepad.c
index 1ab6b55ae..aae6e4b55 100644
--- a/examples/core/core_input_gamepad.c
+++ b/examples/core/core_input_gamepad.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Gamepad input
+* raylib [core] example - gamepad input
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_input_gestures.c b/examples/core/core_input_gestures.c
index b491da393..fd7250658 100644
--- a/examples/core/core_input_gestures.c
+++ b/examples/core/core_input_gestures.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Input Gestures Detection
+* raylib [core] example - input gestures
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/core/core_input_gestures_web.c b/examples/core/core_input_gestures_web.c
index 613aff0ab..743639ea0 100644
--- a/examples/core/core_input_gestures_web.c
+++ b/examples/core/core_input_gestures_web.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Input Gestures for Web
+* raylib [core] example - input gestures web
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/core/core_input_keys.c b/examples/core/core_input_keys.c
index 670df1ef4..6ab099c4e 100644
--- a/examples/core/core_input_keys.c
+++ b/examples/core/core_input_keys.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Keyboard input
+* raylib [core] example - keyboard input
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_input_mouse.c b/examples/core/core_input_mouse.c
index 58c1c4035..d892b4e9b 100644
--- a/examples/core/core_input_mouse.c
+++ b/examples/core/core_input_mouse.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Mouse input
+* raylib [core] example - mouse input
*
* Example complexity rating: [★☆☆☆] 1/4
*
@@ -29,7 +29,6 @@ int main(void)
Vector2 ballPosition = { -100.0f, -100.0f };
Color ballColor = DARKBLUE;
- int isCursorHidden = 0;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
@@ -41,15 +40,13 @@ int main(void)
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_H))
{
- if (isCursorHidden == 0)
+ if (IsCursorHidden())
{
- HideCursor();
- isCursorHidden = 1;
+ ShowCursor();
}
else
{
- ShowCursor();
- isCursorHidden = 0;
+ HideCursor();
}
}
@@ -75,7 +72,7 @@ int main(void)
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);
DrawText("Press 'H' to toggle cursor visibility", 10, 30, 20, DARKGRAY);
- if (isCursorHidden == 1) DrawText("CURSOR HIDDEN", 20, 60, 20, RED);
+ if (!IsCursorHidden()) DrawText("CURSOR HIDDEN", 20, 60, 20, RED);
else DrawText("CURSOR VISIBLE", 20, 60, 20, LIME);
EndDrawing();
diff --git a/examples/core/core_input_mouse_wheel.c b/examples/core/core_input_mouse_wheel.c
index 242eeafa6..b5d0a0e21 100644
--- a/examples/core/core_input_mouse_wheel.c
+++ b/examples/core/core_input_mouse_wheel.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] examples - Mouse wheel input
+* raylib [core] example - input mouse wheel
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_input_multitouch.c b/examples/core/core_input_multitouch.c
index 136c603cc..01dd90fae 100644
--- a/examples/core/core_input_multitouch.c
+++ b/examples/core/core_input_multitouch.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Input multitouch
+* raylib [core] example - input multitouch
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_random_values.c b/examples/core/core_random_values.c
index 16b89e700..911de2949 100644
--- a/examples/core/core_random_values.c
+++ b/examples/core/core_random_values.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Generate random values
+* raylib [core] example - generate random values
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_scissor_test.c b/examples/core/core_scissor_test.c
index 49e90c794..3166fad86 100644
--- a/examples/core/core_scissor_test.c
+++ b/examples/core/core_scissor_test.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Scissor test
+* raylib [core] example - scissor test
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_smooth_pixelperfect.c b/examples/core/core_smooth_pixelperfect.c
index 697b2ff09..9570ce482 100644
--- a/examples/core/core_smooth_pixelperfect.c
+++ b/examples/core/core_smooth_pixelperfect.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Smooth Pixel-perfect camera
+* raylib [core] example - smooth pixel-perfect camera
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/core/core_storage_values.c b/examples/core/core_storage_values.c
index 747b94d5b..c74c7ce93 100644
--- a/examples/core/core_storage_values.c
+++ b/examples/core/core_storage_values.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Storage save/load values
+* raylib [core] example - storage save/load values
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/core/core_vr_simulator.c b/examples/core/core_vr_simulator.c
index 34b556e99..635bda123 100644
--- a/examples/core/core_vr_simulator.c
+++ b/examples/core/core_vr_simulator.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - VR Simulator (Oculus Rift CV1 parameters)
+* raylib [core] example - vr simulator
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/core/core_window_letterbox.c b/examples/core/core_window_letterbox.c
index a46e9eec6..4bbf12cfe 100644
--- a/examples/core/core_window_letterbox.c
+++ b/examples/core/core_window_letterbox.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - window scale letterbox (and virtual mouse)
+* raylib [core] example - window scale letterbox
*
* Example complexity rating: [★★☆☆] 2/4
*
@@ -27,12 +27,12 @@
//------------------------------------------------------------------------------------
int main(void)
{
- const int windowWidth = 800;
- const int windowHeight = 450;
+ const int screenWidth = 800;
+ const int screenHeight = 450;
// Enable config flags for resizable window and vertical synchro
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT);
- InitWindow(windowWidth, windowHeight, "raylib [core] example - window scale letterbox");
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - window scale letterbox");
SetWindowMinSize(320, 240);
int gameScreenWidth = 640;
diff --git a/examples/core/core_window_should_close.c b/examples/core/core_window_should_close.c
index 274891ef3..bb7daf3ee 100644
--- a/examples/core/core_window_should_close.c
+++ b/examples/core/core_window_should_close.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Window should close
+* raylib [core] example - window should close
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/core/core_world_screen.c b/examples/core/core_world_screen.c
index 6e065ca34..6df76db08 100644
--- a/examples/core/core_world_screen.c
+++ b/examples/core/core_world_screen.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - World to screen
+* raylib [core] example - core world screen
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/examples_list.txt b/examples/examples_list.txt
index 230656000..a980ff4a4 100644
--- a/examples/examples_list.txt
+++ b/examples/examples_list.txt
@@ -3,7 +3,7 @@
# examples must be provided as: ;;;;;"";
#
# This list is used as the main reference by [rexm] tool for examples collection validation and management
-# New examples must be added to this list and any possible rename must be made on this list first
+# New examples must be added to this list and any possible rename must be made on this list first
#
# WARNING: List is not ordered by example name but by the display order on web
#
@@ -23,6 +23,7 @@ core;core_3d_camera_mode;⭐️☆☆☆;1.0;1.0;"Ramon Santamaria";@raysan5
core;core_3d_camera_free;⭐️☆☆☆;1.3;1.3;"Ramon Santamaria";@raysan5
core;core_3d_camera_first_person;⭐️⭐️☆☆;1.3;1.3;"Ramon Santamaria";@raysan5
core;core_3d_camera_split_screen;⭐️⭐️⭐️☆;3.7;4.0;"Jeffery Myers";@JeffM2501
+core;core_3d_camera_fps;⭐️⭐️⭐️☆;5.5;5.5;"Agnis Aldins";@nezvers
core;core_3d_picking;⭐️⭐️☆☆;1.3;4.0;"Ramon Santamaria";@raysan5
core;core_world_screen;⭐️⭐️☆☆;1.3;1.4;"Ramon Santamaria";@raysan5
core;core_custom_logging;⭐️⭐️⭐️☆;2.5;2.5;"Pablo Marcos Oltra";@pamarcos
@@ -141,7 +142,7 @@ shaders;shaders_simple_mask;⭐️⭐️☆☆;2.5;3.7;"Chris Camacho";@chriscam
shaders;shaders_hot_reloading;⭐️⭐️⭐️☆;3.0;3.5;"Ramon Santamaria";@raysan5
shaders;shaders_mesh_instancing;⭐️⭐️⭐️⭐️;3.7;4.2;"seanpringle";@seanpringle
shaders;shaders_multi_sample2d;⭐️⭐️☆☆;3.5;3.5;"Ramon Santamaria";@raysan5
-shaders;shaders_normalmap;⭐️⭐️⭐️⭐️;5.6;5.6;"Jeremy Montgomery";@Sir_Irk
+shaders;shaders_normal_map;⭐️⭐️⭐️⭐️;5.6;5.6;"Jeremy Montgomery";@Sir_Irk
shaders;shaders_spotlight;⭐️⭐️☆☆;2.5;3.7;"Chris Camacho";@chriscamacho
shaders;shaders_deferred_render;⭐️⭐️⭐️⭐️;4.5;4.5;"Justin Andreas Lacoste";@27justin
shaders;shaders_hybrid_render;⭐️⭐️⭐️⭐️;4.2;4.2;"Buğra Alptekin Sarı";@BugraAlptekinSari
@@ -167,3 +168,4 @@ others;easings_testbed;⭐️⭐️⭐️☆;2.5;3.0;"Juan Miguel López";@flash
others;raylib_opengl_interop;⭐️⭐️⭐️⭐️;3.8;4.0;"Stephan Soller";@arkanis
others;embedded_files_loading;⭐️⭐️☆☆;3.0;3.5;"Kristian Holmgren";@defutura
others;raymath_vector_angle;⭐️⭐️☆☆;1.0;4.6;"Ramon Santamaria";@raysan5
+text;text_unicode_ranges;⭐⭐⭐⭐️;2.5;4.0;"Vlad Adrian";@demizdor
diff --git a/examples/models/models_animation.c b/examples/models/models_animation.c
index b02172dd7..7193ed50f 100644
--- a/examples/models/models_animation.c
+++ b/examples/models/models_animation.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Load 3d model with animations and play them
+* raylib [models] example - model animation
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/models/models_billboard.c b/examples/models/models_billboard.c
index 82610a4df..40266c277 100644
--- a/examples/models/models_billboard.c
+++ b/examples/models/models_billboard.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Drawing billboards
+* raylib [models] example - billboard render
*
* Example complexity rating: [★★★☆] 3/4
*
@@ -26,7 +26,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards");
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - billboard render");
// Define the camera to look into our 3d world
Camera camera = { 0 };
diff --git a/examples/models/models_bone_socket.c b/examples/models/models_bone_socket.c
index cdad46738..8348aa50d 100644
--- a/examples/models/models_bone_socket.c
+++ b/examples/models/models_bone_socket.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Using bones as socket for calculating the positioning of something
+* raylib [models] example - bone socket
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/models/models_box_collisions.c b/examples/models/models_box_collisions.c
index 8b07d1324..620a94a2d 100644
--- a/examples/models/models_box_collisions.c
+++ b/examples/models/models_box_collisions.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Detect basic 3d collisions (box vs sphere vs box)
+* raylib [models] example - box collisions
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/models/models_cubicmap.c b/examples/models/models_cubicmap.c
index 980215b2e..fe6c6604f 100644
--- a/examples/models/models_cubicmap.c
+++ b/examples/models/models_cubicmap.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Cubicmap loading and drawing
+* raylib [models] example - cubicmap loading and drawing
*
* Example complexity rating: [★★☆☆] 2/4
*
@@ -25,7 +25,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [models] example - cubesmap loading and drawing");
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - cubicmap loading and drawing");
// Define the camera to look into our 3d world
Camera camera = { 0 };
diff --git a/examples/models/models_draw_cube_texture.c b/examples/models/models_draw_cube_texture.c
index 650f80aee..bc55b4c15 100644
--- a/examples/models/models_draw_cube_texture.c
+++ b/examples/models/models_draw_cube_texture.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Draw textured cube
+* raylib [models] example - draw cube texture
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/models/models_geometric_shapes.c b/examples/models/models_geometric_shapes.c
index 8cce4fcb0..baaf458b1 100644
--- a/examples/models/models_geometric_shapes.c
+++ b/examples/models/models_geometric_shapes.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Draw some basic geometric shapes (cube, sphere, cylinder...)
+* raylib [models] example - geometric shapes
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/models/models_gpu_skinning.c b/examples/models/models_gpu_skinning.c
index d1b8c097a..ac989aa60 100644
--- a/examples/models/models_gpu_skinning.c
+++ b/examples/models/models_gpu_skinning.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [core] example - Doing skinning on the gpu using a vertex shader
+* raylib [models] example - gpu skinning
*
* Example complexity rating: [★★★☆] 3/4
*
@@ -37,7 +37,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [models] example - GPU skinning");
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - gpu skinning");
// Define the camera to look into our 3d world
Camera camera = { 0 };
diff --git a/examples/models/models_heightmap.c b/examples/models/models_heightmap.c
index a86d8aec3..c7f3c2094 100644
--- a/examples/models/models_heightmap.c
+++ b/examples/models/models_heightmap.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Heightmap loading and drawing
+* raylib [models] example - heightmap terrain
*
* Example complexity rating: [★☆☆☆] 1/4
*
@@ -25,7 +25,7 @@ int main(void)
int screenWidth = 800;
int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing");
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap terrain");
// Define our custom camera to look into our 3d world
Camera camera = { 0 };
diff --git a/examples/models/models_loading.c b/examples/models/models_loading.c
index fd1849a82..2e22e8ec9 100644
--- a/examples/models/models_loading.c
+++ b/examples/models/models_loading.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Models loading
+* raylib [models] example - models loading
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/models/models_loading_gltf.c b/examples/models/models_loading_gltf.c
index e3a5b5bcb..a827ec154 100644
--- a/examples/models/models_loading_gltf.c
+++ b/examples/models/models_loading_gltf.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - loading gltf with animations
+* raylib [models] example - loading gltf animations
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/models/models_loading_m3d.c b/examples/models/models_loading_m3d.c
index 871bb54dd..9851e3cbf 100644
--- a/examples/models/models_loading_m3d.c
+++ b/examples/models/models_loading_m3d.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Load models M3D
+* raylib [models] example - model loading m3d
*
* Example complexity rating: [★★☆☆] 2/4
*
@@ -31,7 +31,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [models] example - M3D model loading");
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - model loading m3d");
// Define the camera to look into our 3d world
Camera camera = { 0 };
diff --git a/examples/models/models_loading_vox.c b/examples/models/models_loading_vox.c
index 19002170d..0dad76d67 100644
--- a/examples/models/models_loading_vox.c
+++ b/examples/models/models_loading_vox.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Load models vox (MagicaVoxel)
+* raylib [models] example - magicavoxel loading
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/models/models_mesh_generation.c b/examples/models/models_mesh_generation.c
index 770846c16..82f1022b7 100644
--- a/examples/models/models_mesh_generation.c
+++ b/examples/models/models_mesh_generation.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - procedural mesh generation
+* raylib [models] example - mesh generation
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/models/models_mesh_picking.c b/examples/models/models_mesh_picking.c
index 141bfd504..e1ec8710d 100644
--- a/examples/models/models_mesh_picking.c
+++ b/examples/models/models_mesh_picking.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Mesh picking in 3d mode, ground plane, triangle, mesh
+* raylib [models] example - mesh picking
*
* Example complexity rating: [★★★☆] 3/4
*
@@ -89,7 +89,7 @@ int main(void)
// Display information about closest hit
RayCollision collision = { 0 };
- char *hitObjectName = "None";
+ const char *hitObjectName = "None";
collision.distance = FLT_MAX;
collision.hit = false;
Color cursorColor = WHITE;
diff --git a/examples/models/models_orthographic_projection.c b/examples/models/models_orthographic_projection.c
index 8392f7a7d..d0873724d 100644
--- a/examples/models/models_orthographic_projection.c
+++ b/examples/models/models_orthographic_projection.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Show the difference between perspective and orthographic projection
+* raylib [models] example - orthographic projection
*
* Example complexity rating: [★☆☆☆] 1/4
*
@@ -30,7 +30,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes");
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - orthographic projection");
// Define the camera to look into our 3d world
Camera camera = { { 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, FOVY_PERSPECTIVE, CAMERA_PERSPECTIVE };
diff --git a/examples/models/models_point_rendering.c b/examples/models/models_point_rendering.c
index 748e72524..2eba34355 100644
--- a/examples/models/models_point_rendering.c
+++ b/examples/models/models_point_rendering.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib example - point rendering
+* raylib [models] example - point rendering
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/models/models_skybox.c b/examples/models/models_skybox.c
index a5304a93d..6cd0259f7 100644
--- a/examples/models/models_skybox.c
+++ b/examples/models/models_skybox.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Skybox loading and drawing
+* raylib [models] example - skybox rendering
*
* Example complexity rating: [★★☆☆] 2/4
*
@@ -37,7 +37,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox loading and drawing");
+ InitWindow(screenWidth, screenHeight, "raylib [models] example - skybox rendering");
// Define the camera to look into our 3d world
Camera camera = { 0 };
diff --git a/examples/models/models_tesseract_view.c b/examples/models/models_tesseract_view.c
index 661d078b4..d23e34141 100644
--- a/examples/models/models_tesseract_view.c
+++ b/examples/models/models_tesseract_view.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Tesseract view
+* raylib [models] example - tesseract view
*
* NOTE: This example only works on platforms that support drag & drop (Windows, Linux, OSX, Html5?)
*
diff --git a/examples/models/models_waving_cubes.c b/examples/models/models_waving_cubes.c
index 455d85e18..51febf39d 100644
--- a/examples/models/models_waving_cubes.c
+++ b/examples/models/models_waving_cubes.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Waving cubes
+* raylib [models] example - waving cubes
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/models/models_yaw_pitch_roll.c b/examples/models/models_yaw_pitch_roll.c
index 3316ddc00..d5ab629dd 100644
--- a/examples/models/models_yaw_pitch_roll.c
+++ b/examples/models/models_yaw_pitch_roll.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [models] example - Plane rotations (yaw, pitch, roll)
+* raylib [models] example - plane rotations (yaw, pitch, roll)
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/models/resources/shaders/glsl100/voxel_lighting.fs b/examples/models/resources/shaders/glsl100/voxel_lighting.fs
new file mode 100644
index 000000000..f23d9292d
--- /dev/null
+++ b/examples/models/resources/shaders/glsl100/voxel_lighting.fs
@@ -0,0 +1,65 @@
+#version 100
+
+precision mediump float;
+
+// Input from vertex shader
+varying vec3 fragPosition;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+// Uniforms
+uniform vec4 colDiffuse;
+uniform vec4 ambient;
+uniform vec3 viewPos;
+
+#define MAX_LIGHTS 4
+#define LIGHT_DIRECTIONAL 0
+#define LIGHT_POINT 1
+
+struct Light {
+ int enabled;
+ int type;
+ vec3 position;
+ vec3 target;
+ vec4 color;
+};
+
+uniform Light lights[MAX_LIGHTS];
+
+void main()
+{
+ vec3 lightDot = vec3(0.0);
+ vec3 normal = normalize(fragNormal);
+ vec3 viewD = normalize(viewPos - fragPosition);
+ vec3 specular = vec3(0.0);
+
+ for (int i = 0; i < MAX_LIGHTS; i++)
+ {
+ if (lights[i].enabled == 1)
+ {
+ vec3 light = vec3(0.0);
+
+ if (lights[i].type == LIGHT_DIRECTIONAL)
+ light = -normalize(lights[i].target - lights[i].position);
+
+ if (lights[i].type == LIGHT_POINT)
+ light = normalize(lights[i].position - fragPosition);
+
+ float NdotL = max(dot(normal, light), 0.0);
+ lightDot += lights[i].color.rgb * NdotL;
+
+ if (NdotL > 0.0)
+ {
+ float specCo = pow(max(0.0, dot(viewD, reflect(-light, normal))), 16.0);
+ specular += specCo;
+ }
+ }
+ }
+
+ vec4 finalColor = (fragColor * ((colDiffuse + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
+ finalColor += fragColor * (ambient / 10.0) * colDiffuse;
+
+ finalColor = pow(finalColor, vec4(1.0/2.2)); // gamma correction
+
+ gl_FragColor = finalColor;
+}
diff --git a/examples/models/resources/shaders/glsl100/voxel_lighting.vs b/examples/models/resources/shaders/glsl100/voxel_lighting.vs
new file mode 100644
index 000000000..12f53ed32
--- /dev/null
+++ b/examples/models/resources/shaders/glsl100/voxel_lighting.vs
@@ -0,0 +1,28 @@
+#version 100
+
+precision mediump float;
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+// attribute vec2 vertexTexCoord;
+
+// Input uniform values
+uniform mat4 mvp;
+uniform mat4 matModel;
+uniform mat4 matNormal;
+
+// Output to fragment shader
+varying vec3 fragPosition;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+void main()
+{
+ fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
+ fragColor = vertexColor;
+ fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 1.0)));
+
+ gl_Position = mvp * vec4(vertexPosition, 1.0);
+}
diff --git a/examples/models/resources/shaders/glsl120/voxel_lighting.fs b/examples/models/resources/shaders/glsl120/voxel_lighting.fs
new file mode 100644
index 000000000..eb01f96bb
--- /dev/null
+++ b/examples/models/resources/shaders/glsl120/voxel_lighting.fs
@@ -0,0 +1,62 @@
+#version 120
+// Input from vertex shader
+varying vec3 fragPosition;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+// Uniforms
+uniform vec4 colDiffuse;
+uniform vec4 ambient;
+uniform vec3 viewPos;
+
+#define MAX_LIGHTS 4
+#define LIGHT_DIRECTIONAL 0
+#define LIGHT_POINT 1
+
+struct Light {
+ int enabled;
+ int type;
+ vec3 position;
+ vec3 target;
+ vec4 color;
+};
+
+uniform Light lights[MAX_LIGHTS];
+
+void main()
+{
+ vec3 lightDot = vec3(0.0);
+ vec3 normal = normalize(fragNormal);
+ vec3 viewD = normalize(viewPos - fragPosition);
+ vec3 specular = vec3(0.0);
+
+ for (int i = 0; i < MAX_LIGHTS; i++)
+ {
+ if (lights[i].enabled == 1)
+ {
+ vec3 light = vec3(0.0);
+
+ if (lights[i].type == LIGHT_DIRECTIONAL)
+ light = -normalize(lights[i].target - lights[i].position);
+
+ if (lights[i].type == LIGHT_POINT)
+ light = normalize(lights[i].position - fragPosition);
+
+ float NdotL = max(dot(normal, light), 0.0);
+ lightDot += lights[i].color.rgb * NdotL;
+
+ if (NdotL > 0.0)
+ {
+ float specCo = pow(max(0.0, dot(viewD, reflect(-light, normal))), 16.0);
+ specular += specCo;
+ }
+ }
+ }
+
+ vec4 finalColor = (fragColor * ((colDiffuse + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
+ finalColor += fragColor * (ambient / 10.0) * colDiffuse;
+
+ finalColor = pow(finalColor, vec4(1.0/2.2)); // gamma correction
+
+ gl_FragColor = finalColor;
+}
diff --git a/examples/models/resources/shaders/glsl120/voxel_lighting.vs b/examples/models/resources/shaders/glsl120/voxel_lighting.vs
new file mode 100644
index 000000000..75163c7f8
--- /dev/null
+++ b/examples/models/resources/shaders/glsl120/voxel_lighting.vs
@@ -0,0 +1,24 @@
+#version 120
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+// Uniforms
+uniform mat4 mvp;
+uniform mat4 matModel;
+uniform mat4 matNormal;
+
+// Output to fragment shader
+varying vec3 fragPosition;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+void main()
+{
+ fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
+ fragColor = vertexColor;
+ fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 1.0)));
+
+ gl_Position = mvp * vec4(vertexPosition, 1.0);
+}
diff --git a/examples/others/easings_testbed.c b/examples/others/easings_testbed.c
index 31daeecee..fb3175711 100644
--- a/examples/others/easings_testbed.c
+++ b/examples/others/easings_testbed.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [easings] example - Easings Testbed
+* raylib [easings] example - easings testbed
*
* Example originally created with raylib 2.5, last time updated with raylib 2.5
*
diff --git a/examples/others/embedded_files_loading.c b/examples/others/embedded_files_loading.c
index 8a66b4394..10a094f84 100644
--- a/examples/others/embedded_files_loading.c
+++ b/examples/others/embedded_files_loading.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [others] example - Embedded files loading (Wave and Image)
+* raylib [others] example - embedded files loading
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/others/raylib_opengl_interop.c b/examples/others/raylib_opengl_interop.c
index 4dc534d12..7ca4c28b6 100644
--- a/examples/others/raylib_opengl_interop.c
+++ b/examples/others/raylib_opengl_interop.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - OpenGL point particle system
+* raylib [others] example - OpenGL interoperatibility
*
* Example complexity rating: [★★★★] 4/4
*
@@ -71,7 +71,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [shaders] example - point particles");
+ InitWindow(screenWidth, screenHeight, "raylib [others] example - OpenGL interoperatibility");
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/point_particle.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/point_particle.fs", GLSL_VERSION));
diff --git a/examples/others/raymath_vector_angle.c b/examples/others/raymath_vector_angle.c
index 1d49cec66..d98b158ed 100644
--- a/examples/others/raymath_vector_angle.c
+++ b/examples/others/raymath_vector_angle.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - Vector Angle
+* raylib [math] example - vector angle
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/others/resources/shaders/glsl100/point_particle.fs b/examples/others/resources/shaders/glsl100/point_particle.fs
index b1c5103e6..d74d457a7 100644
--- a/examples/others/resources/shaders/glsl100/point_particle.fs
+++ b/examples/others/resources/shaders/glsl100/point_particle.fs
@@ -10,7 +10,7 @@ uniform vec4 color;
void main()
{
// Each point is drawn as a screen space square of gl_PointSize size. gl_PointCoord contains where we are inside of
- // it. (0, 0) is the top left, (1, 1) the bottom right corner.
- // Draw each point as a colored circle with alpha 1.0 in the center and 0.0 at the outer edges.
- gl_FragColor = vec4(color.rgb, color.a * (1.0 - length(gl_PointCoord.xy - vec2(0.5))*2.0));
+ // it. (0, 0) is the top left, (1, 1) the bottom right corner
+ // Draw each point as a colored circle with alpha 1.0 in the center and 0.0 at the outer edges
+ gl_FragColor = vec4(color.rgb, color.a*(1.0 - length(gl_PointCoord.xy - vec2(0.5))*2.0));
}
\ No newline at end of file
diff --git a/examples/others/resources/shaders/glsl100/point_particle.vs b/examples/others/resources/shaders/glsl100/point_particle.vs
index e1c4381ad..281ef6599 100644
--- a/examples/others/resources/shaders/glsl100/point_particle.vs
+++ b/examples/others/resources/shaders/glsl100/point_particle.vs
@@ -16,9 +16,9 @@ void main()
float period = vertexPosition.z;
// Calculate final vertex position (jiggle it around a bit horizontally)
- pos += vec2(100.0, 0.0) * sin(period * currentTime);
- gl_Position = mvp * vec4(pos.x, pos.y, 0.0, 1.0);
+ pos += vec2(100.0, 0.0)*sin(period*currentTime);
+ gl_Position = mvp*vec4(pos.x, pos.y, 0.0, 1.0);
// Calculate the screen space size of this particle (also vary it over time)
- gl_PointSize = 10.0 - 5.0 * abs(sin(period * currentTime));
+ gl_PointSize = 10.0 - 5.0*abs(sin(period*currentTime));
}
\ No newline at end of file
diff --git a/examples/others/resources/shaders/glsl330/point_particle.fs b/examples/others/resources/shaders/glsl330/point_particle.fs
index c8a834f9e..456345e4b 100644
--- a/examples/others/resources/shaders/glsl330/point_particle.fs
+++ b/examples/others/resources/shaders/glsl330/point_particle.fs
@@ -11,7 +11,7 @@ out vec4 finalColor;
void main()
{
// Each point is drawn as a screen space square of gl_PointSize size. gl_PointCoord contains where we are inside of
- // it. (0, 0) is the top left, (1, 1) the bottom right corner.
- // Draw each point as a colored circle with alpha 1.0 in the center and 0.0 at the outer edges.
- finalColor = vec4(color.rgb, color.a * (1 - length(gl_PointCoord.xy - vec2(0.5))*2));
+ // it. (0, 0) is the top left, (1, 1) the bottom right corner
+ // Draw each point as a colored circle with alpha 1.0 in the center and 0.0 at the outer edges
+ finalColor = vec4(color.rgb, color.a*(1 - length(gl_PointCoord.xy - vec2(0.5))*2));
}
\ No newline at end of file
diff --git a/examples/others/resources/shaders/glsl330/point_particle.vs b/examples/others/resources/shaders/glsl330/point_particle.vs
index 1d835a9bc..90ea53836 100644
--- a/examples/others/resources/shaders/glsl330/point_particle.vs
+++ b/examples/others/resources/shaders/glsl330/point_particle.vs
@@ -16,9 +16,9 @@ void main()
float period = vertexPosition.z;
// Calculate final vertex position (jiggle it around a bit horizontally)
- pos += vec2(100, 0) * sin(period * currentTime);
- gl_Position = mvp * vec4(pos, 0.0, 1.0);
+ pos += vec2(100, 0)*sin(period*currentTime);
+ gl_Position = mvp*vec4(pos, 0.0, 1.0);
// Calculate the screen space size of this particle (also vary it over time)
- gl_PointSize = 10 - 5 * abs(sin(period * currentTime));
+ gl_PointSize = 10 - 5*abs(sin(period*currentTime));
}
\ No newline at end of file
diff --git a/examples/others/rlgl_compute_shader.c b/examples/others/rlgl_compute_shader.c
index 07a10b1d5..81b2e7db9 100644
--- a/examples/others/rlgl_compute_shader.c
+++ b/examples/others/rlgl_compute_shader.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [rlgl] example - compute shader - Conway's Game of Life
+* raylib [rlgl] example - compute shader - game of life
*
* NOTE: This example requires raylib OpenGL 4.3 versions for compute shaders support,
* shaders used in this example are #version 430 (OpenGL 4.3)
diff --git a/examples/shaders/resources/shaders/glsl100/bloom.fs b/examples/shaders/resources/shaders/glsl100/bloom.fs
index 65254a860..e0c2ecf3c 100644
--- a/examples/shaders/resources/shaders/glsl100/bloom.fs
+++ b/examples/shaders/resources/shaders/glsl100/bloom.fs
@@ -12,9 +12,9 @@ uniform vec4 colDiffuse;
// NOTE: Add your custom variables here
-const vec2 size = vec2(800, 450); // render size
-const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance
-const float quality = 2.5; // lower = smaller glow, better quality
+const vec2 size = vec2(800, 450); // Framebuffer size
+const float samples = 5.0; // Pixels per axis; higher = bigger glow, worse performance
+const float quality = 2.5; // Defines size factor: Lower = smaller glow, better quality
void main()
{
diff --git a/examples/shaders/resources/shaders/glsl100/cross_stitching.fs b/examples/shaders/resources/shaders/glsl100/cross_stitching.fs
index f43f09c84..a098794d4 100644
--- a/examples/shaders/resources/shaders/glsl100/cross_stitching.fs
+++ b/examples/shaders/resources/shaders/glsl100/cross_stitching.fs
@@ -23,8 +23,8 @@ vec4 PostFX(sampler2D tex, vec2 uv)
{
vec4 c = vec4(0.0);
float size = stitchingSize;
- vec2 cPos = uv * vec2(renderWidth, renderHeight);
- vec2 tlPos = floor(cPos / vec2(size, size));
+ vec2 cPos = uv*vec2(renderWidth, renderHeight);
+ vec2 tlPos = floor(cPos/vec2(size, size));
tlPos *= size;
int remX = int(mod(cPos.x, size));
@@ -38,11 +38,11 @@ vec4 PostFX(sampler2D tex, vec2 uv)
if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y)))))
{
if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0);
- else c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ else c = texture2D(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
}
else
{
- if (invert == 1) c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ if (invert == 1) c = texture2D(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
else c = vec4(0.0, 0.0, 0.0, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl100/cubes_panning.fs b/examples/shaders/resources/shaders/glsl100/cubes_panning.fs
index 9e5eab0fe..ea05cadff 100644
--- a/examples/shaders/resources/shaders/glsl100/cubes_panning.fs
+++ b/examples/shaders/resources/shaders/glsl100/cubes_panning.fs
@@ -16,7 +16,7 @@ float angle = 0.0;
vec2 VectorRotateTime(vec2 v, float speed)
{
float time = uTime*speed;
- float localTime = fract(time); // The time domain this works on is 1 sec.
+ float localTime = fract(time); // The time domain this works on is 1 sec
if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4.0*sin(2.0*PI*localTime - PI/2.0);
diff --git a/examples/shaders/resources/shaders/glsl100/deferred_shading.fs b/examples/shaders/resources/shaders/glsl100/deferred_shading.fs
index d782792b9..63e9c5bea 100644
--- a/examples/shaders/resources/shaders/glsl100/deferred_shading.fs
+++ b/examples/shaders/resources/shaders/glsl100/deferred_shading.fs
@@ -13,9 +13,9 @@ uniform sampler2D gAlbedoSpec;
struct Light {
int enabled;
- int type; // Unused in this demo.
+ int type; // Unused in this demo
vec3 position;
- vec3 target; // Unused in this demo.
+ vec3 target; // Unused in this demo
vec4 color;
};
@@ -38,7 +38,7 @@ void main()
for (int i = 0; i < NR_LIGHTS; ++i)
{
- if(lights[i].enabled == 0) continue;
+ if (lights[i].enabled == 0) continue;
vec3 lightDirection = lights[i].position - fragPosition;
vec3 diffuse = max(dot(normal, lightDirection), 0.0)*albedo*lights[i].color.xyz;
@@ -48,7 +48,7 @@ void main()
// Attenuation
float distance = length(lights[i].position - fragPosition);
- float attenuation = 1.0/(1.0 + LINEAR * distance + QUADRATIC*distance*distance);
+ float attenuation = 1.0/(1.0 + LINEAR*distance + QUADRATIC*distance*distance);
diffuse *= attenuation;
specular *= attenuation;
ambient += diffuse + specular;
diff --git a/examples/shaders/resources/shaders/glsl100/eratosthenes.fs b/examples/shaders/resources/shaders/glsl100/eratosthenes.fs
index 0d5fcc5a4..739d7b991 100644
--- a/examples/shaders/resources/shaders/glsl100/eratosthenes.fs
+++ b/examples/shaders/resources/shaders/glsl100/eratosthenes.fs
@@ -7,12 +7,12 @@ precision mediump float;
The Sieve of Eratosthenes -- a simple shader by ProfJski
An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
- The screen is divided into a square grid of boxes, each representing an integer value.
- Each integer is tested to see if it is a prime number. Primes are colored white.
- Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer.
+ The screen is divided into a square grid of boxes, each representing an integer value
+ Each integer is tested to see if it is a prime number. Primes are colored white
+ Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer
- You can change the scale variable to make a larger or smaller grid.
- Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers.
+ You can change the scale variable to make a larger or smaller grid
+ Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers
WARNING: If you make scale too large, your GPU may bog down!
@@ -38,7 +38,7 @@ vec4 Colorizer(float counter, float maxSize)
void main()
{
vec4 color = vec4(1.0);
- float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid.
+ float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid
float value = scale*floor(fragTexCoord.y*scale) + floor(fragTexCoord.x*scale); // Group pixels into boxes representing integer values
int valuei = int(value);
diff --git a/examples/shaders/resources/shaders/glsl100/fisheye.fs b/examples/shaders/resources/shaders/glsl100/fisheye.fs
index 161c417c1..9c136a978 100644
--- a/examples/shaders/resources/shaders/glsl100/fisheye.fs
+++ b/examples/shaders/resources/shaders/glsl100/fisheye.fs
@@ -17,22 +17,22 @@ const float PI = 3.1415926535;
void main()
{
float aperture = 178.0;
- float apertureHalf = 0.5 * aperture * (PI / 180.0);
+ float apertureHalf = 0.5*aperture*(PI/180.0);
float maxFactor = sin(apertureHalf);
vec2 uv = vec2(0.0);
- vec2 xy = 2.0 * fragTexCoord.xy - 1.0;
+ vec2 xy = 2.0*fragTexCoord.xy - 1.0;
float d = length(xy);
if (d < (2.0 - maxFactor))
{
- d = length(xy * maxFactor);
- float z = sqrt(1.0 - d * d);
- float r = atan(d, z) / PI;
+ d = length(xy*maxFactor);
+ float z = sqrt(1.0 - d*d);
+ float r = atan(d, z)/PI;
float phi = atan(xy.y, xy.x);
- uv.x = r * cos(phi) + 0.5;
- uv.y = r * sin(phi) + 0.5;
+ uv.x = r*cos(phi) + 0.5;
+ uv.y = r*sin(phi) + 0.5;
}
else
{
diff --git a/examples/shaders/resources/shaders/glsl100/hybrid_raster.fs b/examples/shaders/resources/shaders/glsl100/hybrid_raster.fs
index 28188a454..35bc75d30 100644
--- a/examples/shaders/resources/shaders/glsl100/hybrid_raster.fs
+++ b/examples/shaders/resources/shaders/glsl100/hybrid_raster.fs
@@ -1,4 +1,5 @@
-#version 100
+#version 100
+
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
@@ -11,6 +12,7 @@ uniform vec4 colDiffuse;
void main()
{
vec4 texelColor = texture2D(texture0, fragTexCoord);
+
gl_FragColor = texelColor*colDiffuse*fragColor;
- gl_FragDepthEXT = gl_FragCoord.z;
+ gl_FragDepthEXT = gl_FragCoord.z;
}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs b/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs
index 6241186de..44233b3bb 100644
--- a/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs
+++ b/examples/shaders/resources/shaders/glsl100/hybrid_raymarch.fs
@@ -1,9 +1,9 @@
-#version 100
+#version 100
+
#extension GL_EXT_frag_depth : enable //Extension required for writing depth
#extension GL_OES_standard_derivatives : enable //Extension used for fwidth()
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
-
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
@@ -19,21 +19,22 @@ uniform vec2 screenCenter;
#define ZERO 0
-// https://learnopengl.com/Advanced-OpenGL/Depth-testing
-float CalcDepth(in vec3 rd, in float Idist){
+// SRC: https://learnopengl.com/Advanced-OpenGL/Depth-testing
+float CalcDepth(in vec3 rd, in float Idist)
+{
float local_z = dot(normalize(camDir),rd)*Idist;
return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01);
}
-// https://iquilezles.org/articles/distfunctions/
-float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w )
+// SRC: https://iquilezles.org/articles/distfunctions/
+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,
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.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);
@@ -44,67 +45,70 @@ float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w )
// r = sphere's radius
// h = cutting's plane's position
// t = thickness
-float sdSixWayCutHollowSphere( vec3 p, float r, float h, float t )
+float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
{
// Six way symetry Transformation
vec3 ap = abs(p);
- if(ap.x < max(ap.y, ap.z)){
- if(ap.y < ap.z) ap.xz = ap.zx;
+ if (ap.x < max(ap.y, ap.z)){
+ if (ap.y < ap.z) ap.xz = ap.zx;
else ap.xy = ap.yx;
}
- vec2 q = vec2( length(ap.yz), ap.x );
+ vec2 q = vec2(length(ap.yz), ap.x);
float w = sqrt(r*r-h*h);
- return ((h*q.x0.0 )
+ if (tp1>0.0)
{
- tmax = min( tmax, tp1 );
- res = vec2( tp1, 1.0 );
+ tmax = min(tmax, tp1);
+ res = vec2(tp1, 1.0);
}
float t = tmin;
- for( int i=0; i<70 ; i++ )
+ for (int i=0; i<70 ; i++)
{
- if(t>tmax) break;
- vec2 h = map( ro+rd*t );
- if( abs(h.x)<(0.0001*t) )
+ if (t>tmax) break;
+ vec2 h = map(ro+rd*t);
+ if (abs(h.x) < (0.0001*t))
{
res = vec2(t,h.y);
break;
@@ -117,54 +121,54 @@ vec2 raycast( in vec3 ro, in vec3 rd ){
// https://iquilezles.org/articles/rmshadows
-float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
+float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{
// bounding volume
- float tp = (0.8-ro.y)/rd.y; if( tp>0.0 ) tmax = min( tmax, tp );
+ float tp = (0.8-ro.y)/rd.y; if (tp>0.0) tmax = min(tmax, tp);
float res = 1.0;
float t = mint;
- for( int i=ZERO; i<24; i++ )
+ for (int i=ZERO; i<24; i++)
{
- float h = map( ro + rd*t ).x;
+ float h = map(ro + rd*t).x;
float s = clamp(8.0*h/t,0.0,1.0);
- res = min( res, s );
- t += clamp( h, 0.01, 0.2 );
- if( res<0.004 || t>tmax ) break;
+ res = min(res, s);
+ t += clamp(h, 0.01, 0.2);
+ if (res<0.004 || t>tmax) break;
}
- res = clamp( res, 0.0, 1.0 );
+ res = clamp(res, 0.0, 1.0);
return res*res*(3.0-2.0*res);
}
// https://iquilezles.org/articles/normalsSDF
-vec3 calcNormal( in vec3 pos )
+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 +
- e.xxx*map( pos + e.xxx ).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);
}
// https://iquilezles.org/articles/nvscene2008/rwwtt.pdf
-float calcAO( in vec3 pos, in vec3 nor )
+float calcAO(in vec3 pos, in vec3 nor)
{
- float occ = 0.0;
+ float occ = 0.0;
float sca = 1.0;
- for( int i=ZERO; i<5; i++ )
+ for (int i=ZERO; i<5; i++)
{
float h = 0.01 + 0.12*float(i)/4.0;
- float d = map( pos + h*nor ).x;
+ float d = map(pos + h*nor).x;
occ += (h-d)*sca;
sca *= 0.95;
- if( occ>0.35 ) break;
+ if (occ>0.35) break;
}
- return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ) * (0.5+0.5*nor.y);
+ return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y);
}
// https://iquilezles.org/articles/checkerfiltering
-float checkersGradBox( in vec2 p )
+float checkersGradBox(in vec2 p)
{
// filter kernel
vec2 w = fwidth(p) + 0.001;
@@ -175,7 +179,7 @@ float checkersGradBox( in vec2 p )
}
// https://www.shadertoy.com/view/tdS3DG
-vec4 render( in vec3 ro, in vec3 rd)
+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;
@@ -183,37 +187,37 @@ vec4 render( in vec3 ro, in vec3 rd)
// raycast scene
vec2 res = raycast(ro,rd);
float t = res.x;
- float m = res.y;
- if( m>-0.5 )
+ float m = res.y;
+ if (m>-0.5)
{
vec3 pos = ro + t*rd;
- vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos );
- vec3 ref = reflect( rd, nor );
+ vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
+ vec3 ref = reflect(rd, nor);
// material
- col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) );
+ col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
float ks = 1.0;
- if( m<1.5 )
+ if (m<1.5)
{
- float f = checkersGradBox( 3.0*pos.xz);
+ float f = checkersGradBox(3.0*pos.xz);
col = 0.15 + f*vec3(0.05);
ks = 0.4;
}
// lighting
- float occ = calcAO( pos, nor );
+ float occ = calcAO(pos, nor);
- vec3 lin = vec3(0.0);
+ vec3 lin = vec3(0.0);
// sun
{
- vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) );
- vec3 hal = normalize( lig-rd );
- float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
- //if( dif>0.0001 )
- dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
- float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0);
+ vec3 lig = normalize(vec3(-0.5, 0.4, -0.6));
+ vec3 hal = normalize(lig-rd);
+ float dif = clamp(dot(nor, lig), 0.0, 1.0);
+ //if (dif>0.0001)
+ dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
+ float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0);
spe *= dif;
spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
//spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0);
@@ -222,35 +226,35 @@ vec4 render( in vec3 ro, in vec3 rd)
}
// sky
{
- float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 ));
+ float dif = sqrt(clamp(0.5+0.5*nor.y, 0.0, 1.0));
dif *= occ;
- float spe = smoothstep( -0.2, 0.2, ref.y );
+ float spe = smoothstep(-0.2, 0.2, ref.y);
spe *= dif;
- spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 );
- //if( spe>0.001 )
- spe *= calcSoftshadow( pos, ref, 0.02, 2.5 );
+ spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0);
+ //if (spe>0.001)
+ spe *= calcSoftshadow(pos, ref, 0.02, 2.5);
lin += col*0.60*dif*vec3(0.40,0.60,1.15);
lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks;
}
// back
{
- float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
+ float dif = clamp(dot(nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
dif *= occ;
- lin += col*0.55*dif*vec3(0.25,0.25,0.25);
+ lin += col*0.55*dif*vec3(0.25,0.25,0.25);
}
// sss
{
float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0);
dif *= occ;
- lin += col*0.25*dif*vec3(1.00,1.00,1.00);
+ lin += col*0.25*dif*vec3(1.00,1.00,1.00);
}
- col = lin;
+ col = lin;
- col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) );
+ col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
}
- return vec4(vec3( clamp(col,0.0,1.0) ),t);
+ return vec4(vec3(clamp(col,0.0,1.0)),t);
}
vec3 CalcRayDir(vec2 nCoord){
@@ -261,11 +265,11 @@ vec3 CalcRayDir(vec2 nCoord){
mat3 setCamera()
{
- vec3 cw = normalize(camDir);
- vec3 cp = vec3(0.0, 1.0 ,0.0);
- vec3 cu = normalize( cross(cw,cp) );
- vec3 cv = ( cross(cu,cw) );
- return mat3( cu, cv, cw );
+ vec3 cw = normalize(camDir);
+ vec3 cp = vec3(0.0, 1.0 ,0.0);
+ vec3 cu = normalize(cross(cw,cp));
+ vec3 cv = (cross(cu,cw));
+ return mat3(cu, cv, cw);
}
void main()
@@ -275,14 +279,14 @@ void main()
// focal length
float fl = length(camDir);
- vec3 rd = ca * normalize( vec3(nCoord,fl) );
+ vec3 rd = ca*normalize(vec3(nCoord,fl));
vec3 color = vec3(nCoord/2.0 + 0.5, 0.0);
float depth = gl_FragCoord.z;
{
- vec4 res = render( camPos - vec3(0.0, 0.0, 0.0) , rd );
+ vec4 res = render(camPos - vec3(0.0, 0.0, 0.0) , rd);
color = res.xyz;
depth = CalcDepth(rd,res.w);
}
gl_FragColor = vec4(color , 1.0);
- gl_FragDepthEXT = depth;
+ gl_FragDepthEXT = depth;
}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl100/julia_set.fs b/examples/shaders/resources/shaders/glsl100/julia_set.fs
index 9ee8c6f4d..a6f397926 100644
--- a/examples/shaders/resources/shaders/glsl100/julia_set.fs
+++ b/examples/shaders/resources/shaders/glsl100/julia_set.fs
@@ -7,13 +7,13 @@ varying vec2 fragTexCoord;
varying vec4 fragColor;
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
-uniform vec2 offset; // Offset of the scale.
-uniform float zoom; // Zoom of the scale.
+uniform vec2 offset; // Offset of the scale
+uniform float zoom; // Zoom of the scale
// NOTE: Maximum number of shader for-loop iterations depend on GPU,
// for example, on RasperryPi for this examply only supports up to 60
-const int maxIterations = 48; // Max iterations to do.
-const float colorCycles = 1.0; // Number of times the color palette repeats.
+const int maxIterations = 255; // Max iterations to do.
+const float colorCycles = 1.0; // Number of times the color palette repeats.
// Square a complex number
vec2 ComplexSquare(vec2 z)
@@ -32,22 +32,22 @@ vec3 Hsv2rgb(vec3 c)
void main()
{
/**********************************************************************************************
- Julia sets use a function z^2 + c, where c is a constant.
- This function is iterated until the nature of the point is determined.
+ Julia sets use a function z^2 + c, where c is a constant
+ This function is iterated until the nature of the point is determined
If the magnitude of the number becomes greater than 2, then from that point onward
- the number will get bigger and bigger, and will never get smaller (tends towards infinity).
- 2^2 = 4, 4^2 = 8 and so on.
- So at 2 we stop iterating.
+ the number will get bigger and bigger, and will never get smaller (tends towards infinity)
+ 2^2 = 4, 4^2 = 8 and so on
+ So at 2 we stop iterating
- If the number is below 2, we keep iterating.
+ If the number is below 2, we keep iterating
But when do we stop iterating if the number is always below 2 (it converges)?
- That is what maxIterations is for.
- Then we can divide the iterations by the maxIterations value to get a normalized value that we can
- then map to a color.
+ That is what maxIterations is for
+ Then we can divide the iterations by the maxIterations value to get a normalized value
+ that we can then map to a color
- We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
- And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power).
+ We use dot product (z.x*z.x + z.y*z.y) to determine the magnitude (length) squared
+ And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power)
*************************************************************************************************/
// The pixel coordinates are scaled so they are on the mandelbrot scale
@@ -57,7 +57,7 @@ void main()
z.y += offset.y;
int iter = 0;
- for (int iterations = 0; iterations < 60; iterations++)
+ for (int iterations = 0; iterations < maxIterations; iterations++)
{
z = ComplexSquare(z) + c; // Iterate function
if (dot(z, z) > 4.0) break;
@@ -65,18 +65,18 @@ void main()
iter = iterations;
}
- // Another few iterations decreases errors in the smoothing calculation.
- // See http://linas.org/art-gallery/escape/escape.html for more information.
+ // Another few iterations decreases errors in the smoothing calculation
+ // See http://linas.org/art-gallery/escape/escape.html for more information
z = ComplexSquare(z) + c;
z = ComplexSquare(z) + c;
- // This last part smooths the color (again see link above).
+ // This last part smooths the color (again see link above)
float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0));
- // Normalize the value so it is between 0 and 1.
+ // Normalize the value so it is between 0 and 1
float norm = smoothVal/float(maxIterations);
- // If in set, color black. 0.999 allows for some float accuracy error.
+ // If in set, color black. 0.999 allows for some float accuracy error
if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
else gl_FragColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0, 1.0)), 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl100/lighting.fs b/examples/shaders/resources/shaders/glsl100/lighting.fs
index 596da0f6f..e36eb7ac0 100644
--- a/examples/shaders/resources/shaders/glsl100/lighting.fs
+++ b/examples/shaders/resources/shaders/glsl100/lighting.fs
@@ -40,7 +40,7 @@ void main()
vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0);
- vec4 tint = colDiffuse * fragColor;
+ vec4 tint = colDiffuse*fragColor;
// NOTE: Implement here your fragment shader code
diff --git a/examples/shaders/resources/shaders/glsl100/lightmap.fs b/examples/shaders/resources/shaders/glsl100/lightmap.fs
index 9f0bcd27b..70ecad61b 100644
--- a/examples/shaders/resources/shaders/glsl100/lightmap.fs
+++ b/examples/shaders/resources/shaders/glsl100/lightmap.fs
@@ -18,5 +18,5 @@ void main()
vec4 texelColor = texture2D(texture0, fragTexCoord);
vec4 texelColor2 = texture2D(texture1, fragTexCoord2);
- gl_FragColor = texelColor * texelColor2;
+ gl_FragColor = texelColor*texelColor2;
}
diff --git a/examples/shaders/resources/shaders/glsl100/normalmap.fs b/examples/shaders/resources/shaders/glsl100/normalmap.fs
index 02902a61f..197e81ed1 100644
--- a/examples/shaders/resources/shaders/glsl100/normalmap.fs
+++ b/examples/shaders/resources/shaders/glsl100/normalmap.fs
@@ -34,21 +34,21 @@ void main()
normal = texture(normalMap, vec2(fragTexCoord.x, fragTexCoord.y)).rgb;
//Transform normal values to the range -1.0 ... 1.0
- normal = normalize(normal * 2.0 - 1.0);
+ normal = normalize(normal*2.0 - 1.0);
//Transform the normal from tangent-space to world-space for lighting calculation
- normal = normalize(normal * TBN);
+ normal = normalize(normal*TBN);
}
else
{
normal = normalize(fragNormal);
}
- vec4 tint = colDiffuse * fragColor;
+ vec4 tint = colDiffuse*fragColor;
vec3 lightColor = vec3(1.0, 1.0, 1.0);
float NdotL = max(dot(normal, lightDir), 0.0);
- vec3 lightDot = lightColor * NdotL;
+ vec3 lightDot = lightColor*NdotL;
float specCo = 0.0;
@@ -56,9 +56,9 @@ void main()
specular += specCo;
- finalColor = (texelColor * ((tint + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
- finalColor += texelColor * (vec4(1.0, 1.0, 1.0, 1.0) / 40.0) * tint;
+ finalColor = (texelColor*((tint + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
+ finalColor += texelColor*(vec4(1.0, 1.0, 1.0, 1.0)/40.0)*tint;
// Gamma correction
- gl_FragColor = pow(finalColor, vec4(1.0 / 2.2));
+ gl_FragColor = pow(finalColor, vec4(1.0/2.2));
}
diff --git a/examples/shaders/resources/shaders/glsl100/normalmap.vs b/examples/shaders/resources/shaders/glsl100/normalmap.vs
index 072e0a6c2..0426653ef 100644
--- a/examples/shaders/resources/shaders/glsl100/normalmap.vs
+++ b/examples/shaders/resources/shaders/glsl100/normalmap.vs
@@ -27,15 +27,15 @@ mat3 inverse(mat3 m)
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
- float b01 = a22 * a11 - a12 * a21;
- float b11 = -a22 * a10 + a12 * a20;
- float b21 = a21 * a10 - a11 * a20;
+ float b01 = a22*a11 - a12*a21;
+ float b11 = -a22*a10 + a12*a20;
+ float b21 = a21*a10 - a11*a20;
- float det = a00 * b01 + a01 * b11 + a02 * b21;
+ float det = a00*b01 + a01*b11 + a02*b21;
- return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),
- b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),
- b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;
+ return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
+ b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
+ b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
}
// https://github.com/glslify/glsl-transpose
@@ -49,21 +49,21 @@ mat3 transpose(mat3 m)
void main()
{
// Compute binormal from vertex normal and tangent. W component is the tangent handedness
- vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
+ vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz)*vertexTangent.w;
// Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Compute fragment position based on model transformations
- fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
+ fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
//Create TBN matrix for transforming the normal map values from tangent-space to world-space
- fragNormal = normalize(normalMatrix * vertexNormal);
+ fragNormal = normalize(normalMatrix*vertexNormal);
- vec3 fragTangent = normalize(normalMatrix * vertexTangent.xyz);
- fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal) * fragNormal);
+ vec3 fragTangent = normalize(normalMatrix*vertexTangent.xyz);
+ fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
- vec3 fragBinormal = normalize(normalMatrix * vertexBinormal);
+ vec3 fragBinormal = normalize(normalMatrix*vertexBinormal);
fragBinormal = cross(fragNormal, fragTangent);
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
@@ -72,5 +72,5 @@ void main()
fragTexCoord = vertexTexCoord;
- gl_Position = mvp * vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl100/pbr.vs b/examples/shaders/resources/shaders/glsl100/pbr.vs
index baf003842..1bd6e0e9f 100644
--- a/examples/shaders/resources/shaders/glsl100/pbr.vs
+++ b/examples/shaders/resources/shaders/glsl100/pbr.vs
@@ -52,7 +52,7 @@ mat3 transpose(mat3 m)
void main()
{
// Compute binormal from vertex normal and tangent
- vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
+ vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz)*vertexTangent.w;
// Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
diff --git a/examples/shaders/resources/shaders/glsl100/raymarching.fs b/examples/shaders/resources/shaders/glsl100/raymarching.fs
index a7339d216..ce9a2faca 100644
--- a/examples/shaders/resources/shaders/glsl100/raymarching.fs
+++ b/examples/shaders/resources/shaders/glsl100/raymarching.fs
@@ -34,7 +34,7 @@ uniform vec2 resolution;
// SOFTWARE.
// A list of useful distance function to simple primitives, and an example on how to
-// do some interesting boolean operations, repetition and displacement.
+// do some interesting boolean operations, repetition and displacement
//
// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
@@ -42,38 +42,38 @@ uniform vec2 resolution;
//------------------------------------------------------------------
-float sdPlane( vec3 p )
+float sdPlane(vec3 p)
{
return p.y;
}
-float sdSphere( vec3 p, float s )
+float sdSphere(vec3 p, float s)
{
return length(p)-s;
}
-float sdBox( vec3 p, vec3 b )
+float sdBox(vec3 p, vec3 b)
{
vec3 d = abs(p) - b;
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}
-float sdEllipsoid( in vec3 p, in vec3 r )
+float sdEllipsoid(in vec3 p, in vec3 r)
{
- return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z);
+ return (length(p/r) - 1.0)*min(min(r.x,r.y),r.z);
}
-float udRoundBox( vec3 p, vec3 b, float r )
+float udRoundBox(vec3 p, vec3 b, float r)
{
return length(max(abs(p)-b,0.0))-r;
}
-float sdTorus( vec3 p, vec2 t )
+float sdTorus(vec3 p, vec2 t)
{
- return length( vec2(length(p.xz)-t.x,p.y) )-t.y;
+ return length(vec2(length(p.xz)-t.x,p.y))-t.y;
}
-float sdHexPrism( vec3 p, vec2 h )
+float sdHexPrism(vec3 p, vec2 h)
{
vec3 q = abs(p);
#if 0
@@ -85,24 +85,24 @@ float sdHexPrism( vec3 p, vec2 h )
#endif
}
-float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
+float sdCapsule(vec3 p, vec3 a, vec3 b, float r)
{
vec3 pa = p-a, ba = b-a;
- float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
- return length( pa - ba*h ) - r;
+ float h = clamp(dot(pa,ba)/dot(ba,ba), 0.0, 1.0);
+ return length(pa - ba*h) - r;
}
-float sdEquilateralTriangle( in vec2 p )
+float sdEquilateralTriangle( in vec2 p)
{
const float k = sqrt(3.0);
p.x = abs(p.x) - 1.0;
p.y = p.y + 1.0/k;
- if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0;
- p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 );
+ if (p.x + k*p.y > 0.0) p = vec2(p.x - k*p.y, -k*p.x - p.y)/2.0;
+ p.x += 2.0 - 2.0*clamp((p.x+2.0)/2.0, 0.0, 1.0);
return -length(p)*sign(p.y);
}
-float sdTriPrism( vec3 p, vec2 h )
+float sdTriPrism(vec3 p, vec2 h)
{
vec3 q = abs(p);
float d1 = q.z-h.y;
@@ -117,95 +117,95 @@ float sdTriPrism( vec3 p, vec2 h )
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdCylinder( vec3 p, vec2 h )
+float sdCylinder(vec3 p, vec2 h)
{
vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
-float sdCone( in vec3 p, in vec3 c )
+float sdCone(in vec3 p, in vec3 c)
{
- vec2 q = vec2( length(p.xz), p.y );
+ vec2 q = vec2(length(p.xz), p.y);
float d1 = -q.y-c.z;
- float d2 = max( dot(q,c.xy), q.y);
+ float d2 = max(dot(q,c.xy), q.y);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdConeSection( in vec3 p, in float h, in float r1, in float r2 )
+float sdConeSection(in vec3 p, in float h, in float r1, in float r2)
{
float d1 = -p.y - h;
float q = p.y - h;
float si = 0.5*(r1-r2)/h;
- float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q );
+ float d2 = max(sqrt(dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height }
+float sdPryamid4(vec3 p, vec3 h) // h = { cos a, sin a, height }
{
// Tetrahedron = Octahedron - Cube
- float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) );
+ float box = sdBox(p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z));
float d = 0.0;
- d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) ));
- d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) ));
- d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) ));
- d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) ));
+ d = max(d, abs(dot(p, vec3(-h.x, h.y, 0))));
+ d = max(d, abs(dot(p, vec3( h.x, h.y, 0))));
+ d = max(d, abs(dot(p, vec3( 0, h.y, h.x))));
+ d = max(d, abs(dot(p, vec3( 0, h.y,-h.x))));
float octa = d - h.z;
return max(-box,octa); // Subtraction
}
-float length2( vec2 p )
+float length2(vec2 p)
{
- return sqrt( p.x*p.x + p.y*p.y );
+ return sqrt(p.x*p.x + p.y*p.y);
}
-float length6( vec2 p )
+float length6(vec2 p)
{
p = p*p*p; p = p*p;
- return pow( p.x + p.y, 1.0/6.0 );
+ return pow(p.x + p.y, 1.0/6.0);
}
-float length8( vec2 p )
+float length8(vec2 p)
{
p = p*p; p = p*p; p = p*p;
- return pow( p.x + p.y, 1.0/8.0 );
+ return pow(p.x + p.y, 1.0/8.0);
}
-float sdTorus82( vec3 p, vec2 t )
+float sdTorus82(vec3 p, vec2 t)
{
vec2 q = vec2(length2(p.xz)-t.x,p.y);
return length8(q)-t.y;
}
-float sdTorus88( vec3 p, vec2 t )
+float sdTorus88(vec3 p, vec2 t)
{
vec2 q = vec2(length8(p.xz)-t.x,p.y);
return length8(q)-t.y;
}
-float sdCylinder6( vec3 p, vec2 h )
+float sdCylinder6(vec3 p, vec2 h)
{
- return max( length6(p.xz)-h.x, abs(p.y)-h.y );
+ return max(length6(p.xz)-h.x, abs(p.y)-h.y);
}
//------------------------------------------------------------------
-float opS( float d1, float d2 )
+float opS(float d1, float d2)
{
return max(-d2,d1);
}
-vec2 opU( vec2 d1, vec2 d2 )
+vec2 opU(vec2 d1, vec2 d2)
{
return (d1.x0.0 ) tmax = min( tmax, tp1 );
- float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 );
- else tmax = min( tmax, tp2 ); }
+ float tp1 = (0.0-ro.y)/rd.y; if (tp1>0.0) tmax = min(tmax, tp1);
+ float tp2 = (1.6-ro.y)/rd.y; if (tp2>0.0) { if (ro.y>1.6) tmin = max(tmin, tp2);
+ else tmax = min(tmax, tp2); }
#endif
float t = tmin;
float m = -1.0;
- for( int i=0; i<64; i++ )
+ for (int i=0; i<64; i++)
{
float precis = 0.0005*t;
- vec2 res = map( ro+rd*t );
- if( res.xtmax ) break;
+ vec2 res = map(ro+rd*t);
+ if (res.xtmax) break;
t += res.x;
m = res.y;
}
- if( t>tmax ) m=-1.0;
- return vec2( t, m );
+ if (t>tmax) m=-1.0;
+ return vec2(t, m);
}
-float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
+float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{
float res = 1.0;
float t = mint;
- for( int i=0; i<16; i++ )
+ for (int i=0; i<16; i++)
{
- float h = map( ro + rd*t ).x;
- res = min( res, 8.0*h/t );
- t += clamp( h, 0.02, 0.10 );
- if( h<0.001 || t>tmax ) break;
+ float h = map(ro + rd*t).x;
+ res = min(res, 8.0*h/t);
+ t += clamp(h, 0.02, 0.10);
+ if (h<0.001 || t>tmax) break;
}
- return clamp( res, 0.0, 1.0 );
+ return clamp(res, 0.0, 1.0);
}
-vec3 calcNormal( in vec3 pos )
+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 +
- e.xxx*map( pos + e.xxx ).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);
/*
- vec3 eps = vec3( 0.0005, 0.0, 0.0 );
+ vec3 eps = vec3(0.0005, 0.0, 0.0);
vec3 nor = vec3(
map(pos+eps.xyy).x - map(pos-eps.xyy).x,
map(pos+eps.yxy).x - map(pos-eps.yxy).x,
- map(pos+eps.yyx).x - map(pos-eps.yyx).x );
+ map(pos+eps.yyx).x - map(pos-eps.yyx).x);
return normalize(nor);
*/
}
-float calcAO( in vec3 pos, in vec3 nor )
+float calcAO(in vec3 pos, in vec3 nor)
{
float occ = 0.0;
float sca = 1.0;
- for( int i=0; i<5; i++ )
+ for (int i=0; i<5; i++)
{
float hr = 0.01 + 0.12*float(i)/4.0;
- vec3 aopos = nor * hr + pos;
- float dd = map( aopos ).x;
+ vec3 aopos = nor*hr + pos;
+ float dd = map(aopos).x;
occ += -(dd-hr)*sca;
sca *= 0.95;
}
- return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
+ return clamp(1.0 - 3.0*occ, 0.0, 1.0);
}
// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm
-float checkersGradBox( in vec2 p )
+float checkersGradBox(in vec2 p)
{
// filter kernel
vec2 w = fwidth(p) + 0.001;
@@ -328,43 +328,43 @@ float checkersGradBox( in vec2 p )
return 0.5 - 0.5*i.x*i.y;
}
-vec3 render( in vec3 ro, in vec3 rd )
+vec3 render(in vec3 ro, in vec3 rd)
{
vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
vec2 res = castRay(ro,rd);
float t = res.x;
float m = res.y;
- if( m>-0.5 )
+ if (m>-0.5)
{
vec3 pos = ro + t*rd;
- vec3 nor = calcNormal( pos );
- vec3 ref = reflect( rd, nor );
+ vec3 nor = calcNormal(pos);
+ vec3 ref = reflect(rd, nor);
// material
- col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) );
- if( m<1.5 )
+ col = 0.45 + 0.35*sin(vec3(0.05,0.08,0.10)*(m-1.0));
+ if (m<1.5)
{
- float f = checkersGradBox( 5.0*pos.xz );
+ float f = checkersGradBox(5.0*pos.xz);
col = 0.3 + f*vec3(0.1);
}
// lighting
- float occ = calcAO( pos, nor );
- vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) );
- vec3 hal = normalize( lig-rd );
- float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
- float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
- float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
- float dom = smoothstep( -0.1, 0.1, ref.y );
- float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
+ float occ = calcAO(pos, nor);
+ vec3 lig = normalize(vec3(cos(-0.4*runTime), sin(0.7*runTime), -0.6));
+ vec3 hal = normalize(lig-rd);
+ float amb = clamp(0.5+0.5*nor.y, 0.0, 1.0);
+ float dif = clamp(dot(nor, lig), 0.0, 1.0);
+ float bac = clamp(dot(nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
+ float dom = smoothstep(-0.1, 0.1, ref.y);
+ float fre = pow(clamp(1.0+dot(nor,rd),0.0,1.0), 2.0);
- dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
- dom *= calcSoftshadow( pos, ref, 0.02, 2.5 );
+ dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
+ dom *= calcSoftshadow(pos, ref, 0.02, 2.5);
- float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)*
+ float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0)*
dif *
- (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 ));
+ (0.04 + 0.96*pow(clamp(1.0+dot(hal,rd),0.0,1.0), 5.0));
vec3 lin = vec3(0.0);
lin += 1.30*dif*vec3(1.00,0.80,0.55);
@@ -375,51 +375,51 @@ vec3 render( in vec3 ro, in vec3 rd )
col = col*lin;
col += 10.00*spe*vec3(1.00,0.90,0.70);
- col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );
+ col = mix(col, vec3(0.8,0.9,1.0), 1.0-exp(-0.0002*t*t*t));
}
- return vec3( clamp(col,0.0,1.0) );
+ return vec3(clamp(col,0.0,1.0));
}
-mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
+mat3 setCamera(in vec3 ro, in vec3 ta, float cr)
{
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
- vec3 cu = normalize( cross(cw,cp) );
- vec3 cv = normalize( cross(cu,cw) );
- return mat3( cu, cv, cw );
+ vec3 cu = normalize(cross(cw,cp));
+ vec3 cv = normalize(cross(cu,cw));
+ return mat3(cu, cv, cw);
}
void main()
{
vec3 tot = vec3(0.0);
#if AA>1
- for( int m=0; m1
@@ -427,5 +427,5 @@ void main()
tot /= float(AA*AA);
#endif
- gl_FragColor = vec4( tot, 1.0 );
+ gl_FragColor = vec4(tot, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl100/rounded_rectangle.fs b/examples/shaders/resources/shaders/glsl100/rounded_rectangle.fs
index 3c8d07978..f714859de 100644
--- a/examples/shaders/resources/shaders/glsl100/rounded_rectangle.fs
+++ b/examples/shaders/resources/shaders/glsl100/rounded_rectangle.fs
@@ -1,9 +1,9 @@
-// Note: SDF by Iñigo Quilez is licensed under MIT License
-
#version 100
precision mediump float;
+// NOTE: SDF by Iñigo Quilez, licensed under MIT License
+
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
diff --git a/examples/shaders/resources/shaders/glsl100/scanlines.fs b/examples/shaders/resources/shaders/glsl100/scanlines.fs
index debfc7623..3d55b3fe5 100644
--- a/examples/shaders/resources/shaders/glsl100/scanlines.fs
+++ b/examples/shaders/resources/shaders/glsl100/scanlines.fs
@@ -35,7 +35,7 @@ void main()
fragColor = color;
*/
// Scanlines method 2
- float globalPos = (fragTexCoord.y + offset) * frequency;
+ float globalPos = (fragTexCoord.y + offset)*frequency;
float wavePos = cos((fract(globalPos) - 0.5)*3.14);
vec4 color = texture2D(texture0, fragTexCoord);
diff --git a/examples/shaders/resources/shaders/glsl100/shadowmap.fs b/examples/shaders/resources/shaders/glsl100/shadowmap.fs
new file mode 100644
index 000000000..7a0e806a5
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/shadowmap.fs
@@ -0,0 +1,86 @@
+#version 100
+
+precision mediump float;
+
+// This shader is based on the basic lighting shader
+// This only supports one light, which is directional, and it (of course) supports shadows
+
+// Input vertex attributes (from vertex shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+//varying in vec4 fragColor;
+varying vec3 fragNormal;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// Input lighting values
+uniform vec3 lightDir;
+uniform vec4 lightColor;
+uniform vec4 ambient;
+uniform vec3 viewPos;
+
+// Input shadowmapping values
+uniform mat4 lightVP; // Light source view-projection matrix
+uniform sampler2D shadowMap;
+
+uniform int shadowMapResolution;
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor = texture2D(texture0, fragTexCoord);
+ vec3 lightDot = vec3(0.0);
+ vec3 normal = normalize(fragNormal);
+ vec3 viewD = normalize(viewPos - fragPosition);
+ vec3 specular = vec3(0.0);
+
+ vec3 l = -lightDir;
+
+ float NdotL = max(dot(normal, l), 0.0);
+ lightDot += lightColor.rgb*NdotL;
+
+ float specCo = 0.0;
+ if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(l), normal))), 16.0); // 16 refers to shine
+ specular += specCo;
+
+ vec4 finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
+
+ // Shadow calculations
+ vec4 fragPosLightSpace = lightVP*vec4(fragPosition, 1);
+ fragPosLightSpace.xyz /= fragPosLightSpace.w; // Perform the perspective division
+ fragPosLightSpace.xyz = (fragPosLightSpace.xyz + 1.0)/2.0; // Transform from [-1, 1] range to [0, 1] range
+ vec2 sampleCoords = fragPosLightSpace.xy;
+ float curDepth = fragPosLightSpace.z;
+
+ // Slope-scale depth bias: depth biasing reduces "shadow acne" artifacts, where dark stripes appear all over the scene
+ // The solution is adding a small bias to the depth
+ // In this case, the bias is proportional to the slope of the surface, relative to the light
+ 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
+ // This blurs shadow edges, hiding aliasing artifacts
+ vec2 texelSize = vec2(1.0/float(shadowMapResolution));
+ for (int x = -1; x <= 1; x++)
+ {
+ for (int y = -1; y <= 1; y++)
+ {
+ float sampleDepth = texture2D(shadowMap, sampleCoords + texelSize*vec2(x, y)).r;
+ 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
+ finalColor += texelColor*(ambient/10.0)*colDiffuse;
+
+ // Gamma correction
+ finalColor = pow(finalColor, vec4(1.0/2.2));
+ gl_FragColor = finalColor;
+}
diff --git a/examples/shaders/resources/shaders/glsl100/shadowmap.vs b/examples/shaders/resources/shaders/glsl100/shadowmap.vs
new file mode 100644
index 000000000..0fb4d476f
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl100/shadowmap.vs
@@ -0,0 +1,32 @@
+#version 100
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+// Input uniform values
+uniform mat4 mvp;
+uniform mat4 matModel;
+uniform mat4 matNormal;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+// NOTE: Add your custom variables here
+
+void main()
+{
+ // Send vertex attributes to fragment shader
+ fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
+
+ // Calculate final vertex position
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
+}
diff --git a/examples/shaders/resources/shaders/glsl100/sobel.fs b/examples/shaders/resources/shaders/glsl100/sobel.fs
index f8f5b95bc..e0eb06129 100644
--- a/examples/shaders/resources/shaders/glsl100/sobel.fs
+++ b/examples/shaders/resources/shaders/glsl100/sobel.fs
@@ -20,10 +20,10 @@ void main()
vec4 horizEdge = vec4(0.0);
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
- horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
+ horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
- horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
+ horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0);
diff --git a/examples/shaders/resources/shaders/glsl100/vertex_displacement.fs b/examples/shaders/resources/shaders/glsl100/vertex_displacement.fs
index 3328a91e7..c479e02a4 100644
--- a/examples/shaders/resources/shaders/glsl100/vertex_displacement.fs
+++ b/examples/shaders/resources/shaders/glsl100/vertex_displacement.fs
@@ -6,7 +6,6 @@ precision mediump float;
varying vec2 fragTexCoord;
varying float height;
-
void main()
{
vec4 darkblue = vec4(0.0, 0.13, 0.18, 1.0);
diff --git a/examples/shaders/resources/shaders/glsl100/vertex_displacement.vs b/examples/shaders/resources/shaders/glsl100/vertex_displacement.vs
index c7b926d4b..b83b6e966 100644
--- a/examples/shaders/resources/shaders/glsl100/vertex_displacement.vs
+++ b/examples/shaders/resources/shaders/glsl100/vertex_displacement.vs
@@ -23,23 +23,23 @@ varying float height;
void main()
{
// Calculate animated texture coordinates based on time and vertex position
- vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x * 0.1), cos(time + vertexPosition.z * 0.1)) * 0.3);
+ vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x*0.1), cos(time + vertexPosition.z*0.1))*0.3);
// Normalize animated texture coordinates to range [0, 1]
- animatedTexCoord = animatedTexCoord * 0.5 + 0.5;
+ animatedTexCoord = animatedTexCoord*0.5 + 0.5;
// Fetch displacement from the perlin noise map
- float displacement = texture2D(perlinNoiseMap, animatedTexCoord).r * 7.0; // Amplified displacement
+ float displacement = texture2D(perlinNoiseMap, animatedTexCoord).r*7.0; // Amplified displacement
// Displace vertex position
vec3 displacedPosition = vertexPosition + vec3(0.0, displacement, 0.0);
// Send vertex attributes to fragment shader
- fragPosition = vec3(matModel * vec4(displacedPosition, 1.0));
+ fragPosition = vec3(matModel*vec4(displacedPosition, 1.0));
fragTexCoord = vertexTexCoord;
- fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 1.0)));
- height = displacedPosition.y * 0.2; // send height to fragment shader for coloring
+ fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
+ height = displacedPosition.y*0.2; // send height to fragment shader for coloring
// Calculate final vertex position
- gl_Position = mvp * vec4(displacedPosition, 1.0);
+ gl_Position = mvp*vec4(displacedPosition, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl100/wave.fs b/examples/shaders/resources/shaders/glsl100/wave.fs
index cd4ba9de4..df12df9ba 100644
--- a/examples/shaders/resources/shaders/glsl100/wave.fs
+++ b/examples/shaders/resources/shaders/glsl100/wave.fs
@@ -11,9 +11,7 @@ uniform sampler2D texture0;
uniform vec4 colDiffuse;
uniform float seconds;
-
uniform vec2 size;
-
uniform float freqX;
uniform float freqY;
uniform float ampX;
@@ -22,15 +20,15 @@ uniform float speedX;
uniform float speedY;
void main() {
- float pixelWidth = 1.0 / size.x;
- float pixelHeight = 1.0 / size.y;
- float aspect = pixelHeight / pixelWidth;
+ float pixelWidth = 1.0/size.x;
+ float pixelHeight = 1.0/size.y;
+ float aspect = pixelHeight/pixelWidth;
float boxLeft = 0.0;
float boxTop = 0.0;
vec2 p = fragTexCoord;
- p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (seconds * speedX)) * ampX * pixelWidth;
- p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (seconds * speedY)) * ampY * pixelHeight;
+ p.x += cos((fragTexCoord.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
+ p.y += sin((fragTexCoord.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor;
}
diff --git a/examples/shaders/resources/shaders/glsl100/write_depth.fs b/examples/shaders/resources/shaders/glsl100/write_depth.fs
index 341c6115f..6200bd23a 100644
--- a/examples/shaders/resources/shaders/glsl100/write_depth.fs
+++ b/examples/shaders/resources/shaders/glsl100/write_depth.fs
@@ -1,6 +1,7 @@
-#version 100
+#version 100
+
#extension GL_EXT_frag_depth : enable
-precision mediump float; // Precision required for OpenGL ES2 (WebGL)
+precision mediump float;
varying vec2 fragTexCoord;
varying vec4 fragColor;
diff --git a/examples/shaders/resources/shaders/glsl120/color_mix.fs b/examples/shaders/resources/shaders/glsl120/color_mix.fs
new file mode 100644
index 000000000..999f61afc
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/color_mix.fs
@@ -0,0 +1,24 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform sampler2D texture1;
+uniform vec4 colDiffuse;
+
+uniform float divider;
+
+void main()
+{
+ // Texel color fetching from texture sampler
+ vec4 texelColor0 = texture2D(texture0, fragTexCoord);
+ vec4 texelColor1 = texture2D(texture1, fragTexCoord);
+
+ float x = fract(fragTexCoord.s);
+ float final = smoothstep(divider - 0.1, divider + 0.1, x);
+
+ gl_FragColor = mix(texelColor0, texelColor1, final);
+}
diff --git a/examples/shaders/resources/shaders/glsl120/cross_stitching.fs b/examples/shaders/resources/shaders/glsl120/cross_stitching.fs
index 532724635..e3ad3417e 100644
--- a/examples/shaders/resources/shaders/glsl120/cross_stitching.fs
+++ b/examples/shaders/resources/shaders/glsl120/cross_stitching.fs
@@ -21,8 +21,8 @@ vec4 PostFX(sampler2D tex, vec2 uv)
{
vec4 c = vec4(0.0);
float size = stitchingSize;
- vec2 cPos = uv * vec2(renderWidth, renderHeight);
- vec2 tlPos = floor(cPos / vec2(size, size));
+ vec2 cPos = uv*vec2(renderWidth, renderHeight);
+ vec2 tlPos = floor(cPos/vec2(size, size));
tlPos *= size;
int remX = int(mod(cPos.x, size));
@@ -36,11 +36,11 @@ vec4 PostFX(sampler2D tex, vec2 uv)
if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y)))))
{
if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0);
- else c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ else c = texture2D(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
}
else
{
- if (invert == 1) c = texture2D(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ if (invert == 1) c = texture2D(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
else c = vec4(0.0, 0.0, 0.0, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl120/cubes_panning.fs b/examples/shaders/resources/shaders/glsl120/cubes_panning.fs
new file mode 100644
index 000000000..24c53d2ff
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/cubes_panning.fs
@@ -0,0 +1,58 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Custom variables
+const float PI = 3.14159265358979323846;
+uniform float uTime;
+
+float divisions = 5.0;
+float angle = 0.0;
+
+vec2 VectorRotateTime(vec2 v, float speed)
+{
+ float time = uTime*speed;
+ float localTime = fract(time); // The time domain this works on is 1 sec
+
+ if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
+ else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4.0*sin(2.0*PI*localTime - PI/2.0);
+ else if ((localTime >= 0.50) && (localTime < 0.75)) angle = PI*0.25;
+ else if ((localTime >= 0.75) && (localTime < 1.00)) angle = PI/4.0*sin(2.0*PI*localTime);
+
+ // Rotate vector by angle
+ v -= 0.5;
+ v = mat2(cos(angle), -sin(angle), sin(angle), cos(angle))*v;
+ v += 0.5;
+
+ return v;
+}
+
+float Rectangle(in vec2 st, in float size, in float fill)
+{
+ float roundSize = 0.5 - size/2.0;
+ float left = step(roundSize, st.x);
+ float top = step(roundSize, st.y);
+ float bottom = step(roundSize, 1.0 - st.y);
+ float right = step(roundSize, 1.0 - st.x);
+
+ return (left*bottom*right*top)*fill;
+}
+
+void main()
+{
+ vec2 fragPos = fragTexCoord;
+ fragPos.xy += uTime/9.0;
+
+ fragPos *= divisions;
+ vec2 ipos = floor(fragPos); // Get the integer coords
+ vec2 fpos = fract(fragPos); // Get the fractional coords
+
+ fpos = VectorRotateTime(fpos, 0.2);
+
+ float alpha = Rectangle(fpos, 0.216, 1.0);
+ vec3 color = vec3(0.3, 0.3, 0.3);
+
+ gl_FragColor = vec4(color, alpha);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/deferred_shading.fs b/examples/shaders/resources/shaders/glsl120/deferred_shading.fs
new file mode 100644
index 000000000..f52454d8c
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/deferred_shading.fs
@@ -0,0 +1,57 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D gPosition;
+uniform sampler2D gNormal;
+uniform sampler2D gAlbedoSpec;
+
+struct Light {
+ int enabled;
+ int type; // Unused in this demo
+ vec3 position;
+ vec3 target; // Unused in this demo
+ vec4 color;
+};
+
+const int NR_LIGHTS = 4;
+uniform Light lights[NR_LIGHTS];
+uniform vec3 viewPosition;
+
+const float QUADRATIC = 0.032;
+const float LINEAR = 0.09;
+
+void main()
+{
+ vec3 fragPosition = texture2D(gPosition, fragTexCoord).rgb;
+ vec3 normal = texture2D(gNormal, fragTexCoord).rgb;
+ vec3 albedo = texture2D(gAlbedoSpec, fragTexCoord).rgb;
+ float specular = texture2D(gAlbedoSpec, fragTexCoord).a;
+
+ vec3 ambient = albedo*vec3(0.1);
+ vec3 viewDirection = normalize(viewPosition - fragPosition);
+
+ for (int i = 0; i < NR_LIGHTS; ++i)
+ {
+ if (lights[i].enabled == 0) continue;
+ vec3 lightDirection = lights[i].position - fragPosition;
+ vec3 diffuse = max(dot(normal, lightDirection), 0.0)*albedo*lights[i].color.xyz;
+
+ vec3 halfwayDirection = normalize(lightDirection + viewDirection);
+ float spec = pow(max(dot(normal, halfwayDirection), 0.0), 32.0);
+ vec3 specular = specular*spec*lights[i].color.xyz;
+
+ // Attenuation
+ float distance = length(lights[i].position - fragPosition);
+ float attenuation = 1.0/(1.0 + LINEAR*distance + QUADRATIC*distance*distance);
+ diffuse *= attenuation;
+ specular *= attenuation;
+ ambient += diffuse + specular;
+ }
+
+ gl_FragColor = vec4(ambient, 1.0);
+}
+
diff --git a/examples/shaders/resources/shaders/glsl120/deferred_shading.vs b/examples/shaders/resources/shaders/glsl120/deferred_shading.vs
new file mode 100644
index 000000000..daece19e5
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/deferred_shading.vs
@@ -0,0 +1,16 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+
+// Output vertex attributes (to fragment shader)
+varying vec2 fragTexCoord;
+
+void main()
+{
+ fragTexCoord = vertexTexCoord;
+
+ // Calculate final vertex position
+ gl_Position = vec4(vertexPosition, 1.0);
+}
diff --git a/examples/shaders/resources/shaders/glsl120/eratosthenes.fs b/examples/shaders/resources/shaders/glsl120/eratosthenes.fs
new file mode 100644
index 000000000..d1623a67c
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/eratosthenes.fs
@@ -0,0 +1,58 @@
+#version 120
+
+/*************************************************************************************
+
+ The Sieve of Eratosthenes -- a simple shader by ProfJski
+ An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
+
+ The screen is divided into a square grid of boxes, each representing an integer value
+ Each integer is tested to see if it is a prime number. Primes are colored white
+ Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer
+
+ You can change the scale variable to make a larger or smaller grid
+ Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers
+
+ WARNING: If you make scale too large, your GPU may bog down!
+
+***************************************************************************************/
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Make a nice spectrum of colors based on counter and maxSize
+vec4 Colorizer(float counter, float maxSize)
+{
+ float red = 0.0, green = 0.0, blue = 0.0;
+ float normsize = counter/maxSize;
+
+ red = smoothstep(0.3, 0.7, normsize);
+ green = sin(3.14159*normsize);
+ blue = 1.0 - smoothstep(0.0, 0.4, normsize);
+
+ return vec4(0.8*red, 0.8*green, 0.8*blue, 1.0);
+}
+
+void main()
+{
+ vec4 color = vec4(1.0);
+ float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid
+ float value = scale*floor(fragTexCoord.y*scale) + floor(fragTexCoord.x*scale); // Group pixels into boxes representing integer values
+ int valuei = int(value);
+
+ //if ((valuei == 0) || (valuei == 1) || (valuei == 2)) gl_FragColor = vec4(1.0);
+ //else
+ {
+ //for (int i = 2; (i < int(max(2.0, sqrt(value) + 1.0))); i++)
+ // NOTE: On GLSL 100 for loops are restricted and loop condition must be a constant
+ // Tested on RPI, it seems loops are limited around 60 iteractions
+ for (int i = 2; i < 48; i++)
+ {
+ if ((value - float(i)*floor(value/float(i))) <= 0.0)
+ {
+ gl_FragColor = Colorizer(float(i), scale);
+ //break; // Uncomment to color by the largest factor instead
+ }
+ }
+ }
+}
diff --git a/examples/shaders/resources/shaders/glsl120/fisheye.fs b/examples/shaders/resources/shaders/glsl120/fisheye.fs
index 5cc86b811..b88c5b790 100644
--- a/examples/shaders/resources/shaders/glsl120/fisheye.fs
+++ b/examples/shaders/resources/shaders/glsl120/fisheye.fs
@@ -15,22 +15,22 @@ const float PI = 3.1415926535;
void main()
{
float aperture = 178.0;
- float apertureHalf = 0.5 * aperture * (PI / 180.0);
+ float apertureHalf = 0.5*aperture*(PI/180.0);
float maxFactor = sin(apertureHalf);
vec2 uv = vec2(0.0);
- vec2 xy = 2.0 * fragTexCoord.xy - 1.0;
+ vec2 xy = 2.0*fragTexCoord.xy - 1.0;
float d = length(xy);
if (d < (2.0 - maxFactor))
{
- d = length(xy * maxFactor);
- float z = sqrt(1.0 - d * d);
- float r = atan(d, z) / PI;
+ d = length(xy*maxFactor);
+ float z = sqrt(1.0 - d*d);
+ float r = atan(d, z)/PI;
float phi = atan(xy.y, xy.x);
- uv.x = r * cos(phi) + 0.5;
- uv.y = r * sin(phi) + 0.5;
+ uv.x = r*cos(phi) + 0.5;
+ uv.y = r*sin(phi) + 0.5;
}
else
{
diff --git a/examples/shaders/resources/shaders/glsl120/gbuffer.fs b/examples/shaders/resources/shaders/glsl120/gbuffer.fs
new file mode 100644
index 000000000..a826d7916
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/gbuffer.fs
@@ -0,0 +1,34 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec3 fragNormal;
+varying vec4 fragColor;
+
+// TODO: Is there some alternative for GLSL100
+//layout (location = 0) out vec3 gPosition;
+//layout (location = 1) out vec3 gNormal;
+//layout (location = 2) out vec4 gAlbedoSpec;
+//uniform vec3 gPosition;
+//uniform vec3 gNormal;
+//uniform vec4 gAlbedoSpec;
+
+// Input uniform values
+uniform sampler2D texture0; // Diffuse texture
+uniform sampler2D specularTexture;
+
+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;
+}
diff --git a/examples/shaders/resources/shaders/glsl120/gbuffer.vs b/examples/shaders/resources/shaders/glsl120/gbuffer.vs
new file mode 100644
index 000000000..adc1dcd1a
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/gbuffer.vs
@@ -0,0 +1,60 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+// Input uniform values
+uniform mat4 matModel;
+uniform mat4 matView;
+uniform mat4 matProjection;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec3 fragNormal;
+varying vec4 fragColor;
+
+
+// https://github.com/glslify/glsl-inverse
+mat3 inverse(mat3 m)
+{
+ float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
+ float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
+ float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
+
+ float b01 = a22*a11 - a12*a21;
+ float b11 = -a22*a10 + a12*a20;
+ float b21 = a21*a10 - a11*a20;
+
+ float det = a00*b01 + a01*b11 + a02*b21;
+
+ return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
+ b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
+ b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
+}
+
+// https://github.com/glslify/glsl-transpose
+mat3 transpose(mat3 m)
+{
+ return mat3(m[0][0], m[1][0], m[2][0],
+ m[0][1], m[1][1], m[2][1],
+ m[0][2], m[1][2], m[2][2]);
+}
+
+void main()
+{
+ // Calculate vertex attributes for fragment shader
+ vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
+ fragPosition = worldPos.xyz;
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+
+ mat3 normalMatrix = transpose(inverse(mat3(matModel)));
+ fragNormal = normalMatrix*vertexNormal;
+
+ // Calculate final vertex position
+ gl_Position = matProjection*matView*worldPos;
+}
diff --git a/examples/shaders/resources/shaders/glsl120/hybrid_raster.fs b/examples/shaders/resources/shaders/glsl120/hybrid_raster.fs
new file mode 100644
index 000000000..e4c7e2eca
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/hybrid_raster.fs
@@ -0,0 +1,17 @@
+#version 120
+
+#extension GL_EXT_frag_depth : enable // Extension required for writing depth
+
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+void main()
+{
+ vec4 texelColor = texture2D(texture0, fragTexCoord);
+
+ gl_FragColor = texelColor*colDiffuse*fragColor;
+ gl_FragDepthEXT = gl_FragCoord.z;
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs b/examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs
new file mode 100644
index 000000000..3118e1861
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs
@@ -0,0 +1,291 @@
+#version 120
+
+#extension GL_EXT_frag_depth : enable //Extension required for writing depth
+#extension GL_OES_standard_derivatives : enable //Extension used for fwidth()
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// Custom Input Uniform
+uniform vec3 camPos;
+uniform vec3 camDir;
+uniform vec2 screenCenter;
+
+#define ZERO 0
+
+// SRC: https://learnopengl.com/Advanced-OpenGL/Depth-testing
+float CalcDepth(in vec3 rd, in float Idist)
+{
+ float local_z = dot(normalize(camDir),rd)*Idist;
+ return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01);
+}
+
+// SRC: https://iquilezles.org/articles/distfunctions/
+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,
+ 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));
+}
+
+// r = sphere's radius
+// h = cutting's plane's position
+// t = thickness
+float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
+{
+ // Six way symetry Transformation
+ vec3 ap = abs(p);
+ if (ap.x < max(ap.y, ap.z)){
+ if (ap.y < ap.z) ap.xz = ap.zx;
+ else ap.xy = ap.yx;
+ }
+
+ vec2 q = vec2(length(ap.yz), ap.x);
+
+ float w = sqrt(r*r-h*h);
+
+ return ((h*q.x0.0)
+ {
+ tmax = min(tmax, tp1);
+ res = vec2(tp1, 1.0);
+ }
+
+ float t = tmin;
+ for (int i=0; i<70 ; i++)
+ {
+ if (t>tmax) break;
+ vec2 h = map(ro+rd*t);
+ if (abs(h.x) < (0.0001*t))
+ {
+ res = vec2(t,h.y);
+ break;
+ }
+ t += h.x;
+ }
+
+ return res;
+}
+
+
+// https://iquilezles.org/articles/rmshadows
+float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
+{
+ // bounding volume
+ float tp = (0.8-ro.y)/rd.y; if (tp>0.0) tmax = min(tmax, tp);
+
+ float res = 1.0;
+ float t = mint;
+ for (int i=ZERO; i<24; i++)
+ {
+ float h = map(ro + rd*t).x;
+ float s = clamp(8.0*h/t,0.0,1.0);
+ res = min(res, s);
+ 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);
+}
+
+
+// https://iquilezles.org/articles/normalsSDF
+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 +
+ e.xxx*map(pos + e.xxx).x);
+}
+
+// https://iquilezles.org/articles/nvscene2008/rwwtt.pdf
+float calcAO(in vec3 pos, in vec3 nor)
+{
+ float occ = 0.0;
+ float sca = 1.0;
+ for (int i=ZERO; i<5; i++)
+ {
+ float h = 0.01 + 0.12*float(i)/4.0;
+ float d = map(pos + h*nor).x;
+ occ += (h-d)*sca;
+ 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);
+}
+
+// https://iquilezles.org/articles/checkerfiltering
+float checkersGradBox(in vec2 p)
+{
+ // filter kernel
+ vec2 w = fwidth(p) + 0.001;
+ // 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;
+}
+
+// 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;
+ float m = res.y;
+ if (m>-0.5)
+ {
+ 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
+ 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);
+ col = 0.15 + f*vec3(0.05);
+ ks = 0.4;
+ }
+
+ // lighting
+ float occ = calcAO(pos, nor);
+
+ vec3 lin = vec3(0.0);
+
+ // sun
+ {
+ vec3 lig = normalize(vec3(-0.5, 0.4, -0.6));
+ vec3 hal = normalize(lig-rd);
+ float dif = clamp(dot(nor, lig), 0.0, 1.0);
+ //if (dif>0.0001)
+ dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
+ float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0);
+ spe *= dif;
+ spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
+ //spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0);
+ lin += col*2.20*dif*vec3(1.30,1.00,0.70);
+ lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks;
+ }
+ // sky
+ {
+ float dif = sqrt(clamp(0.5+0.5*nor.y, 0.0, 1.0));
+ dif *= occ;
+ float spe = smoothstep(-0.2, 0.2, ref.y);
+ spe *= dif;
+ spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0);
+ //if (spe>0.001)
+ spe *= calcSoftshadow(pos, ref, 0.02, 2.5);
+ lin += col*0.60*dif*vec3(0.40,0.60,1.15);
+ lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks;
+ }
+ // back
+ {
+ float dif = clamp(dot(nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
+ dif *= occ;
+ lin += col*0.55*dif*vec3(0.25,0.25,0.25);
+ }
+ // sss
+ {
+ float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0);
+ 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));
+ }
+
+ return vec4(vec3(clamp(col,0.0,1.0)),t);
+}
+
+vec3 CalcRayDir(vec2 nCoord){
+ vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0)));
+ vec3 vertical = normalize(cross(horizontal,camDir));
+ return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y);
+}
+
+mat3 setCamera()
+{
+ vec3 cw = normalize(camDir);
+ vec3 cp = vec3(0.0, 1.0 ,0.0);
+ vec3 cu = normalize(cross(cw,cp));
+ vec3 cv = (cross(cu,cw));
+ return mat3(cu, cv, cw);
+}
+
+void main()
+{
+ vec2 nCoord = (gl_FragCoord.xy - screenCenter.xy)/screenCenter.y;
+ mat3 ca = setCamera();
+
+ // focal length
+ float fl = length(camDir);
+ vec3 rd = ca*normalize(vec3(nCoord,fl));
+ vec3 color = vec3(nCoord/2.0 + 0.5, 0.0);
+ float depth = gl_FragCoord.z;
+ {
+ vec4 res = render(camPos - vec3(0.0, 0.0, 0.0) , rd);
+ color = res.xyz;
+ depth = CalcDepth(rd,res.w);
+ }
+ gl_FragColor = vec4(color , 1.0);
+ gl_FragDepthEXT = depth;
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/julia_set.fs b/examples/shaders/resources/shaders/glsl120/julia_set.fs
new file mode 100644
index 000000000..4fc8367ed
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/julia_set.fs
@@ -0,0 +1,80 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
+uniform vec2 offset; // Offset of the scale.
+uniform float zoom; // Zoom of the scale.
+
+// NOTE: Maximum number of shader for-loop iterations depend on GPU,
+// for example, on RasperryPi for this examply only supports up to 60
+const int maxIterations = 255; // Max iterations to do
+const float colorCycles = 1.0; // Number of times the color palette repeats
+
+// Square a complex number
+vec2 ComplexSquare(vec2 z)
+{
+ return vec2(z.x*z.x - z.y*z.y, z.x*z.y*2.0);
+}
+
+// Convert Hue Saturation Value (HSV) color into RGB
+vec3 Hsv2rgb(vec3 c)
+{
+ vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);
+ vec3 p = abs(fract(c.xxx + K.xyz)*6.0 - K.www);
+ return c.z*mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+
+void main()
+{
+ /**********************************************************************************************
+ Julia sets use a function z^2 + c, where c is a constant
+ This function is iterated until the nature of the point is determined
+
+ If the magnitude of the number becomes greater than 2, then from that point onward
+ the number will get bigger and bigger, and will never get smaller (tends towards infinity)
+ 2^2 = 4, 4^2 = 8 and so on
+ So at 2 we stop iterating
+
+ If the number is below 2, we keep iterating
+ But when do we stop iterating if the number is always below 2 (it converges)?
+ That is what maxIterations is for
+ Then we can divide the iterations by the maxIterations value to get a normalized value
+ that we can then map to a color
+
+ We use dot product (z.x*z.x + z.y*z.y) to determine the magnitude (length) squared
+ And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power)
+ *************************************************************************************************/
+
+ // The pixel coordinates are scaled so they are on the mandelbrot scale
+ // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
+ vec2 z = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
+ z.x += offset.x;
+ z.y += offset.y;
+
+ int iter = 0;
+ for (int iterations = 0; iterations < maxIterations; iterations++)
+ {
+ z = ComplexSquare(z) + c; // Iterate function
+ if (dot(z, z) > 4.0) break;
+
+ iter = iterations;
+ }
+
+ // Another few iterations decreases errors in the smoothing calculation
+ // See http://linas.org/art-gallery/escape/escape.html for more information
+ z = ComplexSquare(z) + c;
+ z = ComplexSquare(z) + c;
+
+ // This last part smooths the color (again see link above)
+ float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0));
+
+ // Normalize the value so it is between 0 and 1
+ float norm = smoothVal/float(maxIterations);
+
+ // If in set, color black. 0.999 allows for some float accuracy error
+ if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+ else gl_FragColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0, 1.0)), 1.0);
+}
diff --git a/examples/shaders/resources/shaders/glsl120/lighting.fs b/examples/shaders/resources/shaders/glsl120/lighting.fs
index 508d0eb14..ef0dd65ac 100644
--- a/examples/shaders/resources/shaders/glsl120/lighting.fs
+++ b/examples/shaders/resources/shaders/glsl120/lighting.fs
@@ -38,7 +38,7 @@ void main()
vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0);
- vec4 tint = colDiffuse * fragColor;
+ vec4 tint = colDiffuse*fragColor;
// NOTE: Implement here your fragment shader code
diff --git a/examples/shaders/resources/shaders/glsl120/lighting_instancing.vs b/examples/shaders/resources/shaders/glsl120/lighting_instancing.vs
new file mode 100644
index 000000000..4787bc57a
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/lighting_instancing.vs
@@ -0,0 +1,36 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+attribute mat4 instanceTransform;
+
+// Input uniform values
+uniform mat4 mvp;
+uniform mat4 matNormal;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+// NOTE: Add your custom variables here
+
+void main()
+{
+ // Compute MVP for current instance
+ mat4 mvpi = mvp*instanceTransform;
+
+ // Send vertex attributes to fragment shader
+ fragPosition = vec3(mvpi*vec4(vertexPosition, 1.0));
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
+
+ // Calculate final vertex position
+ gl_Position = mvpi*vec4(vertexPosition, 1.0);
+}
diff --git a/examples/shaders/resources/shaders/glsl120/lightmap.fs b/examples/shaders/resources/shaders/glsl120/lightmap.fs
index 93a0609e2..85fc6f7fe 100644
--- a/examples/shaders/resources/shaders/glsl120/lightmap.fs
+++ b/examples/shaders/resources/shaders/glsl120/lightmap.fs
@@ -16,5 +16,5 @@ void main()
vec4 texelColor = texture2D(texture0, fragTexCoord);
vec4 texelColor2 = texture2D(texture1, fragTexCoord2);
- gl_FragColor = texelColor * texelColor2;
+ gl_FragColor = texelColor*texelColor2;
}
diff --git a/examples/shaders/resources/shaders/glsl120/mask.fs b/examples/shaders/resources/shaders/glsl120/mask.fs
new file mode 100644
index 000000000..8203a7008
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/mask.fs
@@ -0,0 +1,22 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform sampler2D mask;
+uniform vec4 colDiffuse;
+uniform int frame;
+
+// NOTE: Add your custom variables here
+
+void main()
+{
+ vec4 maskColour = texture2D(mask, fragTexCoord + vec2(sin(-float(frame)/150.0)/10.0, cos(-float(frame)/170.0)/10.0));
+ if (maskColour.r < 0.25) discard;
+ vec4 texelColor = texture2D(texture0, fragTexCoord + vec2(sin(float(frame)/90.0)/8.0, cos(float(frame)/60.0)/8.0));
+
+ gl_FragColor = texelColor*maskColour;
+}
diff --git a/examples/shaders/resources/shaders/glsl120/normalmap.fs b/examples/shaders/resources/shaders/glsl120/normalmap.fs
index caeb4d5c1..9e7ba5e19 100644
--- a/examples/shaders/resources/shaders/glsl120/normalmap.fs
+++ b/examples/shaders/resources/shaders/glsl120/normalmap.fs
@@ -32,21 +32,21 @@ void main()
normal = texture(normalMap, vec2(fragTexCoord.x, fragTexCoord.y)).rgb;
//Transform normal values to the range -1.0 ... 1.0
- normal = normalize(normal * 2.0 - 1.0);
+ normal = normalize(normal*2.0 - 1.0);
//Transform the normal from tangent-space to world-space for lighting calculation
- normal = normalize(normal * TBN);
+ normal = normalize(normal*TBN);
}
else
{
normal = normalize(fragNormal);
}
- vec4 tint = colDiffuse * fragColor;
+ vec4 tint = colDiffuse*fragColor;
vec3 lightColor = vec3(1.0, 1.0, 1.0);
float NdotL = max(dot(normal, lightDir), 0.0);
- vec3 lightDot = lightColor * NdotL;
+ vec3 lightDot = lightColor*NdotL;
float specCo = 0.0;
@@ -54,9 +54,9 @@ void main()
specular += specCo;
- finalColor = (texelColor * ((tint + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
- finalColor += texelColor * (vec4(1.0, 1.0, 1.0, 1.0) / 40.0) * tint;
+ finalColor = (texelColor*((tint + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
+ finalColor += texelColor*(vec4(1.0, 1.0, 1.0, 1.0)/40.0)*tint;
// Gamma correction
- gl_FragColor = pow(finalColor, vec4(1.0 / 2.2));
+ gl_FragColor = pow(finalColor, vec4(1.0/2.2));
}
diff --git a/examples/shaders/resources/shaders/glsl120/normalmap.vs b/examples/shaders/resources/shaders/glsl120/normalmap.vs
index d8921a68f..69fdc7e0f 100644
--- a/examples/shaders/resources/shaders/glsl120/normalmap.vs
+++ b/examples/shaders/resources/shaders/glsl120/normalmap.vs
@@ -27,15 +27,15 @@ mat3 inverse(mat3 m)
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
- float b01 = a22 * a11 - a12 * a21;
- float b11 = -a22 * a10 + a12 * a20;
- float b21 = a21 * a10 - a11 * a20;
+ float b01 = a22*a11 - a12*a21;
+ float b11 = -a22*a10 + a12*a20;
+ float b21 = a21*a10 - a11*a20;
- float det = a00 * b01 + a01 * b11 + a02 * b21;
+ float det = a00*b01 + a01*b11 + a02*b21;
- return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),
- b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),
- b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;
+ return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
+ b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
+ b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
}
// https://github.com/glslify/glsl-transpose
@@ -49,21 +49,21 @@ mat3 transpose(mat3 m)
void main()
{
// Compute binormal from vertex normal and tangent. W component is the tangent handedness
- vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
+ vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz)*vertexTangent.w;
// Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Compute fragment position based on model transformations
- fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
+ fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
//Create TBN matrix for transforming the normal map values from tangent-space to world-space
- fragNormal = normalize(normalMatrix * vertexNormal);
+ fragNormal = normalize(normalMatrix*vertexNormal);
- vec3 fragTangent = normalize(normalMatrix * vertexTangent.xyz);
- fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal) * fragNormal);
+ vec3 fragTangent = normalize(normalMatrix*vertexTangent.xyz);
+ fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
- vec3 fragBinormal = normalize(normalMatrix * vertexBinormal);
+ vec3 fragBinormal = normalize(normalMatrix*vertexBinormal);
fragBinormal = cross(fragNormal, fragTangent);
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
@@ -72,5 +72,5 @@ void main()
fragTexCoord = vertexTexCoord;
- gl_Position = mvp * vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl120/outline.fs b/examples/shaders/resources/shaders/glsl120/outline.fs
new file mode 100644
index 000000000..1d632caf6
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/outline.fs
@@ -0,0 +1,32 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+uniform vec2 textureSize;
+uniform float outlineSize;
+uniform vec4 outlineColor;
+
+void main()
+{
+ vec4 texel = texture2D(texture0, fragTexCoord); // Get texel color
+ vec2 texelScale = vec2(0.0);
+ texelScale.x = outlineSize/textureSize.x;
+ texelScale.y = outlineSize/textureSize.y;
+
+ // We sample four corner texels, but only for the alpha channel (this is for the outline)
+ vec4 corners = vec4(0.0);
+ corners.x = texture2D(texture0, fragTexCoord + vec2(texelScale.x, texelScale.y)).a;
+ corners.y = texture2D(texture0, fragTexCoord + vec2(texelScale.x, -texelScale.y)).a;
+ corners.z = texture2D(texture0, fragTexCoord + vec2(-texelScale.x, texelScale.y)).a;
+ corners.w = texture2D(texture0, fragTexCoord + vec2(-texelScale.x, -texelScale.y)).a;
+
+ float outline = min(dot(corners, vec4(1.0)), 1.0);
+ vec4 color = mix(vec4(0.0), outlineColor, outline);
+ gl_FragColor = mix(color, texel, texel.a);
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/palette_switch.fs b/examples/shaders/resources/shaders/glsl120/palette_switch.fs
index ab3f79c78..9c60379bc 100644
--- a/examples/shaders/resources/shaders/glsl120/palette_switch.fs
+++ b/examples/shaders/resources/shaders/glsl120/palette_switch.fs
@@ -13,15 +13,15 @@ uniform ivec3 palette[colors];
void main()
{
// Texel color fetching from texture sampler
- vec4 texelColor = texture(texture0, fragTexCoord) * fragColor;
+ vec4 texelColor = texture(texture0, fragTexCoord)*fragColor;
// 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);
+ // to the palette index by scaling up from [0, 1] to [0, 255]
+ int index = int(texelColor.r*255.0);
ivec3 color = palette[index];
// Calculate final fragment color. Note that the palette color components
// are defined in the range [0, 255] and need to be normalized to [0, 1]
- // for OpenGL to work.
- gl_FragColor = vec4(color / 255.0, texelColor.a);
+ // for OpenGL to work
+ gl_FragColor = vec4(color/255.0, texelColor.a);
}
diff --git a/examples/shaders/resources/shaders/glsl120/pbr.vs b/examples/shaders/resources/shaders/glsl120/pbr.vs
index e9750a60a..4c61012cc 100644
--- a/examples/shaders/resources/shaders/glsl120/pbr.vs
+++ b/examples/shaders/resources/shaders/glsl120/pbr.vs
@@ -52,7 +52,7 @@ mat3 transpose(mat3 m)
void main()
{
// Compute binormal from vertex normal and tangent
- vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
+ vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz)*vertexTangent.w;
// Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
diff --git a/examples/shaders/resources/shaders/glsl120/raymarching.fs b/examples/shaders/resources/shaders/glsl120/raymarching.fs
index efe4fa108..6cc27e9d7 100644
--- a/examples/shaders/resources/shaders/glsl120/raymarching.fs
+++ b/examples/shaders/resources/shaders/glsl120/raymarching.fs
@@ -30,7 +30,7 @@ uniform vec2 resolution;
// SOFTWARE.
// A list of useful distance function to simple primitives, and an example on how to
-// do some interesting boolean operations, repetition and displacement.
+// do some interesting boolean operations, repetition and displacement
//
// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
@@ -38,38 +38,38 @@ uniform vec2 resolution;
//------------------------------------------------------------------
-float sdPlane( vec3 p )
+float sdPlane(vec3 p)
{
return p.y;
}
-float sdSphere( vec3 p, float s )
+float sdSphere(vec3 p, float s)
{
return length(p)-s;
}
-float sdBox( vec3 p, vec3 b )
+float sdBox(vec3 p, vec3 b)
{
vec3 d = abs(p) - b;
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}
-float sdEllipsoid( in vec3 p, in vec3 r )
+float sdEllipsoid(in vec3 p, in vec3 r)
{
- return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z);
+ return (length(p/r) - 1.0)*min(min(r.x,r.y),r.z);
}
-float udRoundBox( vec3 p, vec3 b, float r )
+float udRoundBox(vec3 p, vec3 b, float r)
{
return length(max(abs(p)-b,0.0))-r;
}
-float sdTorus( vec3 p, vec2 t )
+float sdTorus(vec3 p, vec2 t)
{
- return length( vec2(length(p.xz)-t.x,p.y) )-t.y;
+ return length(vec2(length(p.xz)-t.x,p.y))-t.y;
}
-float sdHexPrism( vec3 p, vec2 h )
+float sdHexPrism(vec3 p, vec2 h)
{
vec3 q = abs(p);
#if 0
@@ -81,24 +81,24 @@ float sdHexPrism( vec3 p, vec2 h )
#endif
}
-float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
+float sdCapsule(vec3 p, vec3 a, vec3 b, float r)
{
vec3 pa = p-a, ba = b-a;
- float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
- return length( pa - ba*h ) - r;
+ float h = clamp(dot(pa,ba)/dot(ba,ba), 0.0, 1.0);
+ return length(pa - ba*h) - r;
}
-float sdEquilateralTriangle( in vec2 p )
+float sdEquilateralTriangle( in vec2 p)
{
const float k = sqrt(3.0);
p.x = abs(p.x) - 1.0;
p.y = p.y + 1.0/k;
- if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0;
- p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 );
+ if (p.x + k*p.y > 0.0) p = vec2(p.x - k*p.y, -k*p.x - p.y)/2.0;
+ p.x += 2.0 - 2.0*clamp((p.x+2.0)/2.0, 0.0, 1.0);
return -length(p)*sign(p.y);
}
-float sdTriPrism( vec3 p, vec2 h )
+float sdTriPrism(vec3 p, vec2 h)
{
vec3 q = abs(p);
float d1 = q.z-h.y;
@@ -113,95 +113,95 @@ float sdTriPrism( vec3 p, vec2 h )
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdCylinder( vec3 p, vec2 h )
+float sdCylinder(vec3 p, vec2 h)
{
vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
-float sdCone( in vec3 p, in vec3 c )
+float sdCone(in vec3 p, in vec3 c)
{
- vec2 q = vec2( length(p.xz), p.y );
+ vec2 q = vec2(length(p.xz), p.y);
float d1 = -q.y-c.z;
- float d2 = max( dot(q,c.xy), q.y);
+ float d2 = max(dot(q,c.xy), q.y);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdConeSection( in vec3 p, in float h, in float r1, in float r2 )
+float sdConeSection(in vec3 p, in float h, in float r1, in float r2)
{
float d1 = -p.y - h;
float q = p.y - h;
float si = 0.5*(r1-r2)/h;
- float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q );
+ float d2 = max(sqrt(dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height }
+float sdPryamid4(vec3 p, vec3 h) // h = { cos a, sin a, height }
{
// Tetrahedron = Octahedron - Cube
- float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) );
+ float box = sdBox(p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z));
float d = 0.0;
- d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) ));
- d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) ));
- d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) ));
- d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) ));
+ d = max(d, abs(dot(p, vec3(-h.x, h.y, 0))));
+ d = max(d, abs(dot(p, vec3( h.x, h.y, 0))));
+ d = max(d, abs(dot(p, vec3( 0, h.y, h.x))));
+ d = max(d, abs(dot(p, vec3( 0, h.y,-h.x))));
float octa = d - h.z;
return max(-box,octa); // Subtraction
}
-float length2( vec2 p )
+float length2(vec2 p)
{
- return sqrt( p.x*p.x + p.y*p.y );
+ return sqrt(p.x*p.x + p.y*p.y);
}
-float length6( vec2 p )
+float length6(vec2 p)
{
p = p*p*p; p = p*p;
- return pow( p.x + p.y, 1.0/6.0 );
+ return pow(p.x + p.y, 1.0/6.0);
}
-float length8( vec2 p )
+float length8(vec2 p)
{
p = p*p; p = p*p; p = p*p;
- return pow( p.x + p.y, 1.0/8.0 );
+ return pow(p.x + p.y, 1.0/8.0);
}
-float sdTorus82( vec3 p, vec2 t )
+float sdTorus82(vec3 p, vec2 t)
{
vec2 q = vec2(length2(p.xz)-t.x,p.y);
return length8(q)-t.y;
}
-float sdTorus88( vec3 p, vec2 t )
+float sdTorus88(vec3 p, vec2 t)
{
vec2 q = vec2(length8(p.xz)-t.x,p.y);
return length8(q)-t.y;
}
-float sdCylinder6( vec3 p, vec2 h )
+float sdCylinder6(vec3 p, vec2 h)
{
- return max( length6(p.xz)-h.x, abs(p.y)-h.y );
+ return max(length6(p.xz)-h.x, abs(p.y)-h.y);
}
//------------------------------------------------------------------
-float opS( float d1, float d2 )
+float opS(float d1, float d2)
{
return max(-d2,d1);
}
-vec2 opU( vec2 d1, vec2 d2 )
+vec2 opU(vec2 d1, vec2 d2)
{
return (d1.x0.0 ) tmax = min( tmax, tp1 );
- float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 );
- else tmax = min( tmax, tp2 ); }
+ float tp1 = (0.0-ro.y)/rd.y; if (tp1>0.0) tmax = min(tmax, tp1);
+ float tp2 = (1.6-ro.y)/rd.y; if (tp2>0.0) { if (ro.y>1.6) tmin = max(tmin, tp2);
+ else tmax = min(tmax, tp2); }
#endif
float t = tmin;
float m = -1.0;
- for( int i=0; i<64; i++ )
+ for (int i=0; i<64; i++)
{
float precis = 0.0005*t;
- vec2 res = map( ro+rd*t );
- if( res.xtmax ) break;
+ vec2 res = map(ro+rd*t);
+ if (res.xtmax) break;
t += res.x;
m = res.y;
}
- if( t>tmax ) m=-1.0;
- return vec2( t, m );
+ if (t>tmax) m=-1.0;
+ return vec2(t, m);
}
-float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
+float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{
float res = 1.0;
float t = mint;
- for( int i=0; i<16; i++ )
+ for (int i=0; i<16; i++)
{
- float h = map( ro + rd*t ).x;
- res = min( res, 8.0*h/t );
- t += clamp( h, 0.02, 0.10 );
- if( h<0.001 || t>tmax ) break;
+ float h = map(ro + rd*t).x;
+ res = min(res, 8.0*h/t);
+ t += clamp(h, 0.02, 0.10);
+ if (h<0.001 || t>tmax) break;
}
- return clamp( res, 0.0, 1.0 );
+ return clamp(res, 0.0, 1.0);
}
-vec3 calcNormal( in vec3 pos )
+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 +
- e.xxx*map( pos + e.xxx ).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);
/*
- vec3 eps = vec3( 0.0005, 0.0, 0.0 );
+ vec3 eps = vec3(0.0005, 0.0, 0.0);
vec3 nor = vec3(
map(pos+eps.xyy).x - map(pos-eps.xyy).x,
map(pos+eps.yxy).x - map(pos-eps.yxy).x,
- map(pos+eps.yyx).x - map(pos-eps.yyx).x );
+ map(pos+eps.yyx).x - map(pos-eps.yyx).x);
return normalize(nor);
*/
}
-float calcAO( in vec3 pos, in vec3 nor )
+float calcAO(in vec3 pos, in vec3 nor)
{
float occ = 0.0;
float sca = 1.0;
- for( int i=0; i<5; i++ )
+ for (int i=0; i<5; i++)
{
float hr = 0.01 + 0.12*float(i)/4.0;
- vec3 aopos = nor * hr + pos;
- float dd = map( aopos ).x;
+ vec3 aopos = nor*hr + pos;
+ float dd = map(aopos).x;
occ += -(dd-hr)*sca;
sca *= 0.95;
}
- return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
+ return clamp(1.0 - 3.0*occ, 0.0, 1.0);
}
// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm
-float checkersGradBox( in vec2 p )
+float checkersGradBox(in vec2 p)
{
// filter kernel
vec2 w = fwidth(p) + 0.001;
@@ -324,43 +324,43 @@ float checkersGradBox( in vec2 p )
return 0.5 - 0.5*i.x*i.y;
}
-vec3 render( in vec3 ro, in vec3 rd )
+vec3 render(in vec3 ro, in vec3 rd)
{
vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
vec2 res = castRay(ro,rd);
float t = res.x;
float m = res.y;
- if( m>-0.5 )
+ if (m>-0.5)
{
vec3 pos = ro + t*rd;
- vec3 nor = calcNormal( pos );
- vec3 ref = reflect( rd, nor );
+ vec3 nor = calcNormal(pos);
+ vec3 ref = reflect(rd, nor);
// material
- col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) );
- if( m<1.5 )
+ col = 0.45 + 0.35*sin(vec3(0.05,0.08,0.10)*(m-1.0));
+ if (m<1.5)
{
- float f = checkersGradBox( 5.0*pos.xz );
+ float f = checkersGradBox(5.0*pos.xz);
col = 0.3 + f*vec3(0.1);
}
// lighting
- float occ = calcAO( pos, nor );
- vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) );
- vec3 hal = normalize( lig-rd );
- float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
- float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
- float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
- float dom = smoothstep( -0.1, 0.1, ref.y );
- float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
+ float occ = calcAO(pos, nor);
+ vec3 lig = normalize(vec3(cos(-0.4*runTime), sin(0.7*runTime), -0.6));
+ vec3 hal = normalize(lig-rd);
+ float amb = clamp(0.5+0.5*nor.y, 0.0, 1.0);
+ float dif = clamp(dot(nor, lig), 0.0, 1.0);
+ float bac = clamp(dot(nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
+ float dom = smoothstep(-0.1, 0.1, ref.y);
+ float fre = pow(clamp(1.0+dot(nor,rd),0.0,1.0), 2.0);
- dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
- dom *= calcSoftshadow( pos, ref, 0.02, 2.5 );
+ dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
+ dom *= calcSoftshadow(pos, ref, 0.02, 2.5);
- float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)*
+ float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0)*
dif *
- (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 ));
+ (0.04 + 0.96*pow(clamp(1.0+dot(hal,rd),0.0,1.0), 5.0));
vec3 lin = vec3(0.0);
lin += 1.30*dif*vec3(1.00,0.80,0.55);
@@ -371,51 +371,51 @@ vec3 render( in vec3 ro, in vec3 rd )
col = col*lin;
col += 10.00*spe*vec3(1.00,0.90,0.70);
- col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );
+ col = mix(col, vec3(0.8,0.9,1.0), 1.0-exp(-0.0002*t*t*t));
}
- return vec3( clamp(col,0.0,1.0) );
+ return vec3(clamp(col,0.0,1.0));
}
-mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
+mat3 setCamera(in vec3 ro, in vec3 ta, float cr)
{
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
- vec3 cu = normalize( cross(cw,cp) );
- vec3 cv = normalize( cross(cu,cw) );
- return mat3( cu, cv, cw );
+ vec3 cu = normalize(cross(cw,cp));
+ vec3 cv = normalize(cross(cu,cw));
+ return mat3(cu, cv, cw);
}
void main()
{
vec3 tot = vec3(0.0);
#if AA>1
- for( int m=0; m1
@@ -423,5 +423,5 @@ void main()
tot /= float(AA*AA);
#endif
- gl_FragColor = vec4( tot, 1.0 );
+ gl_FragColor = vec4(tot, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl120/reload.fs b/examples/shaders/resources/shaders/glsl120/reload.fs
new file mode 100644
index 000000000..9b5e12746
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/reload.fs
@@ -0,0 +1,37 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord; // Texture coordinates (sampler2D)
+varying vec4 fragColor; // Tint color
+
+// Uniform inputs
+uniform vec2 resolution; // Viewport resolution (in pixels)
+uniform vec2 mouse; // Mouse pixel xy coordinates
+uniform float time; // Total run time (in secods)
+
+// Draw circle
+vec4 DrawCircle(vec2 fragCoord, vec2 position, float radius, vec3 color)
+{
+ float d = length(position - fragCoord) - radius;
+ float t = clamp(d, 0.0, 1.0);
+ return vec4(color, 1.0 - t);
+}
+
+void main()
+{
+ vec2 fragCoord = gl_FragCoord.xy;
+ vec2 position = vec2(mouse.x, resolution.y - mouse.y);
+ float radius = 40.0;
+
+ // Draw background layer
+ vec4 colorA = vec4(0.2,0.2,0.8, 1.0);
+ vec4 colorB = vec4(1.0,0.7,0.2, 1.0);
+ vec4 layer1 = mix(colorA, colorB, abs(sin(time*0.1)));
+
+ // Draw circle layer
+ vec3 color = vec3(0.9, 0.16, 0.21);
+ vec4 layer2 = DrawCircle(fragCoord, position, radius, color);
+
+ // Blend the two layers
+ gl_FragColor = mix(layer1, layer2, layer2.a);
+}
diff --git a/examples/shaders/resources/shaders/glsl120/rounded_rectangle.fs b/examples/shaders/resources/shaders/glsl120/rounded_rectangle.fs
index eb96c28d3..627e7b1b6 100644
--- a/examples/shaders/resources/shaders/glsl120/rounded_rectangle.fs
+++ b/examples/shaders/resources/shaders/glsl120/rounded_rectangle.fs
@@ -1,7 +1,7 @@
-// Note: SDF by Iñigo Quilez is licensed under MIT License
-
#version 120
+// NOTE: SDF by Iñigo Quilez, licensed under MIT License
+
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
diff --git a/examples/shaders/resources/shaders/glsl120/scanlines.fs b/examples/shaders/resources/shaders/glsl120/scanlines.fs
index 4125ed734..c9abc7856 100644
--- a/examples/shaders/resources/shaders/glsl120/scanlines.fs
+++ b/examples/shaders/resources/shaders/glsl120/scanlines.fs
@@ -33,7 +33,7 @@ void main()
fragColor = color;
*/
// Scanlines method 2
- float globalPos = (fragTexCoord.y + offset) * frequency;
+ float globalPos = (fragTexCoord.y + offset)*frequency;
float wavePos = cos((fract(globalPos) - 0.5)*3.14);
vec4 color = texture2D(texture0, fragTexCoord);
diff --git a/examples/shaders/resources/shaders/glsl120/shadowmap.fs b/examples/shaders/resources/shaders/glsl120/shadowmap.fs
index 84f318591..354c4a2c5 100644
--- a/examples/shaders/resources/shaders/glsl120/shadowmap.fs
+++ b/examples/shaders/resources/shaders/glsl120/shadowmap.fs
@@ -52,7 +52,7 @@ void main()
vec2 sampleCoords = fragPosLightSpace.xy;
float curDepth = fragPosLightSpace.z;
- // Slope-scale depth bias: depth biasing reduces "shadow acne" artifacts, where dark stripes appear all over the scene.
+ // Slope-scale depth bias: depth biasing reduces "shadow acne" artifacts, where dark stripes appear all over the scene
// The solution is adding a small bias to the depth
// In this case, the bias is proportional to the slope of the surface, relative to the light
float bias = max(0.0008*(1.0 - dot(normal, l)), 0.00008);
@@ -61,8 +61,8 @@ void main()
// 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.
- // This blurs shadow edges, hiding aliasing artifacts.
+ // we test the surrounding points as well
+ // This blurs shadow edges, hiding aliasing artifacts
vec2 texelSize = vec2(1.0/float(shadowMapResolution));
for (int x = -1; x <= 1; x++)
{
diff --git a/examples/shaders/resources/shaders/glsl120/sobel.fs b/examples/shaders/resources/shaders/glsl120/sobel.fs
index bfa19062b..c17cfd8a8 100644
--- a/examples/shaders/resources/shaders/glsl120/sobel.fs
+++ b/examples/shaders/resources/shaders/glsl120/sobel.fs
@@ -18,10 +18,10 @@ void main()
vec4 horizEdge = vec4(0.0);
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
- horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
+ horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
- horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
+ horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0);
diff --git a/examples/shaders/resources/shaders/glsl120/spotlight.fs b/examples/shaders/resources/shaders/glsl120/spotlight.fs
new file mode 100644
index 000000000..da15a8b39
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/spotlight.fs
@@ -0,0 +1,75 @@
+#version 120
+
+#define MAX_SPOTS 3
+
+struct Spot {
+ vec2 pos; // window coords of spot
+ float inner; // inner fully transparent centre radius
+ float radius; // alpha fades out to this radius
+};
+
+uniform Spot spots[MAX_SPOTS]; // Spotlight positions array
+uniform float screenWidth; // Width of the screen
+
+void main()
+{
+ float alpha = 1.0;
+
+ // Get the position of the current fragment (screen coordinates!)
+ vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
+
+ // Find out which spotlight is nearest
+ float d = 65000.0; // some high value
+ int fi = -1; // found index
+
+ for (int i = 0; i < MAX_SPOTS; i++)
+ {
+ for (int j = 0; j < MAX_SPOTS; j++)
+ {
+ float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius;
+
+ if (d > dj)
+ {
+ d = dj;
+ fi = i;
+ }
+ }
+ }
+
+ // d now equals distance to nearest spot...
+ // allowing for the different radii of all spotlights
+ if (fi == 0)
+ {
+ if (d > spots[0].radius) alpha = 1.0;
+ else
+ {
+ if (d < spots[0].inner) alpha = 0.0;
+ else alpha = (d - spots[0].inner)/(spots[0].radius - spots[0].inner);
+ }
+ }
+ else if (fi == 1)
+ {
+ if (d > spots[1].radius) alpha = 1.0;
+ else
+ {
+ if (d < spots[1].inner) alpha = 0.0;
+ else alpha = (d - spots[1].inner)/(spots[1].radius - spots[1].inner);
+ }
+ }
+ else if (fi == 2)
+ {
+ if (d > spots[2].radius) alpha = 1.0;
+ else
+ {
+ if (d < spots[2].inner) alpha = 0.0;
+ else alpha = (d - spots[2].inner)/(spots[2].radius - spots[2].inner);
+ }
+ }
+
+ // Right hand side of screen is dimly lit,
+ // could make the threshold value user definable
+ if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
+
+ // could make the black out colour user definable...
+ gl_FragColor = vec4(0, 0, 0, alpha);
+}
diff --git a/examples/shaders/resources/shaders/glsl120/tiling.fs b/examples/shaders/resources/shaders/glsl120/tiling.fs
new file mode 100644
index 000000000..78902cf87
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/tiling.fs
@@ -0,0 +1,19 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add your custom variables here
+uniform vec2 tiling;
+
+void main()
+{
+ vec2 texCoord = fragTexCoord*tiling;
+
+ gl_FragColor = texture2D(texture0, texCoord)*colDiffuse;
+}
diff --git a/examples/shaders/resources/shaders/glsl120/vertex_displacement.fs b/examples/shaders/resources/shaders/glsl120/vertex_displacement.fs
new file mode 100644
index 000000000..ac485050d
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/vertex_displacement.fs
@@ -0,0 +1,15 @@
+#version 120
+
+// Input vertex attributes (from fragment shader)
+varying vec2 fragTexCoord;
+varying float height;
+
+void main()
+{
+ vec4 darkblue = vec4(0.0, 0.13, 0.18, 1.0);
+ vec4 lightblue = vec4(1.0, 1.0, 1.0, 1.0);
+ // Interpolate between two colors based on height
+ vec4 finalColor = mix(darkblue, lightblue, height);
+
+ gl_FragColor = finalColor;
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl120/vertex_displacement.vs b/examples/shaders/resources/shaders/glsl120/vertex_displacement.vs
new file mode 100644
index 000000000..db3c496d5
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/vertex_displacement.vs
@@ -0,0 +1,43 @@
+#version 120
+
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+uniform mat4 mvp;
+uniform mat4 matModel;
+uniform mat4 matNormal;
+
+uniform float time;
+
+uniform sampler2D perlinNoiseMap;
+
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec3 fragNormal;
+varying float height;
+
+void main()
+{
+ // Calculate animated texture coordinates based on time and vertex position
+ vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x*0.1), cos(time + vertexPosition.z*0.1))*0.3);
+
+ // Normalize animated texture coordinates to range [0, 1]
+ animatedTexCoord = animatedTexCoord*0.5 + 0.5;
+
+ // Fetch displacement from the perlin noise map
+ float displacement = texture2D(perlinNoiseMap, animatedTexCoord).r*7.0; // Amplified displacement
+
+ // Displace vertex position
+ vec3 displacedPosition = vertexPosition + vec3(0.0, displacement, 0.0);
+
+ // Send vertex attributes to fragment shader
+ fragPosition = vec3(matModel*vec4(displacedPosition, 1.0));
+ fragTexCoord = vertexTexCoord;
+ fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
+ height = displacedPosition.y*0.2; // send height to fragment shader for coloring
+
+ // Calculate final vertex position
+ gl_Position = mvp*vec4(displacedPosition, 1.0);
+}
diff --git a/examples/shaders/resources/shaders/glsl120/wave.fs b/examples/shaders/resources/shaders/glsl120/wave.fs
new file mode 100644
index 000000000..dd6bb2e22
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/wave.fs
@@ -0,0 +1,32 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+uniform float seconds;
+uniform vec2 size;
+uniform float freqX;
+uniform float freqY;
+uniform float ampX;
+uniform float ampY;
+uniform float speedX;
+uniform float speedY;
+
+void main() {
+ float pixelWidth = 1.0/size.x;
+ float pixelHeight = 1.0/size.y;
+ float aspect = pixelHeight/pixelWidth;
+ float boxLeft = 0.0;
+ float boxTop = 0.0;
+
+ vec2 p = fragTexCoord;
+ p.x += cos((fragTexCoord.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
+ p.y += sin((fragTexCoord.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
+
+ gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor;
+}
diff --git a/examples/shaders/resources/shaders/glsl120/write_depth.fs b/examples/shaders/resources/shaders/glsl120/write_depth.fs
new file mode 100644
index 000000000..a2bc38516
--- /dev/null
+++ b/examples/shaders/resources/shaders/glsl120/write_depth.fs
@@ -0,0 +1,17 @@
+#version 120
+
+#extension GL_EXT_frag_depth : enable
+
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+void main()
+{
+ vec4 texelColor = texture2D(texture0, fragTexCoord);
+
+ gl_FragColor = texelColor*colDiffuse*fragColor;
+ gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
+}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl330/cross_stitching.fs b/examples/shaders/resources/shaders/glsl330/cross_stitching.fs
index 7c76cf758..7c4bc9b53 100644
--- a/examples/shaders/resources/shaders/glsl330/cross_stitching.fs
+++ b/examples/shaders/resources/shaders/glsl330/cross_stitching.fs
@@ -25,8 +25,8 @@ vec4 PostFX(sampler2D tex, vec2 uv)
{
vec4 c = vec4(0.0);
float size = stitchingSize;
- vec2 cPos = uv * vec2(renderWidth, renderHeight);
- vec2 tlPos = floor(cPos / vec2(size, size));
+ vec2 cPos = uv*vec2(renderWidth, renderHeight);
+ vec2 tlPos = floor(cPos/vec2(size, size));
tlPos *= size;
int remX = int(mod(cPos.x, size));
@@ -40,11 +40,11 @@ vec4 PostFX(sampler2D tex, vec2 uv)
if ((remX == remY) || (((int(cPos.x) - int(blPos.x)) == (int(blPos.y) - int(cPos.y)))))
{
if (invert == 1) c = vec4(0.2, 0.15, 0.05, 1.0);
- else c = texture(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ else c = texture(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
}
else
{
- if (invert == 1) c = texture(tex, tlPos * vec2(1.0/renderWidth, 1.0/renderHeight)) * 1.4;
+ if (invert == 1) c = texture(tex, tlPos*vec2(1.0/renderWidth, 1.0/renderHeight))*1.4;
else c = vec4(0.0, 0.0, 0.0, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl330/cubes_panning.fs b/examples/shaders/resources/shaders/glsl330/cubes_panning.fs
index 1d75e4e8c..d58b7b196 100644
--- a/examples/shaders/resources/shaders/glsl330/cubes_panning.fs
+++ b/examples/shaders/resources/shaders/glsl330/cubes_panning.fs
@@ -17,7 +17,7 @@ float angle = 0.0;
vec2 VectorRotateTime(vec2 v, float speed)
{
float time = uTime*speed;
- float localTime = fract(time); // The time domain this works on is 1 sec.
+ float localTime = fract(time); // The time domain this works on is 1 sec
if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4*sin(2*PI*localTime - PI/2);
diff --git a/examples/shaders/resources/shaders/glsl330/deferred_shading.fs b/examples/shaders/resources/shaders/glsl330/deferred_shading.fs
index c9c6a313f..660db3244 100644
--- a/examples/shaders/resources/shaders/glsl330/deferred_shading.fs
+++ b/examples/shaders/resources/shaders/glsl330/deferred_shading.fs
@@ -10,9 +10,9 @@ uniform sampler2D gAlbedoSpec;
struct Light {
int enabled;
- int type; // Unused in this demo.
+ int type; // Unused in this demo
vec3 position;
- vec3 target; // Unused in this demo.
+ vec3 target; // Unused in this demo
vec4 color;
};
@@ -29,22 +29,22 @@ void main() {
vec3 albedo = texture(gAlbedoSpec, texCoord).rgb;
float specular = texture(gAlbedoSpec, texCoord).a;
- vec3 ambient = albedo * vec3(0.1f);
+ vec3 ambient = albedo*vec3(0.1f);
vec3 viewDirection = normalize(viewPosition - fragPosition);
- for(int i = 0; i < NR_LIGHTS; ++i)
+ for (int i = 0; i < NR_LIGHTS; ++i)
{
- if(lights[i].enabled == 0) continue;
+ if (lights[i].enabled == 0) continue;
vec3 lightDirection = lights[i].position - fragPosition;
- vec3 diffuse = max(dot(normal, lightDirection), 0.0) * albedo * lights[i].color.xyz;
+ vec3 diffuse = max(dot(normal, lightDirection), 0.0)*albedo*lights[i].color.xyz;
vec3 halfwayDirection = normalize(lightDirection + viewDirection);
float spec = pow(max(dot(normal, halfwayDirection), 0.0), 32.0);
- vec3 specular = specular * spec * lights[i].color.xyz;
+ vec3 specular = specular*spec*lights[i].color.xyz;
// Attenuation
float distance = length(lights[i].position - fragPosition);
- float attenuation = 1.0 / (1.0 + LINEAR * distance + QUADRATIC * distance * distance);
+ float attenuation = 1.0/(1.0 + LINEAR*distance + QUADRATIC*distance*distance);
diffuse *= attenuation;
specular *= attenuation;
ambient += diffuse + specular;
diff --git a/examples/shaders/resources/shaders/glsl330/eratosthenes.fs b/examples/shaders/resources/shaders/glsl330/eratosthenes.fs
index 644e38d8c..3a5b7fe47 100644
--- a/examples/shaders/resources/shaders/glsl330/eratosthenes.fs
+++ b/examples/shaders/resources/shaders/glsl330/eratosthenes.fs
@@ -5,12 +5,12 @@
The Sieve of Eratosthenes -- a simple shader by ProfJski
An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
- The screen is divided into a square grid of boxes, each representing an integer value.
- Each integer is tested to see if it is a prime number. Primes are colored white.
- Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer.
+ The screen is divided into a square grid of boxes, each representing an integer value
+ Each integer is tested to see if it is a prime number. Primes are colored white
+ Non-primes are colored with a color that indicates the smallest factor which evenly divides our integer
- You can change the scale variable to make a larger or smaller grid.
- Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers.
+ You can change the scale variable to make a larger or smaller grid
+ Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers
WARNING: If you make scale too large, your GPU may bog down!
@@ -39,7 +39,7 @@ vec4 Colorizer(float counter, float maxSize)
void main()
{
vec4 color = vec4(1.0);
- float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid.
+ float scale = 1000.0; // Makes 100x100 square grid, change this variable to make a smaller or larger grid
int value = int(scale*floor(fragTexCoord.y*scale)+floor(fragTexCoord.x*scale)); // Group pixels into boxes representing integer values
if ((value == 0) || (value == 1) || (value == 2)) finalColor = vec4(1.0);
diff --git a/examples/shaders/resources/shaders/glsl330/fisheye.fs b/examples/shaders/resources/shaders/glsl330/fisheye.fs
index 51af4ed88..be81aeb23 100644
--- a/examples/shaders/resources/shaders/glsl330/fisheye.fs
+++ b/examples/shaders/resources/shaders/glsl330/fisheye.fs
@@ -14,22 +14,22 @@ const float PI = 3.1415926535;
void main()
{
float aperture = 178.0;
- float apertureHalf = 0.5 * aperture * (PI / 180.0);
+ float apertureHalf = 0.5*aperture*(PI/180.0);
float maxFactor = sin(apertureHalf);
vec2 uv = vec2(0);
- vec2 xy = 2.0 * fragTexCoord.xy - 1.0;
+ vec2 xy = 2.0*fragTexCoord.xy - 1.0;
float d = length(xy);
if (d < (2.0 - maxFactor))
{
- d = length(xy * maxFactor);
- float z = sqrt(1.0 - d * d);
- float r = atan(d, z) / PI;
+ d = length(xy*maxFactor);
+ float z = sqrt(1.0 - d*d);
+ float r = atan(d, z)/PI;
float phi = atan(xy.y, xy.x);
- uv.x = r * cos(phi) + 0.5;
- uv.y = r * sin(phi) + 0.5;
+ uv.x = r*cos(phi) + 0.5;
+ uv.y = r*sin(phi) + 0.5;
}
else
{
diff --git a/examples/shaders/resources/shaders/glsl330/gbuffer.vs b/examples/shaders/resources/shaders/glsl330/gbuffer.vs
index 7d264ba64..5af4448e6 100644
--- a/examples/shaders/resources/shaders/glsl330/gbuffer.vs
+++ b/examples/shaders/resources/shaders/glsl330/gbuffer.vs
@@ -13,12 +13,12 @@ uniform mat4 matProjection;
void main()
{
- vec4 worldPos = matModel * vec4(vertexPosition, 1.0);
+ vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
fragPosition = worldPos.xyz;
fragTexCoord = vertexTexCoord;
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
- fragNormal = normalMatrix * vertexNormal;
+ fragNormal = normalMatrix*vertexNormal;
- gl_Position = matProjection * matView * worldPos;
+ gl_Position = matProjection*matView*worldPos;
}
diff --git a/examples/shaders/resources/shaders/glsl330/hybrid_raster.fs b/examples/shaders/resources/shaders/glsl330/hybrid_raster.fs
index ffd1b3648..12409d137 100644
--- a/examples/shaders/resources/shaders/glsl330/hybrid_raster.fs
+++ b/examples/shaders/resources/shaders/glsl330/hybrid_raster.fs
@@ -18,5 +18,5 @@ void main()
vec4 texelColor = texture(texture0, fragTexCoord);
gl_FragColor = texelColor*colDiffuse*fragColor;
- gl_FragDepth = gl_FragCoord.z;
+ gl_FragDepth = gl_FragCoord.z;
}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs b/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs
index 5b66dd71c..2edb625ad 100644
--- a/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs
+++ b/examples/shaders/resources/shaders/glsl330/hybrid_raymarch.fs
@@ -22,14 +22,14 @@ float CalcDepth(in vec3 rd, in float Idist){
}
// https://iquilezles.org/articles/distfunctions/
-float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w )
+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,
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.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);
@@ -40,48 +40,48 @@ float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w )
// r = sphere's radius
// h = cutting's plane's position
// t = thickness
-float sdSixWayCutHollowSphere( vec3 p, float r, float h, float t )
+float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
{
// Six way symetry Transformation
vec3 ap = abs(p);
- if(ap.x < max(ap.y, ap.z)){
- if(ap.y < ap.z) ap.xz = ap.zx;
+ if (ap.x < max(ap.y, ap.z)){
+ if (ap.y < ap.z) ap.xz = ap.zx;
else ap.xy = ap.yx;
}
- vec2 q = vec2( length(ap.yz), ap.x );
+ vec2 q = vec2(length(ap.yz), ap.x);
float w = sqrt(r*r-h*h);
return ((h*q.x0.0 )
+ if (tp1>0.0)
{
- tmax = min( tmax, tp1 );
- res = vec2( tp1, 1.0 );
+ tmax = min(tmax, tp1);
+ res = vec2(tp1, 1.0);
}
float t = tmin;
- for( int i=0; i<70 ; i++ )
+ for (int i=0; i<70 ; i++)
{
- if(t>tmax) break;
- vec2 h = map( ro+rd*t );
- if( abs(h.x)<(0.0001*t) )
+ if (t>tmax) break;
+ vec2 h = map(ro+rd*t);
+ if (abs(h.x)<(0.0001*t))
{
res = vec2(t,h.y);
break;
@@ -113,54 +113,54 @@ vec2 raycast( in vec3 ro, in vec3 rd ){
// https://iquilezles.org/articles/rmshadows
-float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
+float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{
// bounding volume
- float tp = (0.8-ro.y)/rd.y; if( tp>0.0 ) tmax = min( tmax, tp );
+ float tp = (0.8-ro.y)/rd.y; if (tp>0.0) tmax = min(tmax, tp);
float res = 1.0;
float t = mint;
- for( int i=ZERO; i<24; i++ )
+ for (int i=ZERO; i<24; i++)
{
- float h = map( ro + rd*t ).x;
+ float h = map(ro + rd*t).x;
float s = clamp(8.0*h/t,0.0,1.0);
- res = min( res, s );
- t += clamp( h, 0.01, 0.2 );
- if( res<0.004 || t>tmax ) break;
+ res = min(res, s);
+ t += clamp(h, 0.01, 0.2);
+ if (res<0.004 || t>tmax) break;
}
- res = clamp( res, 0.0, 1.0 );
+ res = clamp(res, 0.0, 1.0);
return res*res*(3.0-2.0*res);
}
// https://iquilezles.org/articles/normalsSDF
-vec3 calcNormal( in vec3 pos )
+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 +
- e.xxx*map( pos + e.xxx ).x );
+ 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 +
+ e.xxx*map(pos + e.xxx).x);
}
// https://iquilezles.org/articles/nvscene2008/rwwtt.pdf
-float calcAO( in vec3 pos, in vec3 nor )
+float calcAO(in vec3 pos, in vec3 nor)
{
- float occ = 0.0;
+ float occ = 0.0;
float sca = 1.0;
- for( int i=ZERO; i<5; i++ )
+ for (int i=ZERO; i<5; i++)
{
float h = 0.01 + 0.12*float(i)/4.0;
- float d = map( pos + h*nor ).x;
+ float d = map(pos + h*nor).x;
occ += (h-d)*sca;
sca *= 0.95;
- if( occ>0.35 ) break;
+ if (occ>0.35) break;
}
- return clamp( 1.0 - 3.0*occ, 0.0, 1.0 ) * (0.5+0.5*nor.y);
+ return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y);
}
// https://iquilezles.org/articles/checkerfiltering
-float checkersGradBox( in vec2 p )
+float checkersGradBox(in vec2 p)
{
// filter kernel
vec2 w = fwidth(p) + 0.001;
@@ -171,7 +171,7 @@ float checkersGradBox( in vec2 p )
}
// https://www.shadertoy.com/view/tdS3DG
-vec4 render( in vec3 ro, in vec3 rd)
+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;
@@ -179,37 +179,37 @@ vec4 render( in vec3 ro, in vec3 rd)
// raycast scene
vec2 res = raycast(ro,rd);
float t = res.x;
- float m = res.y;
- if( m>-0.5 )
+ float m = res.y;
+ if (m>-0.5)
{
vec3 pos = ro + t*rd;
- vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos );
- vec3 ref = reflect( rd, nor );
+ vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
+ vec3 ref = reflect(rd, nor);
// material
- col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) );
+ col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
float ks = 1.0;
- if( m<1.5 )
+ if (m<1.5)
{
- float f = checkersGradBox( 3.0*pos.xz);
+ float f = checkersGradBox(3.0*pos.xz);
col = 0.15 + f*vec3(0.05);
ks = 0.4;
}
// lighting
- float occ = calcAO( pos, nor );
+ float occ = calcAO(pos, nor);
- vec3 lin = vec3(0.0);
+ vec3 lin = vec3(0.0);
// sun
{
- vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) );
- vec3 hal = normalize( lig-rd );
- float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
- //if( dif>0.0001 )
- dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
- float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0);
+ vec3 lig = normalize(vec3(-0.5, 0.4, -0.6));
+ vec3 hal = normalize(lig-rd);
+ float dif = clamp(dot(nor, lig), 0.0, 1.0);
+ //if (dif>0.0001)
+ dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
+ float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0);
spe *= dif;
spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
//spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0);
@@ -218,35 +218,35 @@ vec4 render( in vec3 ro, in vec3 rd)
}
// sky
{
- float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 ));
+ float dif = sqrt(clamp(0.5+0.5*nor.y, 0.0, 1.0));
dif *= occ;
- float spe = smoothstep( -0.2, 0.2, ref.y );
+ float spe = smoothstep(-0.2, 0.2, ref.y);
spe *= dif;
- spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 );
- //if( spe>0.001 )
- spe *= calcSoftshadow( pos, ref, 0.02, 2.5 );
+ spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0);
+ //if (spe>0.001)
+ spe *= calcSoftshadow(pos, ref, 0.02, 2.5);
lin += col*0.60*dif*vec3(0.40,0.60,1.15);
lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks;
}
// back
{
- float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
+ float dif = clamp(dot(nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
dif *= occ;
- lin += col*0.55*dif*vec3(0.25,0.25,0.25);
+ lin += col*0.55*dif*vec3(0.25,0.25,0.25);
}
// sss
{
float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0);
dif *= occ;
- lin += col*0.25*dif*vec3(1.00,1.00,1.00);
+ lin += col*0.25*dif*vec3(1.00,1.00,1.00);
}
- col = lin;
+ col = lin;
- col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) );
+ col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
}
- return vec4(vec3( clamp(col,0.0,1.0) ),t);
+ return vec4(vec3(clamp(col,0.0,1.0)),t);
}
vec3 CalcRayDir(vec2 nCoord){
@@ -257,11 +257,11 @@ vec3 CalcRayDir(vec2 nCoord){
mat3 setCamera()
{
- vec3 cw = normalize(camDir);
- vec3 cp = vec3(0.0, 1.0 ,0.0);
- vec3 cu = normalize( cross(cw,cp) );
- vec3 cv = ( cross(cu,cw) );
- return mat3( cu, cv, cw );
+ vec3 cw = normalize(camDir);
+ vec3 cp = vec3(0.0, 1.0 ,0.0);
+ vec3 cu = normalize(cross(cw,cp));
+ vec3 cv = (cross(cu,cw));
+ return mat3(cu, cv, cw);
}
void main()
@@ -271,14 +271,14 @@ void main()
// focal length
float fl = length(camDir);
- vec3 rd = ca * normalize( vec3(nCoord,fl) );
+ vec3 rd = ca*normalize(vec3(nCoord,fl));
vec3 color = vec3(nCoord/2.0 + 0.5, 0.0);
float depth = gl_FragCoord.z;
{
- vec4 res = render( camPos - vec3(0.0, 0.0, 0.0) , rd );
+ vec4 res = render(camPos - vec3(0.0, 0.0, 0.0) , rd);
color = res.xyz;
depth = CalcDepth(rd,res.w);
}
gl_FragColor = vec4(color , 1.0);
- gl_FragDepth = depth;
+ gl_FragDepth = depth;
}
\ No newline at end of file
diff --git a/examples/shaders/resources/shaders/glsl330/julia_set.fs b/examples/shaders/resources/shaders/glsl330/julia_set.fs
index 3a8e25deb..a3e5bec56 100644
--- a/examples/shaders/resources/shaders/glsl330/julia_set.fs
+++ b/examples/shaders/resources/shaders/glsl330/julia_set.fs
@@ -8,11 +8,11 @@ in vec4 fragColor;
out vec4 finalColor;
uniform vec2 c; // c.x = real, c.y = imaginary component. Equation done is z^2 + c
-uniform vec2 offset; // Offset of the scale.
-uniform float zoom; // Zoom of the scale.
+uniform vec2 offset; // Offset of the scale
+uniform float zoom; // Zoom of the scale
-const int maxIterations = 255; // Max iterations to do.
-const float colorCycles = 2.0; // Number of times the color palette repeats. Can show higher detail for higher iteration numbers.
+const int maxIterations = 255; // Max iterations to do
+const float colorCycles = 2.0; // Number of times the color palette repeats. Can show higher detail for higher iteration numbers
// Square a complex number
vec2 ComplexSquare(vec2 z)
@@ -31,22 +31,22 @@ vec3 Hsv2rgb(vec3 c)
void main()
{
/**********************************************************************************************
- Julia sets use a function z^2 + c, where c is a constant.
- This function is iterated until the nature of the point is determined.
+ Julia sets use a function z^2 + c, where c is a constant
+ This function is iterated until the nature of the point is determined
If the magnitude of the number becomes greater than 2, then from that point onward
- the number will get bigger and bigger, and will never get smaller (tends towards infinity).
- 2^2 = 4, 4^2 = 8 and so on.
- So at 2 we stop iterating.
+ the number will get bigger and bigger, and will never get smaller (tends towards infinity)
+ 2^2 = 4, 4^2 = 8 and so on
+ So at 2 we stop iterating
- If the number is below 2, we keep iterating.
+ If the number is below 2, we keep iterating
But when do we stop iterating if the number is always below 2 (it converges)?
- That is what maxIterations is for.
- Then we can divide the iterations by the maxIterations value to get a normalized value that we can
- then map to a color.
+ That is what maxIterations is for
+ Then we can divide the iterations by the maxIterations value to get a normalized value
+ that we can then map to a color
- We use dot product (z.x * z.x + z.y * z.y) to determine the magnitude (length) squared.
- And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power).
+ We use dot product (z.x*z.x + z.y*z.y) to determine the magnitude (length) squared
+ And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power)
*************************************************************************************************/
// The pixel coordinates are scaled so they are on the mandelbrot scale
@@ -63,18 +63,18 @@ void main()
if (dot(z, z) > 4.0) break;
}
- // Another few iterations decreases errors in the smoothing calculation.
- // See http://linas.org/art-gallery/escape/escape.html for more information.
+ // Another few iterations decreases errors in the smoothing calculation
+ // See http://linas.org/art-gallery/escape/escape.html for more information
z = ComplexSquare(z) + c;
z = ComplexSquare(z) + c;
- // This last part smooths the color (again see link above).
+ // This last part smooths the color (again see link above)
float smoothVal = float(iterations) + 1.0 - (log(log(length(z)))/log(2.0));
- // Normalize the value so it is between 0 and 1.
+ // Normalize the value so it is between 0 and 1
float norm = smoothVal/float(maxIterations);
- // If in set, color black. 0.999 allows for some float accuracy error.
+ // If in set, color black. 0.999 allows for some float accuracy error
if (norm > 0.999) finalColor = vec4(0.0, 0.0, 0.0, 1.0);
else finalColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0, 1.0)), 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl330/lighting.fs b/examples/shaders/resources/shaders/glsl330/lighting.fs
index 8f4a51e54..b9abfed77 100644
--- a/examples/shaders/resources/shaders/glsl330/lighting.fs
+++ b/examples/shaders/resources/shaders/glsl330/lighting.fs
@@ -41,7 +41,7 @@ void main()
vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0);
- vec4 tint = colDiffuse * fragColor;
+ vec4 tint = colDiffuse*fragColor;
// NOTE: Implement here your fragment shader code
diff --git a/examples/shaders/resources/shaders/glsl330/lightmap.fs b/examples/shaders/resources/shaders/glsl330/lightmap.fs
index 827473d25..0685e84b1 100644
--- a/examples/shaders/resources/shaders/glsl330/lightmap.fs
+++ b/examples/shaders/resources/shaders/glsl330/lightmap.fs
@@ -19,5 +19,5 @@ void main()
vec4 texelColor = texture(texture0, fragTexCoord);
vec4 texelColor2 = texture(texture1, fragTexCoord2);
- finalColor = texelColor * texelColor2;
+ finalColor = texelColor*texelColor2;
}
diff --git a/examples/shaders/resources/shaders/glsl330/normalmap.fs b/examples/shaders/resources/shaders/glsl330/normalmap.fs
index 644130ab6..697423701 100644
--- a/examples/shaders/resources/shaders/glsl330/normalmap.fs
+++ b/examples/shaders/resources/shaders/glsl330/normalmap.fs
@@ -36,21 +36,21 @@ void main()
normal = texture(normalMap, vec2(fragTexCoord.x, fragTexCoord.y)).rgb;
//Transform normal values to the range -1.0 ... 1.0
- normal = normalize(normal * 2.0 - 1.0);
+ normal = normalize(normal*2.0 - 1.0);
//Transform the normal from tangent-space to world-space for lighting calculation
- normal = normalize(normal * TBN);
+ normal = normalize(normal*TBN);
}
else
{
normal = normalize(fragNormal);
}
- vec4 tint = colDiffuse * fragColor;
+ vec4 tint = colDiffuse*fragColor;
vec3 lightColor = vec3(1.0, 1.0, 1.0);
float NdotL = max(dot(normal, lightDir), 0.0);
- vec3 lightDot = lightColor * NdotL;
+ vec3 lightDot = lightColor*NdotL;
float specCo = 0.0;
@@ -58,10 +58,10 @@ void main()
specular += specCo;
- finalColor = (texelColor * ((tint + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
- finalColor += texelColor * (vec4(1.0, 1.0, 1.0, 1.0) / 40.0) * tint;
+ finalColor = (texelColor*((tint + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
+ finalColor += texelColor*(vec4(1.0, 1.0, 1.0, 1.0)/40.0)*tint;
// Gamma correction
- finalColor = pow(finalColor, vec4(1.0 / 2.2));
+ finalColor = pow(finalColor, vec4(1.0/2.2));
//finalColor = vec4(normal, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl330/normalmap.vs b/examples/shaders/resources/shaders/glsl330/normalmap.vs
index 1e0a161b8..58fff39b9 100644
--- a/examples/shaders/resources/shaders/glsl330/normalmap.vs
+++ b/examples/shaders/resources/shaders/glsl330/normalmap.vs
@@ -21,21 +21,21 @@ out mat3 TBN;
void main()
{
// Compute binormal from vertex normal and tangent. W component is the tangent handedness
- vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
+ vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz)*vertexTangent.w;
// Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Compute fragment position based on model transformations
- fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
+ fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
//Create TBN matrix for transforming the normal map values from tangent-space to world-space
- fragNormal = normalize(normalMatrix * vertexNormal);
+ fragNormal = normalize(normalMatrix*vertexNormal);
- vec3 fragTangent = normalize(normalMatrix * vertexTangent.xyz);
- fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal) * fragNormal);
+ vec3 fragTangent = normalize(normalMatrix*vertexTangent.xyz);
+ fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
- vec3 fragBinormal = normalize(normalMatrix * vertexBinormal);
+ vec3 fragBinormal = normalize(normalMatrix*vertexBinormal);
fragBinormal = cross(fragNormal, fragTangent);
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
@@ -44,5 +44,5 @@ void main()
fragTexCoord = vertexTexCoord;
- gl_Position = mvp * vec4(vertexPosition, 1.0);
+ gl_Position = mvp*vec4(vertexPosition, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl330/pbr.vs b/examples/shaders/resources/shaders/glsl330/pbr.vs
index 8aabb6baf..0fc7888d3 100644
--- a/examples/shaders/resources/shaders/glsl330/pbr.vs
+++ b/examples/shaders/resources/shaders/glsl330/pbr.vs
@@ -26,7 +26,7 @@ const float normalOffset = 0.1;
void main()
{
// Compute binormal from vertex normal and tangent
- vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz) * vertexTangent.w;
+ vec3 vertexBinormal = cross(vertexNormal, vertexTangent.xyz)*vertexTangent.w;
// Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
diff --git a/examples/shaders/resources/shaders/glsl330/raymarching.fs b/examples/shaders/resources/shaders/glsl330/raymarching.fs
index 6a9eb4516..67446cdc8 100644
--- a/examples/shaders/resources/shaders/glsl330/raymarching.fs
+++ b/examples/shaders/resources/shaders/glsl330/raymarching.fs
@@ -33,7 +33,7 @@ uniform vec2 resolution;
// SOFTWARE.
// A list of useful distance function to simple primitives, and an example on how to
-// do some interesting boolean operations, repetition and displacement.
+// do some interesting boolean operations, repetition and displacement
//
// More info here: http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
@@ -41,38 +41,38 @@ uniform vec2 resolution;
//------------------------------------------------------------------
-float sdPlane( vec3 p )
+float sdPlane(vec3 p)
{
return p.y;
}
-float sdSphere( vec3 p, float s )
+float sdSphere(vec3 p, float s)
{
return length(p)-s;
}
-float sdBox( vec3 p, vec3 b )
+float sdBox(vec3 p, vec3 b)
{
vec3 d = abs(p) - b;
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}
-float sdEllipsoid( in vec3 p, in vec3 r )
+float sdEllipsoid(in vec3 p, in vec3 r)
{
- return (length( p/r ) - 1.0) * min(min(r.x,r.y),r.z);
+ return (length(p/r) - 1.0)*min(min(r.x,r.y),r.z);
}
-float udRoundBox( vec3 p, vec3 b, float r )
+float udRoundBox(vec3 p, vec3 b, float r)
{
return length(max(abs(p)-b,0.0))-r;
}
-float sdTorus( vec3 p, vec2 t )
+float sdTorus(vec3 p, vec2 t)
{
- return length( vec2(length(p.xz)-t.x,p.y) )-t.y;
+ return length(vec2(length(p.xz)-t.x,p.y))-t.y;
}
-float sdHexPrism( vec3 p, vec2 h )
+float sdHexPrism(vec3 p, vec2 h)
{
vec3 q = abs(p);
#if 0
@@ -84,24 +84,24 @@ float sdHexPrism( vec3 p, vec2 h )
#endif
}
-float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
+float sdCapsule(vec3 p, vec3 a, vec3 b, float r)
{
vec3 pa = p-a, ba = b-a;
- float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
- return length( pa - ba*h ) - r;
+ float h = clamp(dot(pa,ba)/dot(ba,ba), 0.0, 1.0);
+ return length(pa - ba*h) - r;
}
-float sdEquilateralTriangle( in vec2 p )
+float sdEquilateralTriangle( in vec2 p)
{
const float k = sqrt(3.0);
p.x = abs(p.x) - 1.0;
p.y = p.y + 1.0/k;
- if( p.x + k*p.y > 0.0 ) p = vec2( p.x - k*p.y, -k*p.x - p.y )/2.0;
- p.x += 2.0 - 2.0*clamp( (p.x+2.0)/2.0, 0.0, 1.0 );
+ if (p.x + k*p.y > 0.0) p = vec2(p.x - k*p.y, -k*p.x - p.y)/2.0;
+ p.x += 2.0 - 2.0*clamp((p.x+2.0)/2.0, 0.0, 1.0);
return -length(p)*sign(p.y);
}
-float sdTriPrism( vec3 p, vec2 h )
+float sdTriPrism(vec3 p, vec2 h)
{
vec3 q = abs(p);
float d1 = q.z-h.y;
@@ -116,95 +116,95 @@ float sdTriPrism( vec3 p, vec2 h )
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdCylinder( vec3 p, vec2 h )
+float sdCylinder(vec3 p, vec2 h)
{
vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
-float sdCone( in vec3 p, in vec3 c )
+float sdCone(in vec3 p, in vec3 c)
{
- vec2 q = vec2( length(p.xz), p.y );
+ vec2 q = vec2(length(p.xz), p.y);
float d1 = -q.y-c.z;
- float d2 = max( dot(q,c.xy), q.y);
+ float d2 = max(dot(q,c.xy), q.y);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdConeSection( in vec3 p, in float h, in float r1, in float r2 )
+float sdConeSection(in vec3 p, in float h, in float r1, in float r2)
{
float d1 = -p.y - h;
float q = p.y - h;
float si = 0.5*(r1-r2)/h;
- float d2 = max( sqrt( dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q );
+ float d2 = max(sqrt(dot(p.xz,p.xz)*(1.0-si*si)) + q*si - r2, q);
return length(max(vec2(d1,d2),0.0)) + min(max(d1,d2), 0.);
}
-float sdPryamid4(vec3 p, vec3 h ) // h = { cos a, sin a, height }
+float sdPryamid4(vec3 p, vec3 h) // h = { cos a, sin a, height }
{
// Tetrahedron = Octahedron - Cube
- float box = sdBox( p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z) );
+ float box = sdBox(p - vec3(0,-2.0*h.z,0), vec3(2.0*h.z));
float d = 0.0;
- d = max( d, abs( dot(p, vec3( -h.x, h.y, 0 )) ));
- d = max( d, abs( dot(p, vec3( h.x, h.y, 0 )) ));
- d = max( d, abs( dot(p, vec3( 0, h.y, h.x )) ));
- d = max( d, abs( dot(p, vec3( 0, h.y,-h.x )) ));
+ d = max(d, abs(dot(p, vec3(-h.x, h.y, 0))));
+ d = max(d, abs(dot(p, vec3( h.x, h.y, 0))));
+ d = max(d, abs(dot(p, vec3( 0, h.y, h.x))));
+ d = max(d, abs(dot(p, vec3( 0, h.y,-h.x))));
float octa = d - h.z;
return max(-box,octa); // Subtraction
}
-float length2( vec2 p )
+float length2(vec2 p)
{
- return sqrt( p.x*p.x + p.y*p.y );
+ return sqrt(p.x*p.x + p.y*p.y);
}
-float length6( vec2 p )
+float length6(vec2 p)
{
p = p*p*p; p = p*p;
- return pow( p.x + p.y, 1.0/6.0 );
+ return pow(p.x + p.y, 1.0/6.0);
}
-float length8( vec2 p )
+float length8(vec2 p)
{
p = p*p; p = p*p; p = p*p;
- return pow( p.x + p.y, 1.0/8.0 );
+ return pow(p.x + p.y, 1.0/8.0);
}
-float sdTorus82( vec3 p, vec2 t )
+float sdTorus82(vec3 p, vec2 t)
{
vec2 q = vec2(length2(p.xz)-t.x,p.y);
return length8(q)-t.y;
}
-float sdTorus88( vec3 p, vec2 t )
+float sdTorus88(vec3 p, vec2 t)
{
vec2 q = vec2(length8(p.xz)-t.x,p.y);
return length8(q)-t.y;
}
-float sdCylinder6( vec3 p, vec2 h )
+float sdCylinder6(vec3 p, vec2 h)
{
- return max( length6(p.xz)-h.x, abs(p.y)-h.y );
+ return max(length6(p.xz)-h.x, abs(p.y)-h.y);
}
//------------------------------------------------------------------
-float opS( float d1, float d2 )
+float opS(float d1, float d2)
{
return max(-d2,d1);
}
-vec2 opU( vec2 d1, vec2 d2 )
+vec2 opU(vec2 d1, vec2 d2)
{
return (d1.x0.0 ) tmax = min( tmax, tp1 );
- float tp2 = (1.6-ro.y)/rd.y; if( tp2>0.0 ) { if( ro.y>1.6 ) tmin = max( tmin, tp2 );
- else tmax = min( tmax, tp2 ); }
+ float tp1 = (0.0-ro.y)/rd.y; if (tp1>0.0) tmax = min(tmax, tp1);
+ float tp2 = (1.6-ro.y)/rd.y; if (tp2>0.0) { if (ro.y>1.6) tmin = max(tmin, tp2);
+ else tmax = min(tmax, tp2); }
#endif
float t = tmin;
float m = -1.0;
- for( int i=0; i<64; i++ )
+ for (int i=0; i<64; i++)
{
float precis = 0.0005*t;
- vec2 res = map( ro+rd*t );
- if( res.xtmax ) break;
+ vec2 res = map(ro+rd*t);
+ if (res.xtmax) break;
t += res.x;
m = res.y;
}
- if( t>tmax ) m=-1.0;
- return vec2( t, m );
+ if (t>tmax) m=-1.0;
+ return vec2(t, m);
}
-float calcSoftshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax )
+float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
{
float res = 1.0;
float t = mint;
- for( int i=0; i<16; i++ )
+ for (int i=0; i<16; i++)
{
- float h = map( ro + rd*t ).x;
- res = min( res, 8.0*h/t );
- t += clamp( h, 0.02, 0.10 );
- if( h<0.001 || t>tmax ) break;
+ float h = map(ro + rd*t).x;
+ res = min(res, 8.0*h/t);
+ t += clamp(h, 0.02, 0.10);
+ if (h<0.001 || t>tmax) break;
}
- return clamp( res, 0.0, 1.0 );
+ return clamp(res, 0.0, 1.0);
}
-vec3 calcNormal( in vec3 pos )
+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 +
- e.xxx*map( pos + e.xxx ).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);
/*
- vec3 eps = vec3( 0.0005, 0.0, 0.0 );
+ vec3 eps = vec3(0.0005, 0.0, 0.0);
vec3 nor = vec3(
map(pos+eps.xyy).x - map(pos-eps.xyy).x,
map(pos+eps.yxy).x - map(pos-eps.yxy).x,
- map(pos+eps.yyx).x - map(pos-eps.yyx).x );
+ map(pos+eps.yyx).x - map(pos-eps.yyx).x);
return normalize(nor);
*/
}
-float calcAO( in vec3 pos, in vec3 nor )
+float calcAO(in vec3 pos, in vec3 nor)
{
float occ = 0.0;
float sca = 1.0;
- for( int i=0; i<5; i++ )
+ for (int i=0; i<5; i++)
{
float hr = 0.01 + 0.12*float(i)/4.0;
- vec3 aopos = nor * hr + pos;
- float dd = map( aopos ).x;
+ vec3 aopos = nor*hr + pos;
+ float dd = map(aopos).x;
occ += -(dd-hr)*sca;
sca *= 0.95;
}
- return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
+ return clamp(1.0 - 3.0*occ, 0.0, 1.0);
}
// http://iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm
-float checkersGradBox( in vec2 p )
+float checkersGradBox(in vec2 p)
{
// filter kernel
vec2 w = fwidth(p) + 0.001;
@@ -327,43 +327,43 @@ float checkersGradBox( in vec2 p )
return 0.5 - 0.5*i.x*i.y;
}
-vec3 render( in vec3 ro, in vec3 rd )
+vec3 render(in vec3 ro, in vec3 rd)
{
vec3 col = vec3(0.7, 0.9, 1.0) +rd.y*0.8;
vec2 res = castRay(ro,rd);
float t = res.x;
float m = res.y;
- if( m>-0.5 )
+ if (m>-0.5)
{
vec3 pos = ro + t*rd;
- vec3 nor = calcNormal( pos );
- vec3 ref = reflect( rd, nor );
+ vec3 nor = calcNormal(pos);
+ vec3 ref = reflect(rd, nor);
// material
- col = 0.45 + 0.35*sin( vec3(0.05,0.08,0.10)*(m-1.0) );
- if( m<1.5 )
+ col = 0.45 + 0.35*sin(vec3(0.05,0.08,0.10)*(m-1.0));
+ if (m<1.5)
{
- float f = checkersGradBox( 5.0*pos.xz );
+ float f = checkersGradBox(5.0*pos.xz);
col = 0.3 + f*vec3(0.1);
}
// lighting
- float occ = calcAO( pos, nor );
- vec3 lig = normalize( vec3(cos(-0.4 * runTime), sin(0.7 * runTime), -0.6) );
- vec3 hal = normalize( lig-rd );
- float amb = clamp( 0.5+0.5*nor.y, 0.0, 1.0 );
- float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
- float bac = clamp( dot( nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0);
- float dom = smoothstep( -0.1, 0.1, ref.y );
- float fre = pow( clamp(1.0+dot(nor,rd),0.0,1.0), 2.0 );
+ float occ = calcAO(pos, nor);
+ vec3 lig = normalize(vec3(cos(-0.4*runTime), sin(0.7*runTime), -0.6));
+ vec3 hal = normalize(lig-rd);
+ float amb = clamp(0.5+0.5*nor.y, 0.0, 1.0);
+ float dif = clamp(dot(nor, lig), 0.0, 1.0);
+ float bac = clamp(dot(nor, normalize(vec3(-lig.x,0.0,-lig.z))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
+ float dom = smoothstep(-0.1, 0.1, ref.y);
+ float fre = pow(clamp(1.0+dot(nor,rd),0.0,1.0), 2.0);
- dif *= calcSoftshadow( pos, lig, 0.02, 2.5 );
- dom *= calcSoftshadow( pos, ref, 0.02, 2.5 );
+ dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
+ dom *= calcSoftshadow(pos, ref, 0.02, 2.5);
- float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0)*
+ float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0)*
dif *
- (0.04 + 0.96*pow( clamp(1.0+dot(hal,rd),0.0,1.0), 5.0 ));
+ (0.04 + 0.96*pow(clamp(1.0+dot(hal,rd),0.0,1.0), 5.0));
vec3 lin = vec3(0.0);
lin += 1.30*dif*vec3(1.00,0.80,0.55);
@@ -374,51 +374,51 @@ vec3 render( in vec3 ro, in vec3 rd )
col = col*lin;
col += 10.00*spe*vec3(1.00,0.90,0.70);
- col = mix( col, vec3(0.8,0.9,1.0), 1.0-exp( -0.0002*t*t*t ) );
+ col = mix(col, vec3(0.8,0.9,1.0), 1.0-exp(-0.0002*t*t*t));
}
- return vec3( clamp(col,0.0,1.0) );
+ return vec3(clamp(col,0.0,1.0));
}
-mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
+mat3 setCamera(in vec3 ro, in vec3 ta, float cr)
{
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
- vec3 cu = normalize( cross(cw,cp) );
- vec3 cv = normalize( cross(cu,cw) );
- return mat3( cu, cv, cw );
+ vec3 cu = normalize(cross(cw,cp));
+ vec3 cv = normalize(cross(cu,cw));
+ return mat3(cu, cv, cw);
}
void main()
{
vec3 tot = vec3(0.0);
#if AA>1
- for( int m=0; m1
@@ -426,5 +426,5 @@ void main()
tot /= float(AA*AA);
#endif
- finalColor = vec4( tot, 1.0 );
+ finalColor = vec4(tot, 1.0);
}
diff --git a/examples/shaders/resources/shaders/glsl330/scanlines.fs b/examples/shaders/resources/shaders/glsl330/scanlines.fs
index 4de19cf11..77d8f63bc 100644
--- a/examples/shaders/resources/shaders/glsl330/scanlines.fs
+++ b/examples/shaders/resources/shaders/glsl330/scanlines.fs
@@ -39,7 +39,7 @@ void main()
fragColor = color;
*/
// Scanlines method 2
- float globalPos = (fragTexCoord.y + offset) * frequency;
+ float globalPos = (fragTexCoord.y + offset)*frequency;
float wavePos = cos((fract(globalPos) - 0.5)*3.14);
// Texel color fetching from texture sampler
diff --git a/examples/shaders/resources/shaders/glsl330/shadowmap.fs b/examples/shaders/resources/shaders/glsl330/shadowmap.fs
index d535de2bc..6ad41461c 100644
--- a/examples/shaders/resources/shaders/glsl330/shadowmap.fs
+++ b/examples/shaders/resources/shaders/glsl330/shadowmap.fs
@@ -49,13 +49,13 @@ void main()
finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
// Shadow calculations
- vec4 fragPosLightSpace = lightVP * vec4(fragPosition, 1);
+ vec4 fragPosLightSpace = lightVP*vec4(fragPosition, 1);
fragPosLightSpace.xyz /= fragPosLightSpace.w; // Perform the perspective division
fragPosLightSpace.xyz = (fragPosLightSpace.xyz + 1.0)/2.0; // Transform from [-1, 1] range to [0, 1] range
vec2 sampleCoords = fragPosLightSpace.xy;
float curDepth = fragPosLightSpace.z;
- // Slope-scale depth bias: depth biasing reduces "shadow acne" artifacts, where dark stripes appear all over the scene.
+ // Slope-scale depth bias: depth biasing reduces "shadow acne" artifacts, where dark stripes appear all over the scene
// The solution is adding a small bias to the depth
// In this case, the bias is proportional to the slope of the surface, relative to the light
float bias = max(0.0002*(1.0 - dot(normal, l)), 0.00002) + 0.00001;
@@ -64,8 +64,8 @@ void main()
// 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.
- // This blurs shadow edges, hiding aliasing artifacts.
+ // we test the surrounding points as well
+ // This blurs shadow edges, hiding aliasing artifacts
vec2 texelSize = vec2(1.0/float(shadowMapResolution));
for (int x = -1; x <= 1; x++)
{
diff --git a/examples/shaders/resources/shaders/glsl330/sobel.fs b/examples/shaders/resources/shaders/glsl330/sobel.fs
index 590c84d70..a8005cb56 100644
--- a/examples/shaders/resources/shaders/glsl330/sobel.fs
+++ b/examples/shaders/resources/shaders/glsl330/sobel.fs
@@ -21,10 +21,10 @@ void main()
vec4 horizEdge = vec4(0.0);
horizEdge -= texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y))*1.0;
- horizEdge -= texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
+ horizEdge -= texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y ))*2.0;
horizEdge -= texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y))*1.0;
horizEdge += texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y))*1.0;
- horizEdge += texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
+ horizEdge += texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y ))*2.0;
horizEdge += texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y))*1.0;
vec4 vertEdge = vec4(0.0);
diff --git a/examples/shaders/resources/shaders/glsl330/spotlight.fs b/examples/shaders/resources/shaders/glsl330/spotlight.fs
index 9c0b70363..b3e89ebdf 100644
--- a/examples/shaders/resources/shaders/glsl330/spotlight.fs
+++ b/examples/shaders/resources/shaders/glsl330/spotlight.fs
@@ -53,7 +53,7 @@ void main()
else
{
if (d < spots[fi].inner) alpha = 0.0;
- else alpha = (d - spots[fi].inner) / (spots[fi].radius - spots[fi].inner);
+ else alpha = (d - spots[fi].inner)/(spots[fi].radius - spots[fi].inner);
}
}
diff --git a/examples/shaders/resources/shaders/glsl330/vertex_displacement.vs b/examples/shaders/resources/shaders/glsl330/vertex_displacement.vs
index 73cf16109..080ad473a 100644
--- a/examples/shaders/resources/shaders/glsl330/vertex_displacement.vs
+++ b/examples/shaders/resources/shaders/glsl330/vertex_displacement.vs
@@ -24,13 +24,13 @@ out float height;
void main()
{
// Calculate animated texture coordinates based on time and vertex position
- vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x * 0.1), cos(time + vertexPosition.z * 0.1)) * 0.3);
+ vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x*0.1), cos(time + vertexPosition.z*0.1))*0.3);
// Normalize animated texture coordinates to range [0, 1]
- animatedTexCoord = animatedTexCoord * 0.5 + 0.5;
+ animatedTexCoord = animatedTexCoord*0.5 + 0.5;
// Fetch displacement from the perlin noise map
- float displacement = texture(perlinNoiseMap, animatedTexCoord).r * 7; // Amplified displacement
+ float displacement = texture(perlinNoiseMap, animatedTexCoord).r*7; // Amplified displacement
// Displace vertex position
vec3 displacedPosition = vertexPosition + vec3(0.0, displacement, 0.0);
@@ -39,7 +39,7 @@ void main()
fragPosition = vec3(matModel*vec4(displacedPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
- height = displacedPosition.y * 0.2; // send height to fragment shader for coloring
+ height = displacedPosition.y*0.2; // send height to fragment shader for coloring
// Calculate final vertex position
gl_Position = mvp*vec4(displacedPosition , 1.0);
diff --git a/examples/shaders/resources/shaders/glsl330/wave.fs b/examples/shaders/resources/shaders/glsl330/wave.fs
index 1f22bee09..393f1bde2 100644
--- a/examples/shaders/resources/shaders/glsl330/wave.fs
+++ b/examples/shaders/resources/shaders/glsl330/wave.fs
@@ -23,15 +23,15 @@ uniform float speedX;
uniform float speedY;
void main() {
- float pixelWidth = 1.0 / size.x;
- float pixelHeight = 1.0 / size.y;
- float aspect = pixelHeight / pixelWidth;
+ float pixelWidth = 1.0/size.x;
+ float pixelHeight = 1.0/size.y;
+ float aspect = pixelHeight/pixelWidth;
float boxLeft = 0.0;
float boxTop = 0.0;
vec2 p = fragTexCoord;
- p.x += cos((fragTexCoord.y - boxTop) * freqX / ( pixelWidth * 750.0) + (seconds * speedX)) * ampX * pixelWidth;
- p.y += sin((fragTexCoord.x - boxLeft) * freqY * aspect / ( pixelHeight * 750.0) + (seconds * speedY)) * ampY * pixelHeight;
+ p.x += cos((fragTexCoord.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
+ p.y += sin((fragTexCoord.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
finalColor = texture(texture0, p)*colDiffuse*fragColor;
}
diff --git a/examples/shaders/shaders_basic_pbr.c b/examples/shaders/shaders_basic_pbr.c
index 2dff5d562..49c03eb31 100644
--- a/examples/shaders/shaders_basic_pbr.c
+++ b/examples/shaders/shaders_basic_pbr.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Basic PBR
+* raylib [shaders] example - basic pbr
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/shaders/shaders_custom_uniform.c b/examples/shaders/shaders_custom_uniform.c
index f73c5e901..740f1aa90 100644
--- a/examples/shaders/shaders_custom_uniform.c
+++ b/examples/shaders/shaders_custom_uniform.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Postprocessing with custom uniform variable
+* raylib [shaders] example - custom uniform variable
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shaders/shaders_deferred_render.c b/examples/shaders/shaders_deferred_render.c
index 96c118c61..c0bdd9f98 100644
--- a/examples/shaders/shaders_deferred_render.c
+++ b/examples/shaders/shaders_deferred_render.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - deferred rendering
+* raylib [shaders] example - deferred render
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/shaders/shaders_hybrid_render.c b/examples/shaders/shaders_hybrid_render.c
index 63ae1e16b..3c6ef1531 100644
--- a/examples/shaders/shaders_hybrid_render.c
+++ b/examples/shaders/shaders_hybrid_render.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - hybrid rendering
+* raylib [shaders] example - write depth buffer
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/shaders/shaders_julia_set.c b/examples/shaders/shaders_julia_set.c
index da5564321..a9c5f5944 100644
--- a/examples/shaders/shaders_julia_set.c
+++ b/examples/shaders/shaders_julia_set.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Julia sets
+* raylib [shaders] example - julia sets
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/shaders/shaders_mesh_instancing.c b/examples/shaders/shaders_mesh_instancing.c
index 6142a825e..c3c7a9d16 100644
--- a/examples/shaders/shaders_mesh_instancing.c
+++ b/examples/shaders/shaders_mesh_instancing.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Mesh instancing
+* raylib [shaders] example - mesh instancing
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/shaders/shaders_model_shader.c b/examples/shaders/shaders_model_shader.c
index 75cfec4d5..4c6d1df91 100644
--- a/examples/shaders/shaders_model_shader.c
+++ b/examples/shaders/shaders_model_shader.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Model shader
+* raylib [shaders] example - model shader
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shaders/shaders_normalmap.c b/examples/shaders/shaders_normal_map.c
similarity index 99%
rename from examples/shaders/shaders_normalmap.c
rename to examples/shaders/shaders_normal_map.c
index 656c8597e..3a8180fef 100644
--- a/examples/shaders/shaders_normalmap.c
+++ b/examples/shaders/shaders_normal_map.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
- * raylib [shaders] example - normalmap
+ * raylib [shaders] example - normal map
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/shaders/shaders_normalmap.png b/examples/shaders/shaders_normal_map.png
similarity index 100%
rename from examples/shaders/shaders_normalmap.png
rename to examples/shaders/shaders_normal_map.png
diff --git a/examples/shaders/shaders_palette_switch.c b/examples/shaders/shaders_palette_switch.c
index df35db447..1384c7332 100644
--- a/examples/shaders/shaders_palette_switch.c
+++ b/examples/shaders/shaders_palette_switch.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Color palette switch
+* raylib [shaders] example - color palette switch
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/shaders/shaders_postprocessing.c b/examples/shaders/shaders_postprocessing.c
index 623152bae..9c152faad 100644
--- a/examples/shaders/shaders_postprocessing.c
+++ b/examples/shaders/shaders_postprocessing.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Apply a postprocessing shader to a scene
+* raylib [shaders] example - postprocessing shader
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/shaders/shaders_raymarching.c b/examples/shaders/shaders_raymarching.c
index cc1badb9f..744181680 100644
--- a/examples/shaders/shaders_raymarching.c
+++ b/examples/shaders/shaders_raymarching.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Raymarching shapes generation
+* raylib [shaders] example - raymarching shapes
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/shaders/shaders_shadowmap.c b/examples/shaders/shaders_shadowmap.c
index ec06dee42..4ddb4e896 100644
--- a/examples/shaders/shaders_shadowmap.c
+++ b/examples/shaders/shaders_shadowmap.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Shadowmap
+* raylib [shaders] example - shadowmap
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/shaders/shaders_shapes_textures.c b/examples/shaders/shaders_shapes_textures.c
index b0f7752ac..080cfabbd 100644
--- a/examples/shaders/shaders_shapes_textures.c
+++ b/examples/shaders/shaders_shapes_textures.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Apply a shader to some shape or texture
+* raylib [shaders] example - shapes and texture shaders
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shaders/shaders_simple_mask.c b/examples/shaders/shaders_simple_mask.c
index 2e6e83a61..df8310a9d 100644
--- a/examples/shaders/shaders_simple_mask.c
+++ b/examples/shaders/shaders_simple_mask.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Simple shader mask
+* raylib [shaders] example - simple shader mask
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shaders/shaders_spotlight.c b/examples/shaders/shaders_spotlight.c
index 3df7ceda8..c6932da31 100644
--- a/examples/shaders/shaders_spotlight.c
+++ b/examples/shaders/shaders_spotlight.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Simple shader mask
+* raylib [shaders] example - shader spotlight
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shaders/shaders_texture_drawing.c b/examples/shaders/shaders_texture_drawing.c
index 2cfe7e64d..dc51f333a 100644
--- a/examples/shaders/shaders_texture_drawing.c
+++ b/examples/shaders/shaders_texture_drawing.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Texture drawing
+* raylib [shaders] example - texture drawing
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shaders/shaders_texture_waves.c b/examples/shaders/shaders_texture_waves.c
index c957635c4..22e6334cb 100644
--- a/examples/shaders/shaders_texture_waves.c
+++ b/examples/shaders/shaders_texture_waves.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Texture Waves
+* raylib [shaders] example - texture waves
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shaders/shaders_vertex_displacement.c b/examples/shaders/shaders_vertex_displacement.c
index 1a163f9b7..3eff34e00 100644
--- a/examples/shaders/shaders_vertex_displacement.c
+++ b/examples/shaders/shaders_vertex_displacement.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - Vertex displacement
+* raylib [shaders] example - vertex displacement
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/shaders/shaders_write_depth.c b/examples/shaders/shaders_write_depth.c
index 96016521b..a71a27d9d 100644
--- a/examples/shaders/shaders_write_depth.c
+++ b/examples/shaders/shaders_write_depth.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shaders] example - depth buffer writing
+* raylib [shaders] example - write depth buffer
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shapes/shapes_basic_shapes.c b/examples/shapes/shapes_basic_shapes.c
index 0302a2ef5..d0801ab0b 100644
--- a/examples/shapes/shapes_basic_shapes.c
+++ b/examples/shapes/shapes_basic_shapes.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - Draw basic shapes 2d (rectangle, circle, line...)
+* raylib [shapes] example - basic shapes drawing
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/shapes/shapes_colors_palette.c b/examples/shapes/shapes_colors_palette.c
index 81d008ff0..9fbcf3063 100644
--- a/examples/shapes/shapes_colors_palette.c
+++ b/examples/shapes/shapes_colors_palette.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - Colors palette
+* raylib [shapes] example - colors palette
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shapes/shapes_digital_clock.c b/examples/shapes/shapes_digital_clock.c
index ffa1ff5dc..671e1ab14 100644
--- a/examples/shapes/shapes_digital_clock.c
+++ b/examples/shapes/shapes_digital_clock.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - fancy clock using basic shapes
+* raylib [shapes] example - digital clock
*
* Example complexity rating: [★★☆☆] 2/4
*
@@ -182,4 +182,4 @@ static void DrawClock(Clock clock, Vector2 centerPosition)
DrawRectanglePro((Rectangle){ centerPosition.x, centerPosition.y, clock.hour.length, clock.hour.thickness },
(Vector2){ 0.0f, clock.hour.thickness/2.0f }, clock.hour.angle, clock.hour.color);
}
-}
\ No newline at end of file
+}
diff --git a/examples/shapes/shapes_double_pendulum.c b/examples/shapes/shapes_double_pendulum.c
index fd486db84..0f9224e9f 100644
--- a/examples/shapes/shapes_double_pendulum.c
+++ b/examples/shapes/shapes_double_pendulum.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - Double Pendulum
+* raylib [shapes] example - double pendulum
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/shapes/shapes_draw_circle_sector.c b/examples/shapes/shapes_draw_circle_sector.c
index 1485c464e..4bc7ffa6c 100644
--- a/examples/shapes/shapes_draw_circle_sector.c
+++ b/examples/shapes/shapes_draw_circle_sector.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - draw circle sector (with gui options)
+* raylib [shapes] example - draw circle sector
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/shapes/shapes_draw_rectangle_rounded.c b/examples/shapes/shapes_draw_rectangle_rounded.c
index 614ed54b1..ebefe055f 100644
--- a/examples/shapes/shapes_draw_rectangle_rounded.c
+++ b/examples/shapes/shapes_draw_rectangle_rounded.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - draw rectangle rounded (with gui options)
+* raylib [shapes] example - draw rectangle rounded
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/shapes/shapes_draw_ring.c b/examples/shapes/shapes_draw_ring.c
index f7a18bdec..c3a13729d 100644
--- a/examples/shapes/shapes_draw_ring.c
+++ b/examples/shapes/shapes_draw_ring.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - draw ring (with gui options)
+* raylib [shapes] example - draw ring
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/shapes/shapes_lines_bezier.c b/examples/shapes/shapes_lines_bezier.c
index 3e8f68a7f..1e0600edf 100644
--- a/examples/shapes/shapes_lines_bezier.c
+++ b/examples/shapes/shapes_lines_bezier.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - Cubic-bezier lines
+* raylib [shapes] example - cubic-bezier lines
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/shapes/shapes_logo_raylib.c b/examples/shapes/shapes_logo_raylib.c
index e7977e580..b468e3b19 100644
--- a/examples/shapes/shapes_logo_raylib.c
+++ b/examples/shapes/shapes_logo_raylib.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - draw raylib logo using basic shapes
+* raylib [shapes] example - raylib logo using shapes
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/shapes/shapes_rectangle_advanced.c b/examples/shapes/shapes_rectangle_advanced.c
index a3f8adf84..4f04c2854 100644
--- a/examples/shapes/shapes_rectangle_advanced.c
+++ b/examples/shapes/shapes_rectangle_advanced.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - advanced rectangle drawing
+* raylib [shapes] example - rectangle avanced
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/shapes/shapes_rectangle_scaling.c b/examples/shapes/shapes_rectangle_scaling.c
index 7426e54d5..5ee03d7aa 100644
--- a/examples/shapes/shapes_rectangle_scaling.c
+++ b/examples/shapes/shapes_rectangle_scaling.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [shapes] example - rectangle scaling by mouse
+* raylib [shapes] example - rectangle scaling mouse
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/text/resources/NotoSansTC-Regular.ttf b/examples/text/resources/NotoSansTC-Regular.ttf
new file mode 100644
index 000000000..e838ef549
Binary files /dev/null and b/examples/text/resources/NotoSansTC-Regular.ttf differ
diff --git a/examples/text/resources/shaders/glsl330/alpha_discard.fs b/examples/text/resources/shaders/glsl330/alpha_discard.fs
index d2134a688..3e2673d0d 100644
--- a/examples/text/resources/shaders/glsl330/alpha_discard.fs
+++ b/examples/text/resources/shaders/glsl330/alpha_discard.fs
@@ -15,5 +15,5 @@ void main()
{
vec4 texelColor = texture(texture0, fragTexCoord);
if (texelColor.a == 0.0) discard;
- finalColor = texelColor * fragColor * colDiffuse;
+ finalColor = texelColor*fragColor*colDiffuse;
}
diff --git a/examples/text/resources/fonts/alagard.png b/examples/text/resources/sprite_fonts/alagard.png
similarity index 100%
rename from examples/text/resources/fonts/alagard.png
rename to examples/text/resources/sprite_fonts/alagard.png
diff --git a/examples/text/resources/fonts/alpha_beta.png b/examples/text/resources/sprite_fonts/alpha_beta.png
similarity index 100%
rename from examples/text/resources/fonts/alpha_beta.png
rename to examples/text/resources/sprite_fonts/alpha_beta.png
diff --git a/examples/text/resources/fonts/jupiter_crash.png b/examples/text/resources/sprite_fonts/jupiter_crash.png
similarity index 100%
rename from examples/text/resources/fonts/jupiter_crash.png
rename to examples/text/resources/sprite_fonts/jupiter_crash.png
diff --git a/examples/text/resources/fonts/mecha.png b/examples/text/resources/sprite_fonts/mecha.png
similarity index 100%
rename from examples/text/resources/fonts/mecha.png
rename to examples/text/resources/sprite_fonts/mecha.png
diff --git a/examples/text/resources/fonts/pixantiqua.png b/examples/text/resources/sprite_fonts/pixantiqua.png
similarity index 100%
rename from examples/text/resources/fonts/pixantiqua.png
rename to examples/text/resources/sprite_fonts/pixantiqua.png
diff --git a/examples/text/resources/fonts/pixelplay.png b/examples/text/resources/sprite_fonts/pixelplay.png
similarity index 100%
rename from examples/text/resources/fonts/pixelplay.png
rename to examples/text/resources/sprite_fonts/pixelplay.png
diff --git a/examples/text/resources/fonts/romulus.png b/examples/text/resources/sprite_fonts/romulus.png
similarity index 100%
rename from examples/text/resources/fonts/romulus.png
rename to examples/text/resources/sprite_fonts/romulus.png
diff --git a/examples/text/resources/fonts/setback.png b/examples/text/resources/sprite_fonts/setback.png
similarity index 100%
rename from examples/text/resources/fonts/setback.png
rename to examples/text/resources/sprite_fonts/setback.png
diff --git a/examples/text/text_codepoints_loading.c b/examples/text/text_codepoints_loading.c
index 28d15c33f..2c33a8da5 100644
--- a/examples/text/text_codepoints_loading.c
+++ b/examples/text/text_codepoints_loading.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [text] example - text codepoints loading
+* raylib [text] example - codepoints loading
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/text/text_draw_3d.c b/examples/text/text_draw_3d.c
index ce76c885e..028acb4c4 100644
--- a/examples/text/text_draw_3d.c
+++ b/examples/text/text_draw_3d.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [text] example - drawing 3d text
+* raylib [text] example - 3d text drawing
*
* Example complexity rating: [★★★★] 4/4
*
@@ -87,7 +87,7 @@ int main(void)
int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT|FLAG_VSYNC_HINT);
- InitWindow(screenWidth, screenHeight, "raylib [text] example - draw 2D text in 3D");
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - 3d text drawing");
bool spin = true; // Spin the camera?
bool multicolor = false; // Multicolor mode
diff --git a/examples/text/text_font_filters.c b/examples/text/text_font_filters.c
index f75ae26b2..efd074c54 100644
--- a/examples/text/text_font_filters.c
+++ b/examples/text/text_font_filters.c
@@ -29,7 +29,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [text] example - font filters");
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - font texture filters");
const char msg[50] = "Loaded Font";
diff --git a/examples/text/text_font_loading.c b/examples/text/text_font_loading.c
index a7f8c60f4..f1582348b 100644
--- a/examples/text/text_font_loading.c
+++ b/examples/text/text_font_loading.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [text] example - Font loading
+* raylib [text] example - font loading
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/text/text_font_sdf.c b/examples/text/text_font_sdf.c
index fd3b2f776..5a24c1013 100644
--- a/examples/text/text_font_sdf.c
+++ b/examples/text/text_font_sdf.c
@@ -33,7 +33,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [text] example - SDF fonts");
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - font SDF loading");
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
diff --git a/examples/text/text_format_text.c b/examples/text/text_format_text.c
index a5c2a2331..2eadf05c2 100644
--- a/examples/text/text_format_text.c
+++ b/examples/text/text_format_text.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [text] example - text formating
+* raylib [text] example - text formatting
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/text/text_input_box.c b/examples/text/text_input_box.c
index 77c04d55a..af98bb17a 100644
--- a/examples/text/text_input_box.c
+++ b/examples/text/text_input_box.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [text] example - text input box
+* raylib [text] example - input box
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/text/text_raylib_fonts.c b/examples/text/text_raylib_fonts.c
index 7248be128..23db709cd 100644
--- a/examples/text/text_raylib_fonts.c
+++ b/examples/text/text_raylib_fonts.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [text] example - raylib fonts loading
+* raylib [text] example - sprite fonts
*
* Example complexity rating: [★☆☆☆] 1/4
*
@@ -30,19 +30,19 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [text] example - raylib fonts");
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - sprite fonts");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Font fonts[MAX_FONTS] = { 0 };
- fonts[0] = LoadFont("resources/fonts/alagard.png");
- fonts[1] = LoadFont("resources/fonts/pixelplay.png");
- fonts[2] = LoadFont("resources/fonts/mecha.png");
- fonts[3] = LoadFont("resources/fonts/setback.png");
- fonts[4] = LoadFont("resources/fonts/romulus.png");
- fonts[5] = LoadFont("resources/fonts/pixantiqua.png");
- fonts[6] = LoadFont("resources/fonts/alpha_beta.png");
- fonts[7] = LoadFont("resources/fonts/jupiter_crash.png");
+ fonts[0] = LoadFont("resources/sprite_fonts/alagard.png");
+ fonts[1] = LoadFont("resources/sprite_fonts/pixelplay.png");
+ fonts[2] = LoadFont("resources/sprite_fonts/mecha.png");
+ fonts[3] = LoadFont("resources/sprite_fonts/setback.png");
+ fonts[4] = LoadFont("resources/sprite_fonts/romulus.png");
+ fonts[5] = LoadFont("resources/sprite_fonts/pixantiqua.png");
+ fonts[6] = LoadFont("resources/sprite_fonts/alpha_beta.png");
+ fonts[7] = LoadFont("resources/sprite_fonts/jupiter_crash.png");
const char *messages[MAX_FONTS] = { "ALAGARD FONT designed by Hewett Tsoi",
"PIXELPLAY FONT designed by Aleksander Shevchuk",
@@ -87,8 +87,8 @@ int main(void)
ClearBackground(RAYWHITE);
- DrawText("free fonts included with raylib", 250, 20, 20, DARKGRAY);
- DrawLine(220, 50, 590, 50, DARKGRAY);
+ DrawText("free sprite fonts included with raylib", 220, 20, 20, DARKGRAY);
+ DrawLine(220, 50, 600, 50, DARKGRAY);
for (int i = 0; i < MAX_FONTS; i++)
{
diff --git a/examples/text/text_rectangle_bounds.c b/examples/text/text_rectangle_bounds.c
index 75ac65b49..66fe53234 100644
--- a/examples/text/text_rectangle_bounds.c
+++ b/examples/text/text_rectangle_bounds.c
@@ -17,8 +17,13 @@
#include "raylib.h"
-static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
-static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
+//----------------------------------------------------------------------------------
+// Module functions declaration
+//----------------------------------------------------------------------------------
+// Draw text using font inside rectangle limits
+static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint);
+// Draw text using font inside rectangle limits with support for text selection
+static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint);
//------------------------------------------------------------------------------------
// Program main entry point
@@ -30,7 +35,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [text] example - draw text inside a rectangle");
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - rectangle bounds");
const char text[] = "Text cannot escape\tthis container\t...word wrap also works when active so here's \
a long text for testing.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod \
diff --git a/examples/text/text_unicode.c b/examples/text/text_unicode.c
index fbf579772..0a9df7b41 100644
--- a/examples/text/text_unicode.c
+++ b/examples/text/text_unicode.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [text] example - unicode text drawing
+* raylib [text] example - unicode emojis emojis
*
* Example complexity rating: [★★★★] 4/4
*
@@ -163,7 +163,7 @@ int main(void)
const int screenHeight = 450;
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT);
- InitWindow(screenWidth, screenHeight, "raylib [text] example - unicode");
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - unicode emojis");
// Load the font resources
// NOTE: fontAsian is for asian languages,
diff --git a/examples/text/text_unicode_ranges.c b/examples/text/text_unicode_ranges.c
new file mode 100644
index 000000000..d3cb4b5e5
--- /dev/null
+++ b/examples/text/text_unicode_ranges.c
@@ -0,0 +1,183 @@
+/*******************************************************************************************
+*
+* raylib [text] example - unicode ranges
+*
+* Example complexity rating: [★★★★] 4/4
+*
+* Example originally created with raylib 2.5, last time updated with raylib 4.0
+*
+* Example contributed by Vlad Adrian (@demizdor) 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) 2019-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include
+
+typedef struct {
+ int* data;
+ int count;
+ int capacity;
+} CodepointsArray;
+
+//--------------------------------------------------------------------------------------
+// Module functions declaration
+//--------------------------------------------------------------------------------------
+static void AddRange(CodepointsArray* array, int start, int stop);
+static Font LoadUnicodeFont(const char* fileName, int fontSize);
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - unicode ranges");
+
+ // Load font with Unicode support
+ Font fontUni = LoadUnicodeFont("resources/NotoSansTC-Regular.ttf", 32);
+ SetTextureFilter(fontUni.texture, TEXTURE_FILTER_BILINEAR);
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ //...
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ // Render test strings in different languages
+ DrawTextEx(fontUni, "English: Hello World!", (Vector2){ 50, 50 }, 32, 1, DARKGRAY); // English
+ DrawTextEx(fontUni, "Español: Hola mundo!", (Vector2){ 50, 100 }, 32, 1, DARKGRAY); // Spanish
+ DrawTextEx(fontUni, "Ελληνικά: Γειά σου κόσμε!", (Vector2){ 50, 150 }, 32, 1, DARKGRAY); // Greek
+ DrawTextEx(fontUni, "Русский: Привет мир!", (Vector2){ 50, 200 }, 32, 0, DARKGRAY); // Russian
+ DrawTextEx(fontUni, "中文: 你好世界!", (Vector2){ 50, 250 }, 32, 1, DARKGRAY); // Chinese
+ DrawTextEx(fontUni, "日本語: こんにちは世界!", (Vector2){ 50, 300 }, 32, 1, DARKGRAY); // Japanese
+ DrawTextEx(fontUni, "देवनागरी: होला मुंडो!", (Vector2){ 50, 350 }, 32, 1, DARKGRAY); // Devanagari
+
+ DrawRectangle(400, 16, 380, 400, BLACK);
+ DrawTexturePro(fontUni.texture, (Rectangle){ 0, 0, fontUni.texture.width, fontUni.texture.height },
+ (Rectangle){ 400, 16, 380, 400 }, (Vector2){ 0, 0 }, 0.0f, WHITE);
+
+ // Display font attribution
+ DrawText("Font: Noto Sans TC. License: SIL Open Font License 1.1", screenWidth - 300, screenHeight - 20, 10, GRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadFont(fontUni); // Unload font resource
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+//--------------------------------------------------------------------------------------
+// Module functions definition
+//--------------------------------------------------------------------------------------
+static void AddRange(CodepointsArray* array, int start, int stop)
+{
+ int rangeSize = stop - start + 1;
+
+ if ((array->count + rangeSize) > array->capacity)
+ {
+ array->capacity = array->count + rangeSize + 1024;
+ array->data = (int *)MemRealloc(array->data, array->capacity*sizeof(int));
+
+ if (!array->data)
+ {
+ TraceLog(LOG_ERROR, "FONTUTIL: Memory allocation failed");
+ exit(1);
+ }
+ }
+
+ for (int i = start; i <= stop; i++) array->data[array->count++] = i;
+}
+
+Font LoadUnicodeFont(const char *fileName, int fontSize)
+{
+ CodepointsArray cp = { 0 };
+ cp.capacity = 2048;
+ cp.data = (int *)MemAlloc(cp.capacity*sizeof(int));
+
+ if (!cp.data)
+ {
+ TraceLog(LOG_ERROR, "FONTUTIL: Initial allocation failed");
+ return GetFontDefault();
+ }
+
+ // Unicode range: Basic ASCII
+ AddRange(&cp, 32, 126);
+
+ // Unicode range: European Languages
+ AddRange(&cp, 0xC0, 0x17F);
+ AddRange(&cp, 0x180, 0x24F);
+ AddRange(&cp, 0x1E00, 0x1EFF);
+ AddRange(&cp, 0x2C60, 0x2C7F);
+
+ // Unicode range: Greek
+ AddRange(&cp, 0x370, 0x3FF);
+ AddRange(&cp, 0x1F00, 0x1FFF);
+
+ // Unicode range: Cyrillic
+ AddRange(&cp, 0x400, 0x4FF);
+ AddRange(&cp, 0x500, 0x52F);
+ AddRange(&cp, 0x2DE0, 0x2DFF);
+ AddRange(&cp, 0xA640, 0xA69F);
+
+ // Unicode range: CJK
+ AddRange(&cp, 0x4E00, 0x9FFF);
+ AddRange(&cp, 0x3400, 0x4DBF);
+ AddRange(&cp, 0x3000, 0x303F);
+ AddRange(&cp, 0x3040, 0x309F);
+ AddRange(&cp, 0x30A0, 0x30FF);
+ AddRange(&cp, 0x31F0, 0x31FF);
+ AddRange(&cp, 0xFF00, 0xFFEF);
+ AddRange(&cp, 0xAC00, 0xD7AF);
+ AddRange(&cp, 0x1100, 0x11FF);
+
+ // Unicode range: Other
+ // WARNING: Not available on provided font
+ AddRange(&cp, 0x900, 0x97F); // Devanagari
+ AddRange(&cp, 0x600, 0x6FF); // Arabic
+ AddRange(&cp, 0x5D0, 0x5EA); // Hebrew
+
+ Font font = {0};
+
+ if (FileExists(fileName))
+ {
+ font = LoadFontEx(fileName, fontSize, cp.data, cp.count);
+ }
+
+ if (font.texture.id == 0)
+ {
+ font = GetFontDefault();
+ TraceLog(LOG_WARNING, "FONTUTIL: Using default font");
+ }
+
+ MemFree(cp.data);
+
+ return font;
+}
diff --git a/examples/text/text_writing_anim.c b/examples/text/text_writing_anim.c
index 5d5b8ea7d..e52f96a03 100644
--- a/examples/text/text_writing_anim.c
+++ b/examples/text/text_writing_anim.c
@@ -25,7 +25,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [text] example - text writing anim");
+ InitWindow(screenWidth, screenHeight, "raylib [text] example - text writing animation");
const char message[128] = "This sample illustrates a text writing\nanimation effect! Check it out! ;)";
diff --git a/examples/textures/textures_draw_tiled.c b/examples/textures/textures_draw_tiled.c
index c6bf3f835..e3262be01 100644
--- a/examples/textures/textures_draw_tiled.c
+++ b/examples/textures/textures_draw_tiled.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - draw texture tiled
+* raylib [textures] example - textures tiled drawing
*
* Example complexity rating: [★★★☆] 3/4
*
@@ -36,7 +36,7 @@ int main(void)
const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_RESIZABLE); // Make the window resizable
- InitWindow(screenWidth, screenHeight, "raylib [textures] example - draw texture tiled");
+ InitWindow(screenWidth, screenHeight, "raylib [textures] example - textures tiled drawing");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Texture texPattern = LoadTexture("resources/patterns.png");
diff --git a/examples/textures/textures_image_channel.c b/examples/textures/textures_image_channel.c
index b11fb5cd6..400029aa6 100644
--- a/examples/textures/textures_image_channel.c
+++ b/examples/textures/textures_image_channel.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - extract image channel
+* raylib [textures] example - extract channel from image
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
diff --git a/examples/textures/textures_image_drawing.c b/examples/textures/textures_image_drawing.c
index cc2340d82..ea41b7baf 100644
--- a/examples/textures/textures_image_drawing.c
+++ b/examples/textures/textures_image_drawing.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - image loading and drawing
+* raylib [textures] example - image drawing
*
* Example complexity rating: [★★☆☆] 2/4
*
diff --git a/examples/textures/textures_image_kernel.c b/examples/textures/textures_image_kernel.c
index cfd05092a..99285e15e 100644
--- a/examples/textures/textures_image_kernel.c
+++ b/examples/textures/textures_image_kernel.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - image kernel convolution
+* raylib [textures] example - image convolution
*
* Example complexity rating: [★★★★] 4/4
*
diff --git a/examples/textures/textures_image_loading.c b/examples/textures/textures_image_loading.c
index 9ed864db5..f48aafe93 100644
--- a/examples/textures/textures_image_loading.c
+++ b/examples/textures/textures_image_loading.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - image loading and texture creation
+* raylib [textures] example - image loading
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/textures/textures_image_processing.c b/examples/textures/textures_image_processing.c
index 8531d1dba..474974f97 100644
--- a/examples/textures/textures_image_processing.c
+++ b/examples/textures/textures_image_processing.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - Image processing
+* raylib [textures] example - image processing
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/textures/textures_image_text.c b/examples/textures/textures_image_text.c
index 6c8720315..354e15fad 100644
--- a/examples/textures/textures_image_text.c
+++ b/examples/textures/textures_image_text.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - image text drawing using TTF generated font
+* raylib [textures] example - image text drawing
*
* Example complexity rating: [★★☆☆] 2/4
*
@@ -25,7 +25,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [texture] example - image text drawing");
+ InitWindow(screenWidth, screenHeight, "raylib [textures] example - image text drawing");
Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
diff --git a/examples/textures/textures_polygon.c b/examples/textures/textures_polygon.c
index 414b91350..6a9e357d8 100644
--- a/examples/textures/textures_polygon.c
+++ b/examples/textures/textures_polygon.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - draw textured polygon
+* raylib [textures] example - textured polygon
*
* Example complexity rating: [★☆☆☆] 1/4
*
diff --git a/examples/textures/textures_raw_data.c b/examples/textures/textures_raw_data.c
index 76be8593a..922ba575f 100644
--- a/examples/textures/textures_raw_data.c
+++ b/examples/textures/textures_raw_data.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - load textures from raw data
+* raylib [textures] example - texture from raw data
*
* Example complexity rating: [★★★☆] 3/4
*
diff --git a/examples/textures/textures_sprite_anim.c b/examples/textures/textures_sprite_anim.c
index 032b1f621..a4e610d65 100644
--- a/examples/textures/textures_sprite_anim.c
+++ b/examples/textures/textures_sprite_anim.c
@@ -28,7 +28,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [texture] example - sprite anim");
+ InitWindow(screenWidth, screenHeight, "raylib [textures] example - sprite animation");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Texture2D scarfy = LoadTexture("resources/scarfy.png"); // Texture loading
diff --git a/examples/textures/textures_srcrec_dstrec.c b/examples/textures/textures_srcrec_dstrec.c
index 6c5ba1b36..437587a79 100644
--- a/examples/textures/textures_srcrec_dstrec.c
+++ b/examples/textures/textures_srcrec_dstrec.c
@@ -25,7 +25,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
- InitWindow(screenWidth, screenHeight, "raylib [textures] examples - texture source and destination rectangles");
+ InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture source and destination rectangles");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
diff --git a/examples/textures/textures_textured_curve.c b/examples/textures/textures_textured_curve.c
index 0102e8d5c..245aee3c7 100644
--- a/examples/textures/textures_textured_curve.c
+++ b/examples/textures/textures_textured_curve.c
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib [textures] example - draw texture along segmented curve
+* raylib [textures] example - textured curve
*
* Example complexity rating: [★★★☆] 3/4
*
@@ -57,7 +57,7 @@ int main()
const int screenHeight = 450;
SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT);
- InitWindow(screenWidth, screenHeight, "raylib [textures] examples - textured curve");
+ InitWindow(screenWidth, screenHeight, "raylib [textures] example - textured curve");
// Load the road texture
texRoad = LoadTexture("resources/road.png");
diff --git a/projects/VS2022/examples/core_3d_fps_controller.vcxproj b/projects/VS2022/examples/core_3d_fps_controller.vcxproj
new file mode 100644
index 000000000..5708555d5
--- /dev/null
+++ b/projects/VS2022/examples/core_3d_fps_controller.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}
+ Win32Proj
+ core_3d_camera_fps
+ 10.0
+ core_3d_camera_fps
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\core
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/examples/shaders_normalmap.vcxproj b/projects/VS2022/examples/shaders_normal_map.vcxproj
similarity index 99%
rename from projects/VS2022/examples/shaders_normalmap.vcxproj
rename to projects/VS2022/examples/shaders_normal_map.vcxproj
index 79f976102..a3e8e9981 100644
--- a/projects/VS2022/examples/shaders_normalmap.vcxproj
+++ b/projects/VS2022/examples/shaders_normal_map.vcxproj
@@ -51,11 +51,11 @@
- {0981CA98-E4A5-4DF1-987F-A41D09131EFC}
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}
Win32Proj
- shaders_normalmap
+ shaders_normal_map
10.0
- shaders_normalmap
+ shaders_normal_map
@@ -553,7 +553,7 @@
-
+
diff --git a/projects/VS2022/examples/text_unicode_ranges.vcxproj b/projects/VS2022/examples/text_unicode_ranges.vcxproj
new file mode 100644
index 000000000..c9ddd9a1c
--- /dev/null
+++ b/projects/VS2022/examples/text_unicode_ranges.vcxproj
@@ -0,0 +1,569 @@
+
+
+
+
+ Debug.DLL
+ ARM64
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ ARM64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}
+ Win32Proj
+ text_unicode_ranges
+ 10.0
+ text_unicode_ranges
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+ $(SolutionDir)..\..\examples\text
+ WindowsLocalDebugger
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP
+ $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+
+
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln
index 452ba39c5..21d7c63b6 100644
--- a/projects/VS2022/raylib.sln
+++ b/projects/VS2022/raylib.sln
@@ -21,7 +21,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shaders", "shaders", "{5317
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "audio", "audio", "{CC132A4D-D081-4C26-BFB9-AB11984054F8}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "other", "other", "{E9D708A5-9C1F-4B84-A795-C5F191801762}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "others", "others", "{E9D708A5-9C1F-4B84-A795-C5F191801762}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}"
EndProject
@@ -305,8 +305,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_gpu_skinning", "exam
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_shadowmap", "examples\shaders_shadowmap.vcxproj", "{41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_virtual_controls", "examples\core_input_virtual_controls.vcxproj", "{0981CA28-E4A5-4DF1-987F-A41D09131EFC}"
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_bone_socket", "examples\models_bone_socket.vcxproj", "{3A7FE53D-35F7-49DC-9C9A-A5204A53523F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_vertex_displacement", "examples\shaders_vertex_displacement.vcxproj", "{CCA63A76-D9FC-4130-9F67-4D97F9770D53}"
@@ -333,6 +331,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_lightmap", "example
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_sound_positioning", "examples\audio_sound_positioning.vcxproj", "{9CD8BCAD-F212-4BCC-BA98-899743CE3279}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_virtual_controls", "examples\core_input_virtual_controls.vcxproj", "{0981CA28-E4A5-4DF1-987F-A41D09131EFC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_fps", "examples\core_3d_camera_fps.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_normal_map", "examples\shaders_normal_map.vcxproj", "{6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_unicode_ranges", "examples\text_unicode_ranges.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug.DLL|ARM64 = Debug.DLL|ARM64
@@ -3745,30 +3751,6 @@ Global
{41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x64.Build.0 = Release|x64
{41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x86.ActiveCfg = Release|Win32
{41BBCC10-6FDE-48A1-B2E0-A0EC6A668629}.Release|x86.Build.0 = Release|Win32
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.Build.0 = Debug|ARM64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.ActiveCfg = Debug|x64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.Build.0 = Debug|x64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.ActiveCfg = Release|ARM64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.Build.0 = Release|ARM64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.ActiveCfg = Release|x64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.Build.0 = Release|x64
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|Win32
{3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
{3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
{3A7FE53D-35F7-49DC-9C9A-A5204A53523F}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
@@ -4081,6 +4063,102 @@ Global
{9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x64.Build.0 = Release|x64
{9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x86.ActiveCfg = Release|Win32
{9CD8BCAD-F212-4BCC-BA98-899743CE3279}.Release|x86.Build.0 = Release|Win32
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|ARM64.Build.0 = Debug|ARM64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.ActiveCfg = Debug|x64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.Build.0 = Debug|x64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.ActiveCfg = Release|ARM64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|ARM64.Build.0 = Release|ARM64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.ActiveCfg = Release|x64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.Build.0 = Release|x64
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|ARM64.Build.0 = Debug|ARM64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x64.ActiveCfg = Debug|x64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x64.Build.0 = Debug|x64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x86.ActiveCfg = Debug|Win32
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Debug|x86.Build.0 = Debug|Win32
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|ARM64.ActiveCfg = Release|ARM64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|ARM64.Build.0 = Release|ARM64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x64.ActiveCfg = Release|x64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x64.Build.0 = Release|x64
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x86.ActiveCfg = Release|Win32
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x86.Build.0 = Release|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -4235,7 +4313,6 @@ Global
{FAFEE2F9-24B0-4AF1-B512-433E9590033F} = {278D8859-20B1-428F-8448-064F46E1F021}
{8245DAD9-D402-4D5C-8F45-32229CD3B263} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{41BBCC10-6FDE-48A1-B2E0-A0EC6A668629} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
- {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{3A7FE53D-35F7-49DC-9C9A-A5204A53523F} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
{CCA63A76-D9FC-4130-9F67-4D97F9770D53} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{D3493FFE-8873-4C53-8F6C-74DEF78EA3C4} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
@@ -4249,6 +4326,10 @@ Global
{4DF6D5E4-6796-4257-B466-BCD62DEBBCF8} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
{9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}
+ {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
+ {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}
+ {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
diff --git a/src/external/fix_win32_compatibility.h b/src/external/fix_win32_compatibility.h
new file mode 100644
index 000000000..fb0f606fb
--- /dev/null
+++ b/src/external/fix_win32_compatibility.h
@@ -0,0 +1,63 @@
+/**********************************************************************************************
+*
+* fix_win32_compatibility.h Utility to help include windows.h with raylib projects
+*
+* Useage: #include "fix_win32_compatibility.h" any library that uses windows.h
+* order is critical, this must be done before raylib
+*
+* LICENSE: MIT
+*
+* Copyright (c) 2025 Jeffery Myers
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+**********************************************************************************************/
+
+#pragma once
+
+// move the windows functions to new names
+// note that you can't call these functions or structures from your code, but you should not neeed to
+#define CloseWindow CloseWindowWin32
+#define Rectangle RectangleWin32
+#define ShowCursor ShowCursorWin32
+#define LoadImageA LoadImageAWin32
+#define LoadImageW LoadImageWin32
+#define DrawTextA DrawTextAWin32
+#define DrawTextW DrawTextWin32
+#define DrawTextExA DrawTextExAWin32
+#define DrawTextExW DrawTextExWin32
+#define PlaySoundA PlaySoundAWin32\
+// include windows
+#define WIN32_LEAN_AND_MEAN
+#include
+
+// remove all our redfintions so that raylib can define them properly
+#undef CloseWindow
+#undef Rectangle
+#undef ShowCursor
+#undef LoadImage
+#undef LoadImageA
+#undef LoadImageW
+#undef DrawText
+#undef DrawTextA
+#undef DrawTextW
+#undef DrawTextEx
+#undef DrawTextExA
+#undef DrawTextExW
+#undef PlaySoundA
diff --git a/src/external/qoaplay.c b/src/external/qoaplay.c
index 039e27974..4378e5ebd 100644
--- a/src/external/qoaplay.c
+++ b/src/external/qoaplay.c
@@ -46,7 +46,6 @@ typedef struct {
unsigned int sample_position; // Current streaming sample position
unsigned char *buffer; // Buffer used to read samples from file/memory (used on decoding)
- unsigned int buffer_len; // Buffer length to read samples for streaming
short *sample_data; // Sample data decoded
unsigned int sample_data_len; // Sample data decoded length
@@ -111,7 +110,7 @@ qoaplay_desc *qoaplay_open(const char *path)
qoa_ctx->file = file;
qoa_ctx->file_data = NULL;
qoa_ctx->file_data_size = 0;
- qoa_ctx->file_data_offset = 0;
+ qoa_ctx->file_data_offset = first_frame_pos;
qoa_ctx->first_frame_pos = first_frame_pos;
// Setup data pointers to previously allocated data
@@ -128,34 +127,30 @@ qoaplay_desc *qoaplay_open(const char *path)
// Open QOA file from memory, no FILE pointer required
qoaplay_desc *qoaplay_open_memory(const unsigned char *data, int data_size)
{
- // Read and decode the file header
- unsigned char header[QOA_MIN_FILESIZE];
- memcpy(header, data, QOA_MIN_FILESIZE);
-
qoa_desc qoa;
- unsigned int first_frame_pos = qoa_decode_header(header, QOA_MIN_FILESIZE, &qoa);
+ if (data_size < QOA_MIN_FILESIZE) return NULL;
+ unsigned int first_frame_pos = qoa_decode_header(data, QOA_MIN_FILESIZE, &qoa);
if (!first_frame_pos) return NULL;
// Allocate one chunk of memory for the qoaplay_desc struct
// + the sample data for one frame
// + a buffer to hold one frame of encoded data
- unsigned int buffer_size = qoa_max_frame_size(&qoa);
unsigned int sample_data_size = qoa.channels*QOA_FRAME_LEN*sizeof(short)*2;
- qoaplay_desc *qoa_ctx = QOA_MALLOC(sizeof(qoaplay_desc) + buffer_size + sample_data_size);
+ qoaplay_desc *qoa_ctx = QOA_MALLOC(sizeof(qoaplay_desc) + sample_data_size + data_size);
memset(qoa_ctx, 0, sizeof(qoaplay_desc));
qoa_ctx->file = NULL;
// Keep a copy of file data provided to be managed internally
- qoa_ctx->file_data = (unsigned char *)QOA_MALLOC(data_size);
+ qoa_ctx->file_data = (((unsigned char *)qoa_ctx) + sizeof(qoaplay_desc) + sample_data_size);
memcpy(qoa_ctx->file_data, data, data_size);
qoa_ctx->file_data_size = data_size;
- qoa_ctx->file_data_offset = 0;
+ qoa_ctx->file_data_offset = first_frame_pos;
qoa_ctx->first_frame_pos = first_frame_pos;
// Setup data pointers to previously allocated data
- qoa_ctx->buffer = ((unsigned char *)qoa_ctx) + sizeof(qoaplay_desc);
- qoa_ctx->sample_data = (short *)(((unsigned char *)qoa_ctx) + sizeof(qoaplay_desc) + buffer_size);
+ qoa_ctx->buffer = NULL;
+ qoa_ctx->sample_data = (short *)(((unsigned char *)qoa_ctx) + sizeof(qoaplay_desc));
qoa_ctx->info.channels = qoa.channels;
qoa_ctx->info.samplerate = qoa.samplerate;
@@ -169,11 +164,7 @@ void qoaplay_close(qoaplay_desc *qoa_ctx)
{
if (qoa_ctx->file) fclose(qoa_ctx->file);
- if ((qoa_ctx->file_data) && (qoa_ctx->file_data_size > 0))
- {
- QOA_FREE(qoa_ctx->file_data);
- qoa_ctx->file_data_size = 0;
- }
+ qoa_ctx->file_data_size = 0;
QOA_FREE(qoa_ctx);
}
@@ -181,16 +172,23 @@ void qoaplay_close(qoaplay_desc *qoa_ctx)
// Decode one frame from QOA data
unsigned int qoaplay_decode_frame(qoaplay_desc *qoa_ctx)
{
- if (qoa_ctx->file) qoa_ctx->buffer_len = fread(qoa_ctx->buffer, 1, qoa_max_frame_size(&qoa_ctx->info), qoa_ctx->file);
+ unsigned char *buffer;
+ unsigned int buffer_len;
+
+ if (qoa_ctx->file)
+ {
+ buffer = qoa_ctx->buffer;
+ buffer_len = fread(buffer, 1, qoa_max_frame_size(&qoa_ctx->info), qoa_ctx->file);
+ }
else
{
- qoa_ctx->buffer_len = qoa_max_frame_size(&qoa_ctx->info);
- memcpy(qoa_ctx->buffer, qoa_ctx->file_data + qoa_ctx->file_data_offset, qoa_ctx->buffer_len);
- qoa_ctx->file_data_offset += qoa_ctx->buffer_len;
+ buffer = qoa_ctx->file_data + qoa_ctx->file_data_offset;
+ buffer_len = qoa_max_frame_size(&qoa_ctx->info);
+ qoa_ctx->file_data_offset += buffer_len;
}
unsigned int frame_len;
- qoa_decode_frame(qoa_ctx->buffer, qoa_ctx->buffer_len, &qoa_ctx->info, qoa_ctx->sample_data, &frame_len);
+ qoa_decode_frame(buffer, buffer_len, &qoa_ctx->info, qoa_ctx->sample_data, &frame_len);
qoa_ctx->sample_data_pos = 0;
qoa_ctx->sample_data_len = frame_len;
@@ -201,7 +199,7 @@ unsigned int qoaplay_decode_frame(qoaplay_desc *qoa_ctx)
void qoaplay_rewind(qoaplay_desc *qoa_ctx)
{
if (qoa_ctx->file) fseek(qoa_ctx->file, qoa_ctx->first_frame_pos, SEEK_SET);
- else qoa_ctx->file_data_offset = 0;
+ else qoa_ctx->file_data_offset = qoa_ctx->first_frame_pos;
qoa_ctx->sample_position = 0;
qoa_ctx->sample_data_len = 0;
diff --git a/src/external/rl_gputex.h b/src/external/rl_gputex.h
index 9773268f5..306f09808 100644
--- a/src/external/rl_gputex.h
+++ b/src/external/rl_gputex.h
@@ -586,6 +586,7 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
// KTX 2.0 defines additional header elements...
} ktx_header;
+ /*
Byte[12] identifier
UInt32 vkFormat
UInt32 typeSize
@@ -596,6 +597,7 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
UInt32 faceCount
UInt32 levelCount
UInt32 supercompressionScheme
+ */
// Calculate file data_size required
int data_size = sizeof(ktx_header);
diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c
index 03cb9741c..bfbdd30b3 100644
--- a/src/platforms/rcore_android.c
+++ b/src/platforms/rcore_android.c
@@ -560,7 +560,7 @@ void EnableCursor(void)
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
- CORE.Input.Mouse.cursorHidden = false;
+ CORE.Input.Mouse.cursorLocked = false;
}
// Disables cursor (lock cursor)
@@ -569,7 +569,7 @@ void DisableCursor(void)
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
- CORE.Input.Mouse.cursorHidden = true;
+ CORE.Input.Mouse.cursorLocked = true;
}
// Swap back buffer with front buffer (screen drawing)
diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c
index c23b570d3..49cb6fff4 100644
--- a/src/platforms/rcore_desktop_glfw.c
+++ b/src/platforms/rcore_desktop_glfw.c
@@ -74,14 +74,27 @@
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include // Required for: timespec, nanosleep(), select() - POSIX
- //#define GLFW_EXPOSE_NATIVE_WAYLAND
- #define GLFW_EXPOSE_NATIVE_X11
- #define Font X11Font // Hack to fix 'Font' name collision
+#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
+ // Set appropriate expose macros based on available backends
+ #if defined(_GLFW_X11)
+ #define GLFW_EXPOSE_NATIVE_X11
+ #define Font X11Font // Hack to fix 'Font' name collision
// The definition and references to the X11 Font type will be replaced by 'X11Font'
// Works as long as the current file consistently references any X11 Font as X11Font
// Since it is never referenced (as of writting), this does not pose an issue
- #include "GLFW/glfw3native.h" // Required for: glfwGetX11Window()
- #undef Font // Revert hack and allow normal raylib Font usage
+ #endif
+
+ #if defined(_GLFW_WAYLAND)
+ #define GLFW_EXPOSE_NATIVE_WAYLAND
+ #endif
+
+ #include "GLFW/glfw3native.h" // Include native header only once, regardless of how many backends are defined
+ // Required for: glfwGetX11Window() and glfwGetWaylandWindow()
+
+ #if defined(_GLFW_X11) // Clean up X11-specific hacks
+ #undef Font // Revert hack and allow normal raylib Font usage
+ #endif
+#endif
#endif
#if defined(__APPLE__)
#include // Required for: usleep()
@@ -710,7 +723,7 @@ void SetWindowFocused(void)
glfwFocusWindow(platform.handle);
}
-#if defined(__linux__)
+#if defined(__linux__) && defined(_GLFW_X11)
// Local storage for the window handle returned by glfwGetX11Window
// This is needed as X11 handles are integers and may not fit inside a pointer depending on platform
// Storing the handle locally and returning a pointer in GetWindowHandle allows the code to work regardless of pointer width
@@ -724,10 +737,27 @@ void *GetWindowHandle(void)
return glfwGetWin32Window(platform.handle);
#endif
#if defined(__linux__)
- // Store the window handle localy and return a pointer to the variable instead
- // Reasoning detailed in the declaration of X11WindowHandle
- X11WindowHandle = glfwGetX11Window(platform.handle);
- return &X11WindowHandle;
+ #if defined(_GLFW_WAYLAND)
+ #if defined(_GLFW_X11)
+ int platformID = glfwGetPlatform();
+ if (platformID == GLFW_PLATFORM_WAYLAND)
+ {
+ return glfwGetWaylandWindow(platform.handle);
+ }
+ else
+ {
+ X11WindowHandle = glfwGetX11Window(platform.handle);
+ return &X11WindowHandle;
+ }
+ #else
+ return glfwGetWaylandWindow(platform.handle);
+ #endif
+ #elif defined(_GLFW_X11)
+ // Store the window handle localy and return a pointer to the variable instead
+ // Reasoning detailed in the declaration of X11WindowHandle
+ X11WindowHandle = glfwGetX11Window(platform.handle);
+ return &X11WindowHandle;
+ #endif
#endif
#if defined(__APPLE__)
// NOTE: Returned handle is: (objc_object *)
@@ -1029,7 +1059,7 @@ void EnableCursor(void)
if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE);
- CORE.Input.Mouse.cursorHidden = false;
+ CORE.Input.Mouse.cursorLocked = false;
}
// Disables cursor (lock cursor)
@@ -1045,7 +1075,7 @@ void DisableCursor(void)
if (glfwRawMouseMotionSupported()) glfwSetInputMode(platform.handle, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
- CORE.Input.Mouse.cursorHidden = true;
+ CORE.Input.Mouse.cursorLocked = true;
}
// Swap back buffer with front buffer (screen drawing)
@@ -1363,6 +1393,9 @@ int InitPlatform(void)
// additionally auto iconify restores the hardware resolution of the monitor if the window that loses focus is a fullscreen window
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
+ // Window flags requested before initialization to be applied after initialization
+ unsigned int requestedWindowFlags = CORE.Window.flags;
+
// Check window creation flags
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true;
@@ -1660,7 +1693,7 @@ int InitPlatform(void)
int monitorHeight = 0;
glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);
- // Here CORE.Window.render.width/height should be used instead of
+ // Here CORE.Window.render.width/height should be used instead of
// CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled
int posX = monitorX + (monitorWidth - (int)CORE.Window.render.width)/2;
int posY = monitorY + (monitorHeight - (int)CORE.Window.render.height)/2;
@@ -1673,6 +1706,9 @@ int InitPlatform(void)
CORE.Window.position.y = posY;
}
+ // Apply window flags requested previous to initialization
+ SetWindowState(requestedWindowFlags);
+
// Load OpenGL extensions
// NOTE: GL procedures address loader is required to load extensions
rlLoadExtensions(glfwGetProcAddress);
@@ -1725,7 +1761,7 @@ int InitPlatform(void)
#if defined(__NetBSD__)
// Workaround for NetBSD
- char *glfwPlatform = "X11";
+ char *glfwPlatform = "X11 (NetBSD)";
#else
char *glfwPlatform = "";
switch (glfwGetPlatform())
diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c
index 5a62fa629..a2603b6e8 100644
--- a/src/platforms/rcore_desktop_sdl.c
+++ b/src/platforms/rcore_desktop_sdl.c
@@ -48,7 +48,9 @@
*
**********************************************************************************************/
-
+#ifdef USING_SDL3_PACKAGE
+ #define USING_SDL3_PROJECT
+#endif
#ifndef SDL_ENABLE_OLD_NAMES
#define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily
#endif
@@ -1103,7 +1105,7 @@ Vector2 GetWindowScaleDPI(void)
TRACELOG(LOG_WARNING, "GetWindowScaleDPI() not implemented on target platform");
#else
scale.x = SDL_GetWindowDisplayScale(platform.window);
- scale.y = scale.x;
+ scale.y = scale.x;
#endif
return scale;
@@ -1214,7 +1216,7 @@ void EnableCursor(void)
#endif
platform.cursorRelative = false;
- CORE.Input.Mouse.cursorHidden = false;
+ CORE.Input.Mouse.cursorLocked = false;
}
// Disables cursor (lock cursor)
@@ -1223,7 +1225,7 @@ void DisableCursor(void)
SDL_SetRelativeMouseMode(SDL_TRUE);
platform.cursorRelative = true;
- CORE.Input.Mouse.cursorHidden = true;
+ CORE.Input.Mouse.cursorLocked = true;
}
// Swap back buffer with front buffer (screen drawing)
@@ -1619,8 +1621,8 @@ void PollInputEvents(void)
{
// Add character (codepoint) to the queue
#if defined(PLATFORM_DESKTOP_SDL3)
- unsigned int textLen = strlen(event.text.text);
- unsigned int codepoint = (unsigned int)SDL_StepUTF8(&event.text.text, textLen);
+ size_t textLen = strlen(event.text.text);
+ unsigned int codepoint = (unsigned int)SDL_StepUTF8(&event.text.text, &textLen);
#else
int codepointSize = 0;
int codepoint = GetCodepointNextSDL(event.text.text, &codepointSize);
diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c
index 79769eee7..2354bb3d2 100644
--- a/src/platforms/rcore_drm.c
+++ b/src/platforms/rcore_drm.c
@@ -556,7 +556,7 @@ void EnableCursor(void)
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
platform.cursorRelative = false;
- CORE.Input.Mouse.cursorHidden = false;
+ CORE.Input.Mouse.cursorLocked = false;
}
// Disables cursor (lock cursor)
@@ -566,7 +566,7 @@ void DisableCursor(void)
SetMousePosition(0, 0);
platform.cursorRelative = true;
- CORE.Input.Mouse.cursorHidden = true;
+ CORE.Input.Mouse.cursorLocked = true;
}
#if defined(SUPPORT_DRM_CACHE)
@@ -1556,7 +1556,7 @@ static void ProcessKeyboard(void)
{
CORE.Input.Keyboard.currentKeyState[259] = 1;
- CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 257; // Add keys pressed into queue
+ CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = 259; // Add keys pressed into queue
CORE.Input.Keyboard.keyPressedQueueCount++;
}
else
@@ -2060,7 +2060,7 @@ static void PollMouseEvents(void)
}
// Screen confinement
- if (!CORE.Input.Mouse.cursorHidden)
+ if (!CORE.Input.Mouse.cursorLocked)
{
if (CORE.Input.Mouse.currentPosition.x < 0) CORE.Input.Mouse.currentPosition.x = 0;
if (CORE.Input.Mouse.currentPosition.x > CORE.Window.screen.width/CORE.Input.Mouse.scale.x) CORE.Input.Mouse.currentPosition.x = CORE.Window.screen.width/CORE.Input.Mouse.scale.x;
diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c
index 3107c30e4..2712aa142 100644
--- a/src/platforms/rcore_web.c
+++ b/src/platforms/rcore_web.c
@@ -102,8 +102,6 @@ static const char cursorLUT[11][12] = {
"not-allowed" // 10 MOUSE_CURSOR_NOT_ALLOWED
};
-Vector2 lockedMousePos = { 0 };
-
//----------------------------------------------------------------------------------
// Module Internal Functions Declaration
//----------------------------------------------------------------------------------
@@ -137,7 +135,7 @@ static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent
static EM_BOOL EmscriptenVisibilityChangeCallback(int eventType, const EmscriptenVisibilityChangeEvent *visibilityChangeEvent, void *userData);
// Emscripten input callback events
-static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyboardEvent, void *userData);
+//static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyboardEvent, void *userData);
static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPointerlockChangeEvent *pointerlockChangeEvent, void *userData);
@@ -862,7 +860,7 @@ void EnableCursor(void)
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
- // NOTE: CORE.Input.Mouse.cursorHidden handled by EmscriptenPointerlockCallback()
+ // NOTE: CORE.Input.Mouse.cursorLocked handled by EmscriptenPointerlockCallback()
}
// Disables cursor (lock cursor)
@@ -874,7 +872,7 @@ void DisableCursor(void)
// Set cursor position in the middle
SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2);
- // NOTE: CORE.Input.Mouse.cursorHidden handled by EmscriptenPointerlockCallback()
+ // NOTE: CORE.Input.Mouse.cursorLocked handled by EmscriptenPointerlockCallback()
}
// Swap back buffer with front buffer (screen drawing)
@@ -955,7 +953,7 @@ void SetMousePosition(int x, int y)
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
- if (CORE.Input.Mouse.cursorHidden) lockedMousePos = CORE.Input.Mouse.currentPosition;
+ if (CORE.Input.Mouse.cursorLocked) CORE.Input.Mouse.lockedPosition = CORE.Input.Mouse.currentPosition;
// NOTE: emscripten not implemented
glfwSetCursorPos(platform.handle, CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y);
@@ -966,7 +964,7 @@ void SetMouseCursor(int cursor)
{
if (CORE.Input.Mouse.cursor != cursor)
{
- if (!CORE.Input.Mouse.cursorHidden) EM_ASM( { Module.canvas.style.cursor = UTF8ToString($0); }, cursorLUT[cursor]);
+ if (!CORE.Input.Mouse.cursorLocked) EM_ASM( { Module.canvas.style.cursor = UTF8ToString($0); }, cursorLUT[cursor]);
CORE.Input.Mouse.cursor = cursor;
}
@@ -1357,7 +1355,7 @@ int InitPlatform(void)
emscripten_set_blur_callback(GetCanvasId(), platform.handle, 1, EmscriptenFocusCallback);
emscripten_set_focus_callback(GetCanvasId(), platform.handle, 1, EmscriptenFocusCallback);
emscripten_set_visibilitychange_callback(NULL, 1, EmscriptenVisibilityChangeCallback);
-
+
// WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review
// Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas)
// emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
@@ -1369,8 +1367,8 @@ int InitPlatform(void)
// Setup input events
// NOTE: Keyboard callbacks only used to consume some events, libglfw.js takes care of the actual input
- emscripten_set_keypress_callback(GetCanvasId(), NULL, 1, EmscriptenKeyboardCallback);
- emscripten_set_keydown_callback(GetCanvasId(), NULL, 1, EmscriptenKeyboardCallback);
+ //emscripten_set_keypress_callback(GetCanvasId(), NULL, 1, EmscriptenKeyboardCallback); // WRNING: Breaks input
+ //emscripten_set_keydown_callback(GetCanvasId(), NULL, 1, EmscriptenKeyboardCallback);
emscripten_set_click_callback(GetCanvasId(), NULL, 1, EmscriptenMouseCallback);
emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenPointerlockCallback);
emscripten_set_mousemove_callback(GetCanvasId(), NULL, 1, EmscriptenMouseMoveCallback);
@@ -1573,7 +1571,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
static void MouseMoveCallback(GLFWwindow *window, double x, double y)
{
// If the pointer is not locked, follow the position
- if (!CORE.Input.Mouse.cursorHidden)
+ if (!CORE.Input.Mouse.cursorLocked)
{
CORE.Input.Mouse.currentPosition.x = (float)x;
CORE.Input.Mouse.currentPosition.y = (float)y;
@@ -1620,13 +1618,15 @@ static void MouseEnterCallback(GLFWwindow *window, int enter)
// Emscripten callback functions, called on specific browser events
//-------------------------------------------------------------------------------------------------------
+/*
// Emscripten: Called on key events
static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyboardEvent, void *userData)
{
- // NOTE: Only used to consume some keyboard events without triggering browser functions
+ // WARNING: Keyboard inputs already processed through GLFW callback
return 1; // The event was consumed by the callback handler
}
+*/
// Emscripten: Called on mouse input events
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
@@ -1639,11 +1639,11 @@ static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent
// Emscripten: Called on mouse move events
static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
{
- // To emulate the GLFW_RAW_MOUSE_MOTION property.
- if (CORE.Input.Mouse.cursorHidden)
+ // To emulate the GLFW_RAW_MOUSE_MOTION property
+ if (CORE.Input.Mouse.cursorLocked)
{
- CORE.Input.Mouse.previousPosition.x = lockedMousePos.x - mouseEvent->movementX;
- CORE.Input.Mouse.previousPosition.y = lockedMousePos.y - mouseEvent->movementY;
+ CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.lockedPosition.x - mouseEvent->movementX;
+ CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.lockedPosition.y - mouseEvent->movementY;
}
return 1; // The event was consumed by the callback handler
@@ -1652,12 +1652,12 @@ static EM_BOOL EmscriptenMouseMoveCallback(int eventType, const EmscriptenMouseE
// Emscripten: Called on pointer lock events
static EM_BOOL EmscriptenPointerlockCallback(int eventType, const EmscriptenPointerlockChangeEvent *pointerlockChangeEvent, void *userData)
{
- CORE.Input.Mouse.cursorHidden = EM_ASM_INT( { if (document.pointerLockElement) return 1; }, 0);
+ CORE.Input.Mouse.cursorLocked = EM_ASM_INT( { if (document.pointerLockElement) return 1; }, 0);
- if (CORE.Input.Mouse.cursorHidden)
+ if (CORE.Input.Mouse.cursorLocked)
{
- lockedMousePos = CORE.Input.Mouse.currentPosition;
- CORE.Input.Mouse.previousPosition = lockedMousePos;
+ CORE.Input.Mouse.lockedPosition = CORE.Input.Mouse.currentPosition;
+ CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.lockedPosition;
}
return 1; // The event was consumed by the callback handler
@@ -1822,6 +1822,8 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
+ glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
+
// NOTE: Postprocessing texture is not scaled to new size
return 0;
diff --git a/src/raudio.c b/src/raudio.c
index 76fee2333..e9d76fa99 100644
--- a/src/raudio.c
+++ b/src/raudio.c
@@ -982,9 +982,13 @@ Sound LoadSoundAlias(Sound source)
}
audioBuffer->sizeInFrames = source.stream.buffer->sizeInFrames;
- audioBuffer->volume = source.stream.buffer->volume;
audioBuffer->data = source.stream.buffer->data;
+ // initalize the buffer as if it was new
+ audioBuffer->volume = 1.0f;
+ audioBuffer->pitch = 1.0f;
+ audioBuffer->pan = 0.5f;
+
sound.frameCount = source.frameCount;
sound.stream.sampleRate = AUDIO.System.device.sampleRate;
sound.stream.sampleSize = 32;
@@ -1763,7 +1767,7 @@ void UnloadMusicStream(Music music)
else if (music.ctxType == MUSIC_AUDIO_QOA) qoaplay_close((qoaplay_desc *)music.ctxData);
#endif
#if defined(SUPPORT_FILEFORMAT_FLAC)
- else if (music.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)music.ctxData, NULL);
+ else if (music.ctxType == MUSIC_AUDIO_FLAC) { drflac_close((drflac *)music.ctxData); drflac_free((drflac *)music.ctxData, NULL); }
#endif
#if defined(SUPPORT_FILEFORMAT_XM)
else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData);
diff --git a/src/raylib.h b/src/raylib.h
index 0851905c1..e58469856 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -36,7 +36,7 @@
* [rcore] msf_gif (Miles Fogle) for GIF recording
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm
-* [rcore] rprand (Ramon Snatamaria) for pseudo-random numbers generation
+* [rcore] rprand (Ramon Santamaria) for pseudo-random numbers generation
* [rtextures] qoi (Dominic Szablewski - https://phoboslab.org) for QOI image manage
* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG)
@@ -1129,7 +1129,7 @@ RLAPI bool SaveFileText(const char *fileName, const char *text); // Save text d
// File system functions
RLAPI bool FileExists(const char *fileName); // Check if file exists
RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists
-RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (including point: .png, .wav)
+RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (recommended include point: .png, .wav)
RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h)
RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png')
RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
@@ -1506,6 +1506,8 @@ RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size);
// Text strings management functions (no UTF-8 strings, only byte chars)
// WARNING 1: Most of these functions use internal static buffers, it's recommended to store returned data on user-side for re-use
// WARNING 2: Some strings allocate memory internally for the returned strings, those strings must be free by user using MemFree()
+RLAPI char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
+RLAPI void UnloadTextLines(char **text); // Unload text lines
RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending
@@ -1522,7 +1524,6 @@ RLAPI char *TextToLower(const char *text);
RLAPI char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
RLAPI char *TextToSnake(const char *text); // Get Snake case notation version of provided string
RLAPI char *TextToCamel(const char *text); // Get Camel case notation version of provided string
-
RLAPI int TextToInteger(const char *text); // Get integer value from text
RLAPI float TextToFloat(const char *text); // Get float value from text
diff --git a/src/rcore.c b/src/rcore.c
index 46e39991f..2927b4952 100644
--- a/src/rcore.c
+++ b/src/rcore.c
@@ -113,7 +113,7 @@
#include // Required for: srand(), rand(), atexit()
#include // Required for: sprintf() [Used in OpenURL()]
-#include // Required for: strrchr(), strcmp(), strlen(), memset()
+#include // Required for: strlen(), strcpy(), strcmp(), strrchr(), memset()
#include // Required for: time() [Used in InitTimer()]
#include // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
@@ -333,9 +333,11 @@ typedef struct CoreData {
Vector2 scale; // Mouse scaling
Vector2 currentPosition; // Mouse position on screen
Vector2 previousPosition; // Previous mouse position
+ Vector2 lockedPosition; // Mouse position when locked
int cursor; // Tracks current mouse cursor
bool cursorHidden; // Track if cursor is hidden
+ bool cursorLocked; // Track if cursor is locked (disabled)
bool cursorOnScreen; // Tracks if cursor is inside client area
char currentButtonState[MAX_MOUSE_BUTTONS]; // Registers current mouse button state
@@ -512,11 +514,11 @@ static void RecordAutomationEvent(void); // Record frame events (to internal eve
#if defined(_WIN32) && !defined(PLATFORM_DESKTOP_RGFW)
// NOTE: We declare Sleep() function symbol to avoid including windows.h (kernel32.lib linkage required)
-__declspec(dllimport) void __stdcall Sleep(unsigned long msTimeout); // Required for: WaitTime()
+__declspec(dllimport) void __stdcall Sleep(unsigned long msTimeout); // Required for: WaitTime()
#endif
#if !defined(SUPPORT_MODULE_RTEXT)
-const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
+const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
#endif // !SUPPORT_MODULE_RTEXT
#if defined(PLATFORM_DESKTOP)
@@ -562,6 +564,7 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
#else
// TODO: Include your custom platform backend!
// i.e software rendering backend or console backend!
+ #pragma message ("WARNING: No [rcore] platform defined")
#endif
//----------------------------------------------------------------------------------
@@ -1940,34 +1943,64 @@ bool FileExists(const char *fileName)
}
// Check file extension
-// TODO: Avoid [rtext] module dependency
bool IsFileExtension(const char *fileName, const char *ext)
{
- #define MAX_FILE_EXTENSION_LENGTH 16
+ #define MAX_FILE_EXTENSIONS 32
bool result = false;
const char *fileExt = GetFileExtension(fileName);
+ // WARNING: fileExt points to last '.' on fileName string but it could happen
+ // that fileName is not correct: "myfile.png more text following\n"
+
if (fileExt != NULL)
{
-#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_TEXT_MANIPULATION)
- int extCount = 0;
- char **checkExts = TextSplit(ext, ';', &extCount); // WARNING: Module required: rtext
+ int fileExtLen = (int)strlen(fileExt);
+ char fileExtLower[16] = { 0 };
+ char *fileExtLowerPtr = fileExtLower;
+ for (int i = 0; (i < fileExtLen) && (i < 16); i++)
+ {
+ // Copy and convert to lower-case
+ if ((fileExt[i] >= 'A') && (fileExt[i] <= 'Z')) fileExtLower[i] = fileExt[i] + 32;
+ else fileExtLower[i] = fileExt[i];
+ }
- char fileExtLower[MAX_FILE_EXTENSION_LENGTH + 1] = { 0 };
- strncpy(fileExtLower, TextToLower(fileExt), MAX_FILE_EXTENSION_LENGTH); // WARNING: Module required: rtext
+ int extCount = 1;
+ int extLen = (int)strlen(ext);
+ char *extList = (char *)RL_CALLOC(extLen + 1, 1);
+ char *extListPtrs[MAX_FILE_EXTENSIONS] = { 0 };
+ strcpy(extList, ext);
+ extListPtrs[0] = extList;
+
+ for (int i = 0; i < extLen; i++)
+ {
+ // Convert to lower-case if extension is upper-case
+ if ((extList[i] >= 'A') && (extList[i] <= 'Z')) extList[i] += 32;
+
+ // Get pointer to next extension and add null-terminator
+ if ((extList[i] == ';') && (extCount < (MAX_FILE_EXTENSIONS - 1)))
+ {
+ extList[i] = '\0';
+ extListPtrs[extCount] = extList + i + 1;
+ extCount++;
+ }
+ }
for (int i = 0; i < extCount; i++)
{
- if (strcmp(fileExtLower, TextToLower(checkExts[i])) == 0)
+ // Consider the case where extension provided
+ // does not start with the '.'
+ fileExtLowerPtr = fileExtLower;
+ if (extListPtrs[i][0] != '.') fileExtLowerPtr++;
+
+ if (strcmp(fileExtLowerPtr, extListPtrs[i]) == 0)
{
result = true;
break;
}
}
-#else
- if (strcmp(fileExt, ext) == 0) result = true;
-#endif
+
+ RL_FREE(extList);
}
return result;
@@ -2018,11 +2051,12 @@ int GetFileLength(const char *fileName)
}
// Get pointer to extension for a filename string (includes the dot: .png)
+// WARNING: We just get the ptr but not the extension as a separate string
const char *GetFileExtension(const char *fileName)
{
const char *dot = strrchr(fileName, '.');
- if (!dot || dot == fileName) return NULL;
+ if (!dot || (dot == fileName)) return NULL;
return dot;
}
diff --git a/src/rlgl.h b/src/rlgl.h
index e83cb55a7..17c854f10 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -2573,7 +2573,7 @@ void rlLoadExtensions(void *loader)
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
RLGL.loader = (rlglLoadProc)loader;
-
+
// NOTE: Anisotropy levels capability is an extension
#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
diff --git a/src/rmodels.c b/src/rmodels.c
index c1a32058a..ebd3b92d1 100644
--- a/src/rmodels.c
+++ b/src/rmodels.c
@@ -5488,14 +5488,16 @@ static Model LoadGLTF(const char *fileName)
// Other possible materials not supported by raylib pipeline:
// has_clearcoat, has_transmission, has_volume, has_ior, has specular, has_sheen
}
+ //----------------------------------------------------------------------------------------------------
- // Visit each node in the hierarchy and process any mesh linked from it
- // Each primitive within a glTF node becomes a Raylib Mesh
- // The local-to-world transform of each node is used to transform the
- // points/normals/tangents of the created Mesh(es)
- // Any glTF mesh linked from more than one Node (i.e. instancing)
- // is turned into multiple Mesh's, as each Node will have its own transform applied
- // NOTE: The code below disregards the scenes defined in the file, all nodes are used
+ // Load meshes data
+ //
+ // NOTE: Visit each node in the hierarchy and process any mesh linked from it
+ // - Each primitive within a glTF node becomes a raylib Mesh
+ // - The local-to-world transform of each node is used to transform the points/normals/tangents of the created Mesh(es)
+ // - Any glTF mesh linked from more than one Node (i.e. instancing) is turned into multiple Mesh's, as each Node will have its own transform applied
+ //
+ // WARNING: The code below disregards the scenes defined in the file, all nodes are used
//----------------------------------------------------------------------------------------------------
int meshIndex = 0;
for (unsigned int i = 0; i < data->nodes_count; i++)
@@ -5503,8 +5505,7 @@ static Model LoadGLTF(const char *fileName)
cgltf_node *node = &(data->nodes[i]);
cgltf_mesh *mesh = node->mesh;
- if (!mesh)
- continue;
+ if (!mesh) continue;
cgltf_float worldTransform[16];
cgltf_node_transform_world(node, worldTransform);
@@ -5535,75 +5536,87 @@ static Model LoadGLTF(const char *fileName)
cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
// WARNING: SPECS: POSITION accessor MUST have its min and max properties defined
-
- if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
+
+ if (model.meshes[meshIndex].vertices != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data already loaded", fileName);
+ else
{
- // Init raylib mesh vertices to copy glTF attribute data
- model.meshes[meshIndex].vertexCount = (int)attribute->count;
- model.meshes[meshIndex].vertices = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
-
- // Load 3 components of float data type into mesh.vertices
- LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices)
-
- // Transform the vertices
- float *vertices = model.meshes[meshIndex].vertices;
- for (unsigned int k = 0; k < attribute->count; k++)
+ if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
{
- Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix);
- vertices[3*k] = vt.x;
- vertices[3*k+1] = vt.y;
- vertices[3*k+2] = vt.z;
+ // Init raylib mesh vertices to copy glTF attribute data
+ model.meshes[meshIndex].vertexCount = (int)attribute->count;
+ model.meshes[meshIndex].vertices = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
+
+ // Load 3 components of float data type into mesh.vertices
+ LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices)
+
+ // Transform the vertices
+ float *vertices = model.meshes[meshIndex].vertices;
+ for (unsigned int k = 0; k < attribute->count; k++)
+ {
+ Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix);
+ vertices[3*k] = vt.x;
+ vertices[3*k+1] = vt.y;
+ vertices[3*k+2] = vt.z;
+ }
}
+ else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName);
}
- else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName);
}
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL, vec3, float
{
cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
- if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
+ if (model.meshes[meshIndex].normals != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Normals attribute data already loaded", fileName);
+ else
{
- // Init raylib mesh normals to copy glTF attribute data
- model.meshes[meshIndex].normals = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
-
- // Load 3 components of float data type into mesh.normals
- LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals)
-
- // Transform the normals
- float *normals = model.meshes[meshIndex].normals;
- for (unsigned int k = 0; k < attribute->count; k++)
+ if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
{
- Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals);
- normals[3*k] = nt.x;
- normals[3*k+1] = nt.y;
- normals[3*k+2] = nt.z;
+ // Init raylib mesh normals to copy glTF attribute data
+ model.meshes[meshIndex].normals = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
+
+ // Load 3 components of float data type into mesh.normals
+ LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals)
+
+ // Transform the normals
+ float *normals = model.meshes[meshIndex].normals;
+ for (unsigned int k = 0; k < attribute->count; k++)
+ {
+ Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals);
+ normals[3*k] = nt.x;
+ normals[3*k+1] = nt.y;
+ normals[3*k+2] = nt.z;
+ }
}
+ else TRACELOG(LOG_WARNING, "MODEL: [%s] Normals attribute data format not supported, use vec3 float", fileName);
}
- else TRACELOG(LOG_WARNING, "MODEL: [%s] Normal attribute data format not supported, use vec3 float", fileName);
}
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT, vec4, float, w is tangent basis sign
{
cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
- if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f))
+ if (model.meshes[meshIndex].tangents != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Tangents attribute data already loaded", fileName);
+ else
{
- // Init raylib mesh tangent to copy glTF attribute data
- model.meshes[meshIndex].tangents = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
-
- // Load 4 components of float data type into mesh.tangents
- LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents)
-
- // Transform the tangents
- float *tangents = model.meshes[meshIndex].tangents;
- for (unsigned int k = 0; k < attribute->count; k++)
+ if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f))
{
- Vector3 tt = Vector3Transform((Vector3){ tangents[4*k], tangents[4*k+1], tangents[4*k+2] }, worldMatrix);
- tangents[4*k] = tt.x;
- tangents[4*k+1] = tt.y;
- tangents[4*k+2] = tt.z;
+ // Init raylib mesh tangent to copy glTF attribute data
+ model.meshes[meshIndex].tangents = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
+
+ // Load 4 components of float data type into mesh.tangents
+ LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents)
+
+ // Transform the tangents
+ float *tangents = model.meshes[meshIndex].tangents;
+ for (unsigned int k = 0; k < attribute->count; k++)
+ {
+ Vector3 tt = Vector3Transform((Vector3){ tangents[4*k], tangents[4*k+1], tangents[4*k+2] }, worldMatrix);
+ tangents[4*k] = tt.x;
+ tangents[4*k+1] = tt.y;
+ tangents[4*k+2] = tt.z;
+ }
}
+ else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangents attribute data format not supported, use vec4 float", fileName);
}
- else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName);
}
else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n
{
@@ -5669,114 +5682,118 @@ static Model LoadGLTF(const char *fileName)
// WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range
- if (attribute->type == cgltf_type_vec3) // RGB
+ if (model.meshes[meshIndex].colors != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Colors attribute data already loaded", fileName);
+ else
{
- if (attribute->component_type == cgltf_component_type_r_8u)
+ if (attribute->type == cgltf_type_vec3) // RGB
{
- // Init raylib mesh color to copy glTF attribute data
- model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
-
- // Load data into a temp buffer to be converted to raylib data type
- unsigned char *temp = (unsigned char *)RL_MALLOC(attribute->count*3*sizeof(unsigned char));
- LOAD_ATTRIBUTE(attribute, 3, unsigned char, temp);
-
- // Convert data to raylib color data type (4 bytes)
- for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
+ if (attribute->component_type == cgltf_component_type_r_8u)
{
- model.meshes[meshIndex].colors[c] = temp[k];
- model.meshes[meshIndex].colors[c + 1] = temp[k + 1];
- model.meshes[meshIndex].colors[c + 2] = temp[k + 2];
- model.meshes[meshIndex].colors[c + 3] = 255;
- }
+ // Init raylib mesh color to copy glTF attribute data
+ model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
- RL_FREE(temp);
+ // Load data into a temp buffer to be converted to raylib data type
+ unsigned char *temp = (unsigned char *)RL_MALLOC(attribute->count*3*sizeof(unsigned char));
+ LOAD_ATTRIBUTE(attribute, 3, unsigned char, temp);
+
+ // Convert data to raylib color data type (4 bytes)
+ for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
+ {
+ model.meshes[meshIndex].colors[c] = temp[k];
+ model.meshes[meshIndex].colors[c + 1] = temp[k + 1];
+ model.meshes[meshIndex].colors[c + 2] = temp[k + 2];
+ model.meshes[meshIndex].colors[c + 3] = 255;
+ }
+
+ RL_FREE(temp);
+ }
+ else if (attribute->component_type == cgltf_component_type_r_16u)
+ {
+ // Init raylib mesh color to copy glTF attribute data
+ model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
+
+ // Load data into a temp buffer to be converted to raylib data type
+ unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*3*sizeof(unsigned short));
+ LOAD_ATTRIBUTE(attribute, 3, unsigned short, temp);
+
+ // Convert data to raylib color data type (4 bytes)
+ for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
+ {
+ model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[k]/65535.0f)*255.0f);
+ model.meshes[meshIndex].colors[c + 1] = (unsigned char)(((float)temp[k + 1]/65535.0f)*255.0f);
+ model.meshes[meshIndex].colors[c + 2] = (unsigned char)(((float)temp[k + 2]/65535.0f)*255.0f);
+ model.meshes[meshIndex].colors[c + 3] = 255;
+ }
+
+ RL_FREE(temp);
+ }
+ else if (attribute->component_type == cgltf_component_type_r_32f)
+ {
+ // Init raylib mesh color to copy glTF attribute data
+ model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
+
+ // Load data into a temp buffer to be converted to raylib data type
+ float *temp = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
+ LOAD_ATTRIBUTE(attribute, 3, float, temp);
+
+ // Convert data to raylib color data type (4 bytes)
+ for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
+ {
+ model.meshes[meshIndex].colors[c] = (unsigned char)(temp[k]*255.0f);
+ model.meshes[meshIndex].colors[c + 1] = (unsigned char)(temp[k + 1]*255.0f);
+ model.meshes[meshIndex].colors[c + 2] = (unsigned char)(temp[k + 2]*255.0f);
+ model.meshes[meshIndex].colors[c + 3] = 255;
+ }
+
+ RL_FREE(temp);
+ }
+ else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
}
- else if (attribute->component_type == cgltf_component_type_r_16u)
+ else if (attribute->type == cgltf_type_vec4) // RGBA
{
- // Init raylib mesh color to copy glTF attribute data
- model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
-
- // Load data into a temp buffer to be converted to raylib data type
- unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*3*sizeof(unsigned short));
- LOAD_ATTRIBUTE(attribute, 3, unsigned short, temp);
-
- // Convert data to raylib color data type (4 bytes)
- for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
+ if (attribute->component_type == cgltf_component_type_r_8u)
{
- model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[k]/65535.0f)*255.0f);
- model.meshes[meshIndex].colors[c + 1] = (unsigned char)(((float)temp[k + 1]/65535.0f)*255.0f);
- model.meshes[meshIndex].colors[c + 2] = (unsigned char)(((float)temp[k + 2]/65535.0f)*255.0f);
- model.meshes[meshIndex].colors[c + 3] = 255;
+ // Init raylib mesh color to copy glTF attribute data
+ model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
+
+ // Load 4 components of unsigned char data type into mesh.colors
+ LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].colors)
}
-
- RL_FREE(temp);
- }
- else if (attribute->component_type == cgltf_component_type_r_32f)
- {
- // Init raylib mesh color to copy glTF attribute data
- model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
-
- // Load data into a temp buffer to be converted to raylib data type
- float *temp = (float *)RL_MALLOC(attribute->count*3*sizeof(float));
- LOAD_ATTRIBUTE(attribute, 3, float, temp);
-
- // Convert data to raylib color data type (4 bytes)
- for (unsigned int c = 0, k = 0; c < (attribute->count*4 - 3); c += 4, k += 3)
+ else if (attribute->component_type == cgltf_component_type_r_16u)
{
- model.meshes[meshIndex].colors[c] = (unsigned char)(temp[k]*255.0f);
- model.meshes[meshIndex].colors[c + 1] = (unsigned char)(temp[k + 1]*255.0f);
- model.meshes[meshIndex].colors[c + 2] = (unsigned char)(temp[k + 2]*255.0f);
- model.meshes[meshIndex].colors[c + 3] = 255;
- }
+ // Init raylib mesh color to copy glTF attribute data
+ model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
- RL_FREE(temp);
+ // Load data into a temp buffer to be converted to raylib data type
+ unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*4*sizeof(unsigned short));
+ LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp);
+
+ // Convert data to raylib color data type (4 bytes)
+ for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[c]/65535.0f)*255.0f);
+
+ RL_FREE(temp);
+ }
+ else if (attribute->component_type == cgltf_component_type_r_32f)
+ {
+ // Init raylib mesh color to copy glTF attribute data
+ model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
+
+ // Load data into a temp buffer to be converted to raylib data type
+ float *temp = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
+ LOAD_ATTRIBUTE(attribute, 4, float, temp);
+
+ // Convert data to raylib color data type (4 bytes), we expect the color data normalized
+ for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(temp[c]*255.0f);
+
+ RL_FREE(temp);
+ }
+ else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
}
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
}
- else if (attribute->type == cgltf_type_vec4) // RGBA
- {
- if (attribute->component_type == cgltf_component_type_r_8u)
- {
- // Init raylib mesh color to copy glTF attribute data
- model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
-
- // Load 4 components of unsigned char data type into mesh.colors
- LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].colors)
- }
- else if (attribute->component_type == cgltf_component_type_r_16u)
- {
- // Init raylib mesh color to copy glTF attribute data
- model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
-
- // Load data into a temp buffer to be converted to raylib data type
- unsigned short *temp = (unsigned short *)RL_MALLOC(attribute->count*4*sizeof(unsigned short));
- LOAD_ATTRIBUTE(attribute, 4, unsigned short, temp);
-
- // Convert data to raylib color data type (4 bytes)
- for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(((float)temp[c]/65535.0f)*255.0f);
-
- RL_FREE(temp);
- }
- else if (attribute->component_type == cgltf_component_type_r_32f)
- {
- // Init raylib mesh color to copy glTF attribute data
- model.meshes[meshIndex].colors = (unsigned char *)RL_MALLOC(attribute->count*4*sizeof(unsigned char));
-
- // Load data into a temp buffer to be converted to raylib data type
- float *temp = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
- LOAD_ATTRIBUTE(attribute, 4, float, temp);
-
- // Convert data to raylib color data type (4 bytes), we expect the color data normalized
- for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(temp[c]*255.0f);
-
- RL_FREE(temp);
- }
- else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
- }
- else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
}
- // NOTE: Attributes related to animations are processed separately
+ // NOTE: Attributes related to animations data are processed after mesh data loading
}
// Load primitive indices data (if provided)
@@ -5786,32 +5803,33 @@ static Model LoadGLTF(const char *fileName)
model.meshes[meshIndex].triangleCount = (int)attribute->count/3;
- if (attribute->component_type == cgltf_component_type_r_16u)
- {
- // Init raylib mesh indices to copy glTF attribute data
- model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
-
- // Load unsigned short data type into mesh.indices
- LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices)
- }
- else if (attribute->component_type == cgltf_component_type_r_8u)
- {
- // Init raylib mesh indices to copy glTF attribute data
- model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
- LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short)
-
- }
- else if (attribute->component_type == cgltf_component_type_r_32u)
- {
- // Init raylib mesh indices to copy glTF attribute data
- model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
- LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned int, model.meshes[meshIndex].indices, unsigned short);
-
- TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);
- }
+ if (model.meshes[meshIndex].indices != NULL) TRACELOG(LOG_WARNING, "MODEL: [%s] Indices attribute data already loaded", fileName);
else
{
- TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName);
+ if (attribute->component_type == cgltf_component_type_r_16u)
+ {
+ // Init raylib mesh indices to copy glTF attribute data
+ model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
+
+ // Load unsigned short data type into mesh.indices
+ LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices)
+ }
+ else if (attribute->component_type == cgltf_component_type_r_8u)
+ {
+ // Init raylib mesh indices to copy glTF attribute data
+ model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
+ LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short)
+
+ }
+ else if (attribute->component_type == cgltf_component_type_r_32u)
+ {
+ // Init raylib mesh indices to copy glTF attribute data
+ model.meshes[meshIndex].indices = (unsigned short *)RL_MALLOC(attribute->count*sizeof(unsigned short));
+ LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned int, model.meshes[meshIndex].indices, unsigned short);
+
+ TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);
+ }
+ else TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName);
}
}
else model.meshes[meshIndex].triangleCount = model.meshes[meshIndex].vertexCount/3; // Unindexed mesh
@@ -5834,8 +5852,9 @@ static Model LoadGLTF(const char *fileName)
meshIndex++; // Move to next mesh
}
}
+ //----------------------------------------------------------------------------------------------------
- // Load glTF meshes animation data
+ // Load animation data
// REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skins
// REF: https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes
//
@@ -5863,10 +5882,8 @@ static Model LoadGLTF(const char *fileName)
};
MatrixDecompose(worldMatrix, &(model.bindPose[i].translation), &(model.bindPose[i].rotation), &(model.bindPose[i].scale));
}
- }
- if (data->skins_count > 1)
- {
- TRACELOG(LOG_WARNING, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
+
+ if (data->skins_count > 1) TRACELOG(LOG_WARNING, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
}
meshIndex = 0;
@@ -5875,8 +5892,7 @@ static Model LoadGLTF(const char *fileName)
cgltf_node *node = &(data->nodes[i]);
cgltf_mesh *mesh = node->mesh;
- if (!mesh)
- continue;
+ if (!mesh) continue;
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{
@@ -6039,6 +6055,7 @@ static Model LoadGLTF(const char *fileName)
meshIndex++; // Move to next mesh
}
}
+ //----------------------------------------------------------------------------------------------------
// Free all cgltf loaded data
cgltf_free(data);
diff --git a/src/rtext.c b/src/rtext.c
index 50ea6c883..f54c71aef 100644
--- a/src/rtext.c
+++ b/src/rtext.c
@@ -93,6 +93,9 @@
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
+ #define STBTT_malloc(x,u) ((void)(u),RL_MALLOC(x))
+ #define STBTT_free(x,u) ((void)(u),RL_FREE(x))
+
#define STBTT_STATIC
#define STB_TRUETYPE_IMPLEMENTATION
#include "external/stb_truetype.h" // Required for: ttf font data reading
@@ -847,7 +850,7 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp
{
for (int j = i + 1; j < glyphCount; j++)
{
- TRACELOG(LOG_WARNING, "FONT: Failed to package character (%i)", j);
+ TRACELOG(LOG_WARNING, "FONT: Failed to package character (0x%02x)", glyphs[j].value);
// Make sure remaining recs contain valid data
recs[j].x = 0;
recs[j].y = 0;
@@ -915,7 +918,7 @@ Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyp
}
}
}
- else TRACELOG(LOG_WARNING, "FONT: Failed to package character (%i)", i);
+ else TRACELOG(LOG_WARNING, "FONT: Failed to package character (0x%02x)", glyphs[i].value);
}
RL_FREE(rects);
@@ -1412,6 +1415,40 @@ Rectangle GetGlyphAtlasRec(Font font, int codepoint)
//----------------------------------------------------------------------------------
// Text strings management functions
//----------------------------------------------------------------------------------
+// Load text as separate lines ('\n')
+// WARNING: There is a limit set for number of lines and line-size
+char **LoadTextLines(const char *text, int *count)
+{
+ #define MAX_TEXTLINES_COUNT 512
+ #define MAX_TEXTLINES_LINE_LEN 512
+
+ char **lines = (char **)RL_CALLOC(MAX_TEXTLINES_COUNT, sizeof(char *));
+ for (int i = 0; i < MAX_TEXTLINES_COUNT; i++) lines[i] = (char *)RL_CALLOC(MAX_TEXTLINES_LINE_LEN, 1);
+ int textSize = (int)strlen(text);
+ int k = 0;
+
+ for (int i = 0, len = 0; (i < textSize) && (k < MAX_TEXTLINES_COUNT); i++)
+ {
+ if ((text[i] == '\n') || (len == (MAX_TEXTLINES_LINE_LEN - 1)))
+ {
+ strncpy(lines[k], &text[i - len], len);
+ len = 0;
+ k++;
+ }
+ else len++;
+ }
+
+ *count += k;
+ return lines;
+}
+
+// Unload text lines
+void UnloadTextLines(char **lines)
+{
+ for (int i = 0; i < MAX_TEXTLINES_COUNT; i++) RL_FREE(lines[i]);
+ RL_FREE(lines);
+}
+
// Get text length in bytes, check for \0 character
unsigned int TextLength(const char *text)
{
diff --git a/tools/parser/Makefile b/tools/parser/Makefile
index 165192463..ecfdb44ba 100644
--- a/tools/parser/Makefile
+++ b/tools/parser/Makefile
@@ -6,34 +6,28 @@ FORMAT?=DEFAULT
raylib_parser: raylib_parser.c
cc raylib_parser.c -o raylib_parser
-raylib_api: ../src/raylib.h raylib_parser
+raylib_api: ../../src/raylib.h raylib_parser
FORMAT=DEFAULT EXTENSION=txt $(MAKE) raylib_api.txt
FORMAT=JSON EXTENSION=json $(MAKE) raylib_api.json
FORMAT=XML EXTENSION=xml $(MAKE) raylib_api.xml
FORMAT=LUA EXTENSION=lua $(MAKE) raylib_api.lua
-raylib_api.$(EXTENSION): ../src/raylib.h raylib_parser
- ./raylib_parser -i ../src/raylib.h -o raylib_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
+raylib_api.$(EXTENSION): ../../src/raylib.h raylib_parser
+ ./raylib_parser -i ../../src/raylib.h -o raylib_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
-raymath_api.$(EXTENSION): ../src/raymath.h raylib_parser
- ./raylib_parser -i ../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
+raymath_api.$(EXTENSION): ../../src/raymath.h raylib_parser
+ ./raylib_parser -i ../../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
-rlgl_api.$(EXTENSION): ../src/rlgl.h raylib_parser
- ./raylib_parser -i ../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI -t "RLGL IMPLEMENTATION"
+rlgl_api.$(EXTENSION): ../../src/rlgl.h raylib_parser
+ ./raylib_parser -i ../../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI -t "RLGL IMPLEMENTATION"
-reasings_api.$(EXTENSION): ../examples/others/reasings.h raylib_parser
- ./raylib_parser -i ../examples/others/reasings.h -o reasings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
-
-rmem_api.$(EXTENSION): ../rmem.h raylib_parser
- ./raylib_parser -i ../rmem.h -o rmem_api.$(EXTENSION) -f $(FORMAT) -d RMEMAPI -t "RMEM IMPLEMENTATION"
-
-physac_api.$(EXTENSION): ../physac.h raylib_parser
- ./raylib_parser -i ../physac.h -o physac_api.$(EXTENSION) -f $(FORMAT) -d PHYSACDEF -t "PHYSAC IMPLEMENTATION"
+reasings_api.$(EXTENSION): ../../examples/others/reasings.h raylib_parser
+ ./raylib_parser -i ../../examples/others/reasings.h -o reasings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
raygui_api.$(EXTENSION): ../raygui.h raylib_parser
./raylib_parser -i ../raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI -t "RAYGUI IMPLEMENTATION"
-parse: raylib_api.$(EXTENSION) raymath_api.$(EXTENSION) rlgl_api.$(EXTENSION) rmem_api.$(EXTENSION) physac_api.$(EXTENSION) raygui_api.$(EXTENSION)
+parse: raylib_api.$(EXTENSION) raymath_api.$(EXTENSION) rlgl_api.$(EXTENSION) raygui_api.$(EXTENSION)
# `make parse` (and therefore `make all) requires
diff --git a/tools/parser/output/raylib_api.json b/tools/parser/output/raylib_api.json
index c2a4a1827..714e02907 100644
--- a/tools/parser/output/raylib_api.json
+++ b/tools/parser/output/raylib_api.json
@@ -4438,7 +4438,7 @@
},
{
"name": "IsFileExtension",
- "description": "Check file extension (including point: .png, .wav)",
+ "description": "Check file extension (recommended include point: .png, .wav)",
"returnType": "bool",
"params": [
{
@@ -9605,6 +9605,32 @@
}
]
},
+ {
+ "name": "LoadTextLines",
+ "description": "Load text as separate lines ('\\n')",
+ "returnType": "char **",
+ "params": [
+ {
+ "type": "const char *",
+ "name": "text"
+ },
+ {
+ "type": "int *",
+ "name": "count"
+ }
+ ]
+ },
+ {
+ "name": "UnloadTextLines",
+ "description": "Unload text lines",
+ "returnType": "void",
+ "params": [
+ {
+ "type": "char **",
+ "name": "text"
+ }
+ ]
+ },
{
"name": "TextCopy",
"description": "Copy one string to another, returns bytes copied",
diff --git a/tools/parser/output/raylib_api.lua b/tools/parser/output/raylib_api.lua
index 23547d9f1..c66bad1a7 100644
--- a/tools/parser/output/raylib_api.lua
+++ b/tools/parser/output/raylib_api.lua
@@ -4027,7 +4027,7 @@ return {
},
{
name = "IsFileExtension",
- description = "Check file extension (including point: .png, .wav)",
+ description = "Check file extension (recommended include point: .png, .wav)",
returnType = "bool",
params = {
{type = "const char *", name = "fileName"},
@@ -6845,6 +6845,23 @@ return {
{type = "int *", name = "utf8Size"}
}
},
+ {
+ name = "LoadTextLines",
+ description = "Load text as separate lines ('\\n')",
+ returnType = "char **",
+ params = {
+ {type = "const char *", name = "text"},
+ {type = "int *", name = "count"}
+ }
+ },
+ {
+ name = "UnloadTextLines",
+ description = "Unload text lines",
+ returnType = "void",
+ params = {
+ {type = "char **", name = "text"}
+ }
+ },
{
name = "TextCopy",
description = "Copy one string to another, returns bytes copied",
diff --git a/tools/parser/output/raylib_api.txt b/tools/parser/output/raylib_api.txt
index 9539d72a5..765c077e5 100644
--- a/tools/parser/output/raylib_api.txt
+++ b/tools/parser/output/raylib_api.txt
@@ -993,7 +993,7 @@ Callback 006: AudioCallback() (2 input parameters)
Param[1]: bufferData (type: void *)
Param[2]: frames (type: unsigned int)
-Functions found: 584
+Functions found: 586
Function 001: InitWindow() (3 input parameters)
Name: InitWindow
@@ -1670,7 +1670,7 @@ Function 125: DirectoryExists() (1 input parameters)
Function 126: IsFileExtension() (2 input parameters)
Name: IsFileExtension
Return type: bool
- Description: Check file extension (including point: .png, .wav)
+ Description: Check file extension (recommended include point: .png, .wav)
Param[1]: fileName (type: const char *)
Param[2]: ext (type: const char *)
Function 127: GetFileLength() (1 input parameters)
@@ -3674,126 +3674,137 @@ Function 424: CodepointToUTF8() (2 input parameters)
Description: Encode one codepoint into UTF-8 byte array (array length returned as parameter)
Param[1]: codepoint (type: int)
Param[2]: utf8Size (type: int *)
-Function 425: TextCopy() (2 input parameters)
+Function 425: LoadTextLines() (2 input parameters)
+ Name: LoadTextLines
+ Return type: char **
+ Description: Load text as separate lines ('\n')
+ Param[1]: text (type: const char *)
+ Param[2]: count (type: int *)
+Function 426: UnloadTextLines() (1 input parameters)
+ Name: UnloadTextLines
+ Return type: void
+ Description: Unload text lines
+ Param[1]: text (type: char **)
+Function 427: TextCopy() (2 input parameters)
Name: TextCopy
Return type: int
Description: Copy one string to another, returns bytes copied
Param[1]: dst (type: char *)
Param[2]: src (type: const char *)
-Function 426: TextIsEqual() (2 input parameters)
+Function 428: TextIsEqual() (2 input parameters)
Name: TextIsEqual
Return type: bool
Description: Check if two text string are equal
Param[1]: text1 (type: const char *)
Param[2]: text2 (type: const char *)
-Function 427: TextLength() (1 input parameters)
+Function 429: TextLength() (1 input parameters)
Name: TextLength
Return type: unsigned int
Description: Get text length, checks for '\0' ending
Param[1]: text (type: const char *)
-Function 428: TextFormat() (2 input parameters)
+Function 430: TextFormat() (2 input parameters)
Name: TextFormat
Return type: const char *
Description: Text formatting with variables (sprintf() style)
Param[1]: text (type: const char *)
Param[2]: args (type: ...)
-Function 429: TextSubtext() (3 input parameters)
+Function 431: TextSubtext() (3 input parameters)
Name: TextSubtext
Return type: const char *
Description: Get a piece of a text string
Param[1]: text (type: const char *)
Param[2]: position (type: int)
Param[3]: length (type: int)
-Function 430: TextReplace() (3 input parameters)
+Function 432: TextReplace() (3 input parameters)
Name: TextReplace
Return type: char *
Description: Replace text string (WARNING: memory must be freed!)
Param[1]: text (type: const char *)
Param[2]: replace (type: const char *)
Param[3]: by (type: const char *)
-Function 431: TextInsert() (3 input parameters)
+Function 433: TextInsert() (3 input parameters)
Name: TextInsert
Return type: char *
Description: Insert text in a position (WARNING: memory must be freed!)
Param[1]: text (type: const char *)
Param[2]: insert (type: const char *)
Param[3]: position (type: int)
-Function 432: TextJoin() (3 input parameters)
+Function 434: TextJoin() (3 input parameters)
Name: TextJoin
Return type: char *
Description: Join text strings with delimiter
Param[1]: textList (type: char **)
Param[2]: count (type: int)
Param[3]: delimiter (type: const char *)
-Function 433: TextSplit() (3 input parameters)
+Function 435: TextSplit() (3 input parameters)
Name: TextSplit
Return type: char **
Description: Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings
Param[1]: text (type: const char *)
Param[2]: delimiter (type: char)
Param[3]: count (type: int *)
-Function 434: TextAppend() (3 input parameters)
+Function 436: TextAppend() (3 input parameters)
Name: TextAppend
Return type: void
Description: Append text at specific position and move cursor!
Param[1]: text (type: char *)
Param[2]: append (type: const char *)
Param[3]: position (type: int *)
-Function 435: TextFindIndex() (2 input parameters)
+Function 437: TextFindIndex() (2 input parameters)
Name: TextFindIndex
Return type: int
Description: Find first text occurrence within a string, -1 if not found
Param[1]: text (type: const char *)
Param[2]: find (type: const char *)
-Function 436: TextToUpper() (1 input parameters)
+Function 438: TextToUpper() (1 input parameters)
Name: TextToUpper
Return type: char *
Description: Get upper case version of provided string
Param[1]: text (type: const char *)
-Function 437: TextToLower() (1 input parameters)
+Function 439: TextToLower() (1 input parameters)
Name: TextToLower
Return type: char *
Description: Get lower case version of provided string
Param[1]: text (type: const char *)
-Function 438: TextToPascal() (1 input parameters)
+Function 440: TextToPascal() (1 input parameters)
Name: TextToPascal
Return type: char *
Description: Get Pascal case notation version of provided string
Param[1]: text (type: const char *)
-Function 439: TextToSnake() (1 input parameters)
+Function 441: TextToSnake() (1 input parameters)
Name: TextToSnake
Return type: char *
Description: Get Snake case notation version of provided string
Param[1]: text (type: const char *)
-Function 440: TextToCamel() (1 input parameters)
+Function 442: TextToCamel() (1 input parameters)
Name: TextToCamel
Return type: char *
Description: Get Camel case notation version of provided string
Param[1]: text (type: const char *)
-Function 441: TextToInteger() (1 input parameters)
+Function 443: TextToInteger() (1 input parameters)
Name: TextToInteger
Return type: int
Description: Get integer value from text
Param[1]: text (type: const char *)
-Function 442: TextToFloat() (1 input parameters)
+Function 444: TextToFloat() (1 input parameters)
Name: TextToFloat
Return type: float
Description: Get float value from text
Param[1]: text (type: const char *)
-Function 443: DrawLine3D() (3 input parameters)
+Function 445: DrawLine3D() (3 input parameters)
Name: DrawLine3D
Return type: void
Description: Draw a line in 3D world space
Param[1]: startPos (type: Vector3)
Param[2]: endPos (type: Vector3)
Param[3]: color (type: Color)
-Function 444: DrawPoint3D() (2 input parameters)
+Function 446: DrawPoint3D() (2 input parameters)
Name: DrawPoint3D
Return type: void
Description: Draw a point in 3D space, actually a small line
Param[1]: position (type: Vector3)
Param[2]: color (type: Color)
-Function 445: DrawCircle3D() (5 input parameters)
+Function 447: DrawCircle3D() (5 input parameters)
Name: DrawCircle3D
Return type: void
Description: Draw a circle in 3D world space
@@ -3802,7 +3813,7 @@ Function 445: DrawCircle3D() (5 input parameters)
Param[3]: rotationAxis (type: Vector3)
Param[4]: rotationAngle (type: float)
Param[5]: color (type: Color)
-Function 446: DrawTriangle3D() (4 input parameters)
+Function 448: DrawTriangle3D() (4 input parameters)
Name: DrawTriangle3D
Return type: void
Description: Draw a color-filled triangle (vertex in counter-clockwise order!)
@@ -3810,14 +3821,14 @@ Function 446: DrawTriangle3D() (4 input parameters)
Param[2]: v2 (type: Vector3)
Param[3]: v3 (type: Vector3)
Param[4]: color (type: Color)
-Function 447: DrawTriangleStrip3D() (3 input parameters)
+Function 449: DrawTriangleStrip3D() (3 input parameters)
Name: DrawTriangleStrip3D
Return type: void
Description: Draw a triangle strip defined by points
Param[1]: points (type: const Vector3 *)
Param[2]: pointCount (type: int)
Param[3]: color (type: Color)
-Function 448: DrawCube() (5 input parameters)
+Function 450: DrawCube() (5 input parameters)
Name: DrawCube
Return type: void
Description: Draw cube
@@ -3826,14 +3837,14 @@ Function 448: DrawCube() (5 input parameters)
Param[3]: height (type: float)
Param[4]: length (type: float)
Param[5]: color (type: Color)
-Function 449: DrawCubeV() (3 input parameters)
+Function 451: DrawCubeV() (3 input parameters)
Name: DrawCubeV
Return type: void
Description: Draw cube (Vector version)
Param[1]: position (type: Vector3)
Param[2]: size (type: Vector3)
Param[3]: color (type: Color)
-Function 450: DrawCubeWires() (5 input parameters)
+Function 452: DrawCubeWires() (5 input parameters)
Name: DrawCubeWires
Return type: void
Description: Draw cube wires
@@ -3842,21 +3853,21 @@ Function 450: DrawCubeWires() (5 input parameters)
Param[3]: height (type: float)
Param[4]: length (type: float)
Param[5]: color (type: Color)
-Function 451: DrawCubeWiresV() (3 input parameters)
+Function 453: DrawCubeWiresV() (3 input parameters)
Name: DrawCubeWiresV
Return type: void
Description: Draw cube wires (Vector version)
Param[1]: position (type: Vector3)
Param[2]: size (type: Vector3)
Param[3]: color (type: Color)
-Function 452: DrawSphere() (3 input parameters)
+Function 454: DrawSphere() (3 input parameters)
Name: DrawSphere
Return type: void
Description: Draw sphere
Param[1]: centerPos (type: Vector3)
Param[2]: radius (type: float)
Param[3]: color (type: Color)
-Function 453: DrawSphereEx() (5 input parameters)
+Function 455: DrawSphereEx() (5 input parameters)
Name: DrawSphereEx
Return type: void
Description: Draw sphere with extended parameters
@@ -3865,7 +3876,7 @@ Function 453: DrawSphereEx() (5 input parameters)
Param[3]: rings (type: int)
Param[4]: slices (type: int)
Param[5]: color (type: Color)
-Function 454: DrawSphereWires() (5 input parameters)
+Function 456: DrawSphereWires() (5 input parameters)
Name: DrawSphereWires
Return type: void
Description: Draw sphere wires
@@ -3874,7 +3885,7 @@ Function 454: DrawSphereWires() (5 input parameters)
Param[3]: rings (type: int)
Param[4]: slices (type: int)
Param[5]: color (type: Color)
-Function 455: DrawCylinder() (6 input parameters)
+Function 457: DrawCylinder() (6 input parameters)
Name: DrawCylinder
Return type: void
Description: Draw a cylinder/cone
@@ -3884,7 +3895,7 @@ Function 455: DrawCylinder() (6 input parameters)
Param[4]: height (type: float)
Param[5]: slices (type: int)
Param[6]: color (type: Color)
-Function 456: DrawCylinderEx() (6 input parameters)
+Function 458: DrawCylinderEx() (6 input parameters)
Name: DrawCylinderEx
Return type: void
Description: Draw a cylinder with base at startPos and top at endPos
@@ -3894,7 +3905,7 @@ Function 456: DrawCylinderEx() (6 input parameters)
Param[4]: endRadius (type: float)
Param[5]: sides (type: int)
Param[6]: color (type: Color)
-Function 457: DrawCylinderWires() (6 input parameters)
+Function 459: DrawCylinderWires() (6 input parameters)
Name: DrawCylinderWires
Return type: void
Description: Draw a cylinder/cone wires
@@ -3904,7 +3915,7 @@ Function 457: DrawCylinderWires() (6 input parameters)
Param[4]: height (type: float)
Param[5]: slices (type: int)
Param[6]: color (type: Color)
-Function 458: DrawCylinderWiresEx() (6 input parameters)
+Function 460: DrawCylinderWiresEx() (6 input parameters)
Name: DrawCylinderWiresEx
Return type: void
Description: Draw a cylinder wires with base at startPos and top at endPos
@@ -3914,7 +3925,7 @@ Function 458: DrawCylinderWiresEx() (6 input parameters)
Param[4]: endRadius (type: float)
Param[5]: sides (type: int)
Param[6]: color (type: Color)
-Function 459: DrawCapsule() (6 input parameters)
+Function 461: DrawCapsule() (6 input parameters)
Name: DrawCapsule
Return type: void
Description: Draw a capsule with the center of its sphere caps at startPos and endPos
@@ -3924,7 +3935,7 @@ Function 459: DrawCapsule() (6 input parameters)
Param[4]: slices (type: int)
Param[5]: rings (type: int)
Param[6]: color (type: Color)
-Function 460: DrawCapsuleWires() (6 input parameters)
+Function 462: DrawCapsuleWires() (6 input parameters)
Name: DrawCapsuleWires
Return type: void
Description: Draw capsule wireframe with the center of its sphere caps at startPos and endPos
@@ -3934,51 +3945,51 @@ Function 460: DrawCapsuleWires() (6 input parameters)
Param[4]: slices (type: int)
Param[5]: rings (type: int)
Param[6]: color (type: Color)
-Function 461: DrawPlane() (3 input parameters)
+Function 463: DrawPlane() (3 input parameters)
Name: DrawPlane
Return type: void
Description: Draw a plane XZ
Param[1]: centerPos (type: Vector3)
Param[2]: size (type: Vector2)
Param[3]: color (type: Color)
-Function 462: DrawRay() (2 input parameters)
+Function 464: DrawRay() (2 input parameters)
Name: DrawRay
Return type: void
Description: Draw a ray line
Param[1]: ray (type: Ray)
Param[2]: color (type: Color)
-Function 463: DrawGrid() (2 input parameters)
+Function 465: DrawGrid() (2 input parameters)
Name: DrawGrid
Return type: void
Description: Draw a grid (centered at (0, 0, 0))
Param[1]: slices (type: int)
Param[2]: spacing (type: float)
-Function 464: LoadModel() (1 input parameters)
+Function 466: LoadModel() (1 input parameters)
Name: LoadModel
Return type: Model
Description: Load model from files (meshes and materials)
Param[1]: fileName (type: const char *)
-Function 465: LoadModelFromMesh() (1 input parameters)
+Function 467: LoadModelFromMesh() (1 input parameters)
Name: LoadModelFromMesh
Return type: Model
Description: Load model from generated mesh (default material)
Param[1]: mesh (type: Mesh)
-Function 466: IsModelValid() (1 input parameters)
+Function 468: IsModelValid() (1 input parameters)
Name: IsModelValid
Return type: bool
Description: Check if a model is valid (loaded in GPU, VAO/VBOs)
Param[1]: model (type: Model)
-Function 467: UnloadModel() (1 input parameters)
+Function 469: UnloadModel() (1 input parameters)
Name: UnloadModel
Return type: void
Description: Unload model (including meshes) from memory (RAM and/or VRAM)
Param[1]: model (type: Model)
-Function 468: GetModelBoundingBox() (1 input parameters)
+Function 470: GetModelBoundingBox() (1 input parameters)
Name: GetModelBoundingBox
Return type: BoundingBox
Description: Compute model bounding box limits (considers all meshes)
Param[1]: model (type: Model)
-Function 469: DrawModel() (4 input parameters)
+Function 471: DrawModel() (4 input parameters)
Name: DrawModel
Return type: void
Description: Draw a model (with texture if set)
@@ -3986,7 +3997,7 @@ Function 469: DrawModel() (4 input parameters)
Param[2]: position (type: Vector3)
Param[3]: scale (type: float)
Param[4]: tint (type: Color)
-Function 470: DrawModelEx() (6 input parameters)
+Function 472: DrawModelEx() (6 input parameters)
Name: DrawModelEx
Return type: void
Description: Draw a model with extended parameters
@@ -3996,7 +4007,7 @@ Function 470: DrawModelEx() (6 input parameters)
Param[4]: rotationAngle (type: float)
Param[5]: scale (type: Vector3)
Param[6]: tint (type: Color)
-Function 471: DrawModelWires() (4 input parameters)
+Function 473: DrawModelWires() (4 input parameters)
Name: DrawModelWires
Return type: void
Description: Draw a model wires (with texture if set)
@@ -4004,7 +4015,7 @@ Function 471: DrawModelWires() (4 input parameters)
Param[2]: position (type: Vector3)
Param[3]: scale (type: float)
Param[4]: tint (type: Color)
-Function 472: DrawModelWiresEx() (6 input parameters)
+Function 474: DrawModelWiresEx() (6 input parameters)
Name: DrawModelWiresEx
Return type: void
Description: Draw a model wires (with texture if set) with extended parameters
@@ -4014,7 +4025,7 @@ Function 472: DrawModelWiresEx() (6 input parameters)
Param[4]: rotationAngle (type: float)
Param[5]: scale (type: Vector3)
Param[6]: tint (type: Color)
-Function 473: DrawModelPoints() (4 input parameters)
+Function 475: DrawModelPoints() (4 input parameters)
Name: DrawModelPoints
Return type: void
Description: Draw a model as points
@@ -4022,7 +4033,7 @@ Function 473: DrawModelPoints() (4 input parameters)
Param[2]: position (type: Vector3)
Param[3]: scale (type: float)
Param[4]: tint (type: Color)
-Function 474: DrawModelPointsEx() (6 input parameters)
+Function 476: DrawModelPointsEx() (6 input parameters)
Name: DrawModelPointsEx
Return type: void
Description: Draw a model as points with extended parameters
@@ -4032,13 +4043,13 @@ Function 474: DrawModelPointsEx() (6 input parameters)
Param[4]: rotationAngle (type: float)
Param[5]: scale (type: Vector3)
Param[6]: tint (type: Color)
-Function 475: DrawBoundingBox() (2 input parameters)
+Function 477: DrawBoundingBox() (2 input parameters)
Name: DrawBoundingBox
Return type: void
Description: Draw bounding box (wires)
Param[1]: box (type: BoundingBox)
Param[2]: color (type: Color)
-Function 476: DrawBillboard() (5 input parameters)
+Function 478: DrawBillboard() (5 input parameters)
Name: DrawBillboard
Return type: void
Description: Draw a billboard texture
@@ -4047,7 +4058,7 @@ Function 476: DrawBillboard() (5 input parameters)
Param[3]: position (type: Vector3)
Param[4]: scale (type: float)
Param[5]: tint (type: Color)
-Function 477: DrawBillboardRec() (6 input parameters)
+Function 479: DrawBillboardRec() (6 input parameters)
Name: DrawBillboardRec
Return type: void
Description: Draw a billboard texture defined by source
@@ -4057,7 +4068,7 @@ Function 477: DrawBillboardRec() (6 input parameters)
Param[4]: position (type: Vector3)
Param[5]: size (type: Vector2)
Param[6]: tint (type: Color)
-Function 478: DrawBillboardPro() (9 input parameters)
+Function 480: DrawBillboardPro() (9 input parameters)
Name: DrawBillboardPro
Return type: void
Description: Draw a billboard texture defined by source and rotation
@@ -4070,13 +4081,13 @@ Function 478: DrawBillboardPro() (9 input parameters)
Param[7]: origin (type: Vector2)
Param[8]: rotation (type: float)
Param[9]: tint (type: Color)
-Function 479: UploadMesh() (2 input parameters)
+Function 481: UploadMesh() (2 input parameters)
Name: UploadMesh
Return type: void
Description: Upload mesh vertex data in GPU and provide VAO/VBO ids
Param[1]: mesh (type: Mesh *)
Param[2]: dynamic (type: bool)
-Function 480: UpdateMeshBuffer() (5 input parameters)
+Function 482: UpdateMeshBuffer() (5 input parameters)
Name: UpdateMeshBuffer
Return type: void
Description: Update mesh vertex data in GPU for a specific buffer index
@@ -4085,19 +4096,19 @@ Function 480: UpdateMeshBuffer() (5 input parameters)
Param[3]: data (type: const void *)
Param[4]: dataSize (type: int)
Param[5]: offset (type: int)
-Function 481: UnloadMesh() (1 input parameters)
+Function 483: UnloadMesh() (1 input parameters)
Name: UnloadMesh
Return type: void
Description: Unload mesh data from CPU and GPU
Param[1]: mesh (type: Mesh)
-Function 482: DrawMesh() (3 input parameters)
+Function 484: DrawMesh() (3 input parameters)
Name: DrawMesh
Return type: void
Description: Draw a 3d mesh with material and transform
Param[1]: mesh (type: Mesh)
Param[2]: material (type: Material)
Param[3]: transform (type: Matrix)
-Function 483: DrawMeshInstanced() (4 input parameters)
+Function 485: DrawMeshInstanced() (4 input parameters)
Name: DrawMeshInstanced
Return type: void
Description: Draw multiple mesh instances with material and different transforms
@@ -4105,35 +4116,35 @@ Function 483: DrawMeshInstanced() (4 input parameters)
Param[2]: material (type: Material)
Param[3]: transforms (type: const Matrix *)
Param[4]: instances (type: int)
-Function 484: GetMeshBoundingBox() (1 input parameters)
+Function 486: GetMeshBoundingBox() (1 input parameters)
Name: GetMeshBoundingBox
Return type: BoundingBox
Description: Compute mesh bounding box limits
Param[1]: mesh (type: Mesh)
-Function 485: GenMeshTangents() (1 input parameters)
+Function 487: GenMeshTangents() (1 input parameters)
Name: GenMeshTangents
Return type: void
Description: Compute mesh tangents
Param[1]: mesh (type: Mesh *)
-Function 486: ExportMesh() (2 input parameters)
+Function 488: ExportMesh() (2 input parameters)
Name: ExportMesh
Return type: bool
Description: Export mesh data to file, returns true on success
Param[1]: mesh (type: Mesh)
Param[2]: fileName (type: const char *)
-Function 487: ExportMeshAsCode() (2 input parameters)
+Function 489: ExportMeshAsCode() (2 input parameters)
Name: ExportMeshAsCode
Return type: bool
Description: Export mesh as code file (.h) defining multiple arrays of vertex attributes
Param[1]: mesh (type: Mesh)
Param[2]: fileName (type: const char *)
-Function 488: GenMeshPoly() (2 input parameters)
+Function 490: GenMeshPoly() (2 input parameters)
Name: GenMeshPoly
Return type: Mesh
Description: Generate polygonal mesh
Param[1]: sides (type: int)
Param[2]: radius (type: float)
-Function 489: GenMeshPlane() (4 input parameters)
+Function 491: GenMeshPlane() (4 input parameters)
Name: GenMeshPlane
Return type: Mesh
Description: Generate plane mesh (with subdivisions)
@@ -4141,42 +4152,42 @@ Function 489: GenMeshPlane() (4 input parameters)
Param[2]: length (type: float)
Param[3]: resX (type: int)
Param[4]: resZ (type: int)
-Function 490: GenMeshCube() (3 input parameters)
+Function 492: GenMeshCube() (3 input parameters)
Name: GenMeshCube
Return type: Mesh
Description: Generate cuboid mesh
Param[1]: width (type: float)
Param[2]: height (type: float)
Param[3]: length (type: float)
-Function 491: GenMeshSphere() (3 input parameters)
+Function 493: GenMeshSphere() (3 input parameters)
Name: GenMeshSphere
Return type: Mesh
Description: Generate sphere mesh (standard sphere)
Param[1]: radius (type: float)
Param[2]: rings (type: int)
Param[3]: slices (type: int)
-Function 492: GenMeshHemiSphere() (3 input parameters)
+Function 494: GenMeshHemiSphere() (3 input parameters)
Name: GenMeshHemiSphere
Return type: Mesh
Description: Generate half-sphere mesh (no bottom cap)
Param[1]: radius (type: float)
Param[2]: rings (type: int)
Param[3]: slices (type: int)
-Function 493: GenMeshCylinder() (3 input parameters)
+Function 495: GenMeshCylinder() (3 input parameters)
Name: GenMeshCylinder
Return type: Mesh
Description: Generate cylinder mesh
Param[1]: radius (type: float)
Param[2]: height (type: float)
Param[3]: slices (type: int)
-Function 494: GenMeshCone() (3 input parameters)
+Function 496: GenMeshCone() (3 input parameters)
Name: GenMeshCone
Return type: Mesh
Description: Generate cone/pyramid mesh
Param[1]: radius (type: float)
Param[2]: height (type: float)
Param[3]: slices (type: int)
-Function 495: GenMeshTorus() (4 input parameters)
+Function 497: GenMeshTorus() (4 input parameters)
Name: GenMeshTorus
Return type: Mesh
Description: Generate torus mesh
@@ -4184,7 +4195,7 @@ Function 495: GenMeshTorus() (4 input parameters)
Param[2]: size (type: float)
Param[3]: radSeg (type: int)
Param[4]: sides (type: int)
-Function 496: GenMeshKnot() (4 input parameters)
+Function 498: GenMeshKnot() (4 input parameters)
Name: GenMeshKnot
Return type: Mesh
Description: Generate trefoil knot mesh
@@ -4192,91 +4203,91 @@ Function 496: GenMeshKnot() (4 input parameters)
Param[2]: size (type: float)
Param[3]: radSeg (type: int)
Param[4]: sides (type: int)
-Function 497: GenMeshHeightmap() (2 input parameters)
+Function 499: GenMeshHeightmap() (2 input parameters)
Name: GenMeshHeightmap
Return type: Mesh
Description: Generate heightmap mesh from image data
Param[1]: heightmap (type: Image)
Param[2]: size (type: Vector3)
-Function 498: GenMeshCubicmap() (2 input parameters)
+Function 500: GenMeshCubicmap() (2 input parameters)
Name: GenMeshCubicmap
Return type: Mesh
Description: Generate cubes-based map mesh from image data
Param[1]: cubicmap (type: Image)
Param[2]: cubeSize (type: Vector3)
-Function 499: LoadMaterials() (2 input parameters)
+Function 501: LoadMaterials() (2 input parameters)
Name: LoadMaterials
Return type: Material *
Description: Load materials from model file
Param[1]: fileName (type: const char *)
Param[2]: materialCount (type: int *)
-Function 500: LoadMaterialDefault() (0 input parameters)
+Function 502: LoadMaterialDefault() (0 input parameters)
Name: LoadMaterialDefault
Return type: Material
Description: Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
No input parameters
-Function 501: IsMaterialValid() (1 input parameters)
+Function 503: IsMaterialValid() (1 input parameters)
Name: IsMaterialValid
Return type: bool
Description: Check if a material is valid (shader assigned, map textures loaded in GPU)
Param[1]: material (type: Material)
-Function 502: UnloadMaterial() (1 input parameters)
+Function 504: UnloadMaterial() (1 input parameters)
Name: UnloadMaterial
Return type: void
Description: Unload material from GPU memory (VRAM)
Param[1]: material (type: Material)
-Function 503: SetMaterialTexture() (3 input parameters)
+Function 505: SetMaterialTexture() (3 input parameters)
Name: SetMaterialTexture
Return type: void
Description: Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
Param[1]: material (type: Material *)
Param[2]: mapType (type: int)
Param[3]: texture (type: Texture2D)
-Function 504: SetModelMeshMaterial() (3 input parameters)
+Function 506: SetModelMeshMaterial() (3 input parameters)
Name: SetModelMeshMaterial
Return type: void
Description: Set material for a mesh
Param[1]: model (type: Model *)
Param[2]: meshId (type: int)
Param[3]: materialId (type: int)
-Function 505: LoadModelAnimations() (2 input parameters)
+Function 507: LoadModelAnimations() (2 input parameters)
Name: LoadModelAnimations
Return type: ModelAnimation *
Description: Load model animations from file
Param[1]: fileName (type: const char *)
Param[2]: animCount (type: int *)
-Function 506: UpdateModelAnimation() (3 input parameters)
+Function 508: UpdateModelAnimation() (3 input parameters)
Name: UpdateModelAnimation
Return type: void
Description: Update model animation pose (CPU)
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
Param[3]: frame (type: int)
-Function 507: UpdateModelAnimationBones() (3 input parameters)
+Function 509: UpdateModelAnimationBones() (3 input parameters)
Name: UpdateModelAnimationBones
Return type: void
Description: Update model animation mesh bone matrices (GPU skinning)
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
Param[3]: frame (type: int)
-Function 508: UnloadModelAnimation() (1 input parameters)
+Function 510: UnloadModelAnimation() (1 input parameters)
Name: UnloadModelAnimation
Return type: void
Description: Unload animation data
Param[1]: anim (type: ModelAnimation)
-Function 509: UnloadModelAnimations() (2 input parameters)
+Function 511: UnloadModelAnimations() (2 input parameters)
Name: UnloadModelAnimations
Return type: void
Description: Unload animation array data
Param[1]: animations (type: ModelAnimation *)
Param[2]: animCount (type: int)
-Function 510: IsModelAnimationValid() (2 input parameters)
+Function 512: IsModelAnimationValid() (2 input parameters)
Name: IsModelAnimationValid
Return type: bool
Description: Check model animation skeleton match
Param[1]: model (type: Model)
Param[2]: anim (type: ModelAnimation)
-Function 511: CheckCollisionSpheres() (4 input parameters)
+Function 513: CheckCollisionSpheres() (4 input parameters)
Name: CheckCollisionSpheres
Return type: bool
Description: Check collision between two spheres
@@ -4284,40 +4295,40 @@ Function 511: CheckCollisionSpheres() (4 input parameters)
Param[2]: radius1 (type: float)
Param[3]: center2 (type: Vector3)
Param[4]: radius2 (type: float)
-Function 512: CheckCollisionBoxes() (2 input parameters)
+Function 514: CheckCollisionBoxes() (2 input parameters)
Name: CheckCollisionBoxes
Return type: bool
Description: Check collision between two bounding boxes
Param[1]: box1 (type: BoundingBox)
Param[2]: box2 (type: BoundingBox)
-Function 513: CheckCollisionBoxSphere() (3 input parameters)
+Function 515: CheckCollisionBoxSphere() (3 input parameters)
Name: CheckCollisionBoxSphere
Return type: bool
Description: Check collision between box and sphere
Param[1]: box (type: BoundingBox)
Param[2]: center (type: Vector3)
Param[3]: radius (type: float)
-Function 514: GetRayCollisionSphere() (3 input parameters)
+Function 516: GetRayCollisionSphere() (3 input parameters)
Name: GetRayCollisionSphere
Return type: RayCollision
Description: Get collision info between ray and sphere
Param[1]: ray (type: Ray)
Param[2]: center (type: Vector3)
Param[3]: radius (type: float)
-Function 515: GetRayCollisionBox() (2 input parameters)
+Function 517: GetRayCollisionBox() (2 input parameters)
Name: GetRayCollisionBox
Return type: RayCollision
Description: Get collision info between ray and box
Param[1]: ray (type: Ray)
Param[2]: box (type: BoundingBox)
-Function 516: GetRayCollisionMesh() (3 input parameters)
+Function 518: GetRayCollisionMesh() (3 input parameters)
Name: GetRayCollisionMesh
Return type: RayCollision
Description: Get collision info between ray and mesh
Param[1]: ray (type: Ray)
Param[2]: mesh (type: Mesh)
Param[3]: transform (type: Matrix)
-Function 517: GetRayCollisionTriangle() (4 input parameters)
+Function 519: GetRayCollisionTriangle() (4 input parameters)
Name: GetRayCollisionTriangle
Return type: RayCollision
Description: Get collision info between ray and triangle
@@ -4325,7 +4336,7 @@ Function 517: GetRayCollisionTriangle() (4 input parameters)
Param[2]: p1 (type: Vector3)
Param[3]: p2 (type: Vector3)
Param[4]: p3 (type: Vector3)
-Function 518: GetRayCollisionQuad() (5 input parameters)
+Function 520: GetRayCollisionQuad() (5 input parameters)
Name: GetRayCollisionQuad
Return type: RayCollision
Description: Get collision info between ray and quad
@@ -4334,158 +4345,158 @@ Function 518: GetRayCollisionQuad() (5 input parameters)
Param[3]: p2 (type: Vector3)
Param[4]: p3 (type: Vector3)
Param[5]: p4 (type: Vector3)
-Function 519: InitAudioDevice() (0 input parameters)
+Function 521: InitAudioDevice() (0 input parameters)
Name: InitAudioDevice
Return type: void
Description: Initialize audio device and context
No input parameters
-Function 520: CloseAudioDevice() (0 input parameters)
+Function 522: CloseAudioDevice() (0 input parameters)
Name: CloseAudioDevice
Return type: void
Description: Close the audio device and context
No input parameters
-Function 521: IsAudioDeviceReady() (0 input parameters)
+Function 523: IsAudioDeviceReady() (0 input parameters)
Name: IsAudioDeviceReady
Return type: bool
Description: Check if audio device has been initialized successfully
No input parameters
-Function 522: SetMasterVolume() (1 input parameters)
+Function 524: SetMasterVolume() (1 input parameters)
Name: SetMasterVolume
Return type: void
Description: Set master volume (listener)
Param[1]: volume (type: float)
-Function 523: GetMasterVolume() (0 input parameters)
+Function 525: GetMasterVolume() (0 input parameters)
Name: GetMasterVolume
Return type: float
Description: Get master volume (listener)
No input parameters
-Function 524: LoadWave() (1 input parameters)
+Function 526: LoadWave() (1 input parameters)
Name: LoadWave
Return type: Wave
Description: Load wave data from file
Param[1]: fileName (type: const char *)
-Function 525: LoadWaveFromMemory() (3 input parameters)
+Function 527: LoadWaveFromMemory() (3 input parameters)
Name: LoadWaveFromMemory
Return type: Wave
Description: Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
Param[1]: fileType (type: const char *)
Param[2]: fileData (type: const unsigned char *)
Param[3]: dataSize (type: int)
-Function 526: IsWaveValid() (1 input parameters)
+Function 528: IsWaveValid() (1 input parameters)
Name: IsWaveValid
Return type: bool
Description: Checks if wave data is valid (data loaded and parameters)
Param[1]: wave (type: Wave)
-Function 527: LoadSound() (1 input parameters)
+Function 529: LoadSound() (1 input parameters)
Name: LoadSound
Return type: Sound
Description: Load sound from file
Param[1]: fileName (type: const char *)
-Function 528: LoadSoundFromWave() (1 input parameters)
+Function 530: LoadSoundFromWave() (1 input parameters)
Name: LoadSoundFromWave
Return type: Sound
Description: Load sound from wave data
Param[1]: wave (type: Wave)
-Function 529: LoadSoundAlias() (1 input parameters)
+Function 531: LoadSoundAlias() (1 input parameters)
Name: LoadSoundAlias
Return type: Sound
Description: Create a new sound that shares the same sample data as the source sound, does not own the sound data
Param[1]: source (type: Sound)
-Function 530: IsSoundValid() (1 input parameters)
+Function 532: IsSoundValid() (1 input parameters)
Name: IsSoundValid
Return type: bool
Description: Checks if a sound is valid (data loaded and buffers initialized)
Param[1]: sound (type: Sound)
-Function 531: UpdateSound() (3 input parameters)
+Function 533: UpdateSound() (3 input parameters)
Name: UpdateSound
Return type: void
Description: Update sound buffer with new data (data and frame count should fit in sound)
Param[1]: sound (type: Sound)
Param[2]: data (type: const void *)
Param[3]: sampleCount (type: int)
-Function 532: UnloadWave() (1 input parameters)
+Function 534: UnloadWave() (1 input parameters)
Name: UnloadWave
Return type: void
Description: Unload wave data
Param[1]: wave (type: Wave)
-Function 533: UnloadSound() (1 input parameters)
+Function 535: UnloadSound() (1 input parameters)
Name: UnloadSound
Return type: void
Description: Unload sound
Param[1]: sound (type: Sound)
-Function 534: UnloadSoundAlias() (1 input parameters)
+Function 536: UnloadSoundAlias() (1 input parameters)
Name: UnloadSoundAlias
Return type: void
Description: Unload a sound alias (does not deallocate sample data)
Param[1]: alias (type: Sound)
-Function 535: ExportWave() (2 input parameters)
+Function 537: ExportWave() (2 input parameters)
Name: ExportWave
Return type: bool
Description: Export wave data to file, returns true on success
Param[1]: wave (type: Wave)
Param[2]: fileName (type: const char *)
-Function 536: ExportWaveAsCode() (2 input parameters)
+Function 538: ExportWaveAsCode() (2 input parameters)
Name: ExportWaveAsCode
Return type: bool
Description: Export wave sample data to code (.h), returns true on success
Param[1]: wave (type: Wave)
Param[2]: fileName (type: const char *)
-Function 537: PlaySound() (1 input parameters)
+Function 539: PlaySound() (1 input parameters)
Name: PlaySound
Return type: void
Description: Play a sound
Param[1]: sound (type: Sound)
-Function 538: StopSound() (1 input parameters)
+Function 540: StopSound() (1 input parameters)
Name: StopSound
Return type: void
Description: Stop playing a sound
Param[1]: sound (type: Sound)
-Function 539: PauseSound() (1 input parameters)
+Function 541: PauseSound() (1 input parameters)
Name: PauseSound
Return type: void
Description: Pause a sound
Param[1]: sound (type: Sound)
-Function 540: ResumeSound() (1 input parameters)
+Function 542: ResumeSound() (1 input parameters)
Name: ResumeSound
Return type: void
Description: Resume a paused sound
Param[1]: sound (type: Sound)
-Function 541: IsSoundPlaying() (1 input parameters)
+Function 543: IsSoundPlaying() (1 input parameters)
Name: IsSoundPlaying
Return type: bool
Description: Check if a sound is currently playing
Param[1]: sound (type: Sound)
-Function 542: SetSoundVolume() (2 input parameters)
+Function 544: SetSoundVolume() (2 input parameters)
Name: SetSoundVolume
Return type: void
Description: Set volume for a sound (1.0 is max level)
Param[1]: sound (type: Sound)
Param[2]: volume (type: float)
-Function 543: SetSoundPitch() (2 input parameters)
+Function 545: SetSoundPitch() (2 input parameters)
Name: SetSoundPitch
Return type: void
Description: Set pitch for a sound (1.0 is base level)
Param[1]: sound (type: Sound)
Param[2]: pitch (type: float)
-Function 544: SetSoundPan() (2 input parameters)
+Function 546: SetSoundPan() (2 input parameters)
Name: SetSoundPan
Return type: void
Description: Set pan for a sound (0.5 is center)
Param[1]: sound (type: Sound)
Param[2]: pan (type: float)
-Function 545: WaveCopy() (1 input parameters)
+Function 547: WaveCopy() (1 input parameters)
Name: WaveCopy
Return type: Wave
Description: Copy a wave to a new wave
Param[1]: wave (type: Wave)
-Function 546: WaveCrop() (3 input parameters)
+Function 548: WaveCrop() (3 input parameters)
Name: WaveCrop
Return type: void
Description: Crop a wave to defined frames range
Param[1]: wave (type: Wave *)
Param[2]: initFrame (type: int)
Param[3]: finalFrame (type: int)
-Function 547: WaveFormat() (4 input parameters)
+Function 549: WaveFormat() (4 input parameters)
Name: WaveFormat
Return type: void
Description: Convert wave data to desired format
@@ -4493,203 +4504,203 @@ Function 547: WaveFormat() (4 input parameters)
Param[2]: sampleRate (type: int)
Param[3]: sampleSize (type: int)
Param[4]: channels (type: int)
-Function 548: LoadWaveSamples() (1 input parameters)
+Function 550: LoadWaveSamples() (1 input parameters)
Name: LoadWaveSamples
Return type: float *
Description: Load samples data from wave as a 32bit float data array
Param[1]: wave (type: Wave)
-Function 549: UnloadWaveSamples() (1 input parameters)
+Function 551: UnloadWaveSamples() (1 input parameters)
Name: UnloadWaveSamples
Return type: void
Description: Unload samples data loaded with LoadWaveSamples()
Param[1]: samples (type: float *)
-Function 550: LoadMusicStream() (1 input parameters)
+Function 552: LoadMusicStream() (1 input parameters)
Name: LoadMusicStream
Return type: Music
Description: Load music stream from file
Param[1]: fileName (type: const char *)
-Function 551: LoadMusicStreamFromMemory() (3 input parameters)
+Function 553: LoadMusicStreamFromMemory() (3 input parameters)
Name: LoadMusicStreamFromMemory
Return type: Music
Description: Load music stream from data
Param[1]: fileType (type: const char *)
Param[2]: data (type: const unsigned char *)
Param[3]: dataSize (type: int)
-Function 552: IsMusicValid() (1 input parameters)
+Function 554: IsMusicValid() (1 input parameters)
Name: IsMusicValid
Return type: bool
Description: Checks if a music stream is valid (context and buffers initialized)
Param[1]: music (type: Music)
-Function 553: UnloadMusicStream() (1 input parameters)
+Function 555: UnloadMusicStream() (1 input parameters)
Name: UnloadMusicStream
Return type: void
Description: Unload music stream
Param[1]: music (type: Music)
-Function 554: PlayMusicStream() (1 input parameters)
+Function 556: PlayMusicStream() (1 input parameters)
Name: PlayMusicStream
Return type: void
Description: Start music playing
Param[1]: music (type: Music)
-Function 555: IsMusicStreamPlaying() (1 input parameters)
+Function 557: IsMusicStreamPlaying() (1 input parameters)
Name: IsMusicStreamPlaying
Return type: bool
Description: Check if music is playing
Param[1]: music (type: Music)
-Function 556: UpdateMusicStream() (1 input parameters)
+Function 558: UpdateMusicStream() (1 input parameters)
Name: UpdateMusicStream
Return type: void
Description: Updates buffers for music streaming
Param[1]: music (type: Music)
-Function 557: StopMusicStream() (1 input parameters)
+Function 559: StopMusicStream() (1 input parameters)
Name: StopMusicStream
Return type: void
Description: Stop music playing
Param[1]: music (type: Music)
-Function 558: PauseMusicStream() (1 input parameters)
+Function 560: PauseMusicStream() (1 input parameters)
Name: PauseMusicStream
Return type: void
Description: Pause music playing
Param[1]: music (type: Music)
-Function 559: ResumeMusicStream() (1 input parameters)
+Function 561: ResumeMusicStream() (1 input parameters)
Name: ResumeMusicStream
Return type: void
Description: Resume playing paused music
Param[1]: music (type: Music)
-Function 560: SeekMusicStream() (2 input parameters)
+Function 562: SeekMusicStream() (2 input parameters)
Name: SeekMusicStream
Return type: void
Description: Seek music to a position (in seconds)
Param[1]: music (type: Music)
Param[2]: position (type: float)
-Function 561: SetMusicVolume() (2 input parameters)
+Function 563: SetMusicVolume() (2 input parameters)
Name: SetMusicVolume
Return type: void
Description: Set volume for music (1.0 is max level)
Param[1]: music (type: Music)
Param[2]: volume (type: float)
-Function 562: SetMusicPitch() (2 input parameters)
+Function 564: SetMusicPitch() (2 input parameters)
Name: SetMusicPitch
Return type: void
Description: Set pitch for a music (1.0 is base level)
Param[1]: music (type: Music)
Param[2]: pitch (type: float)
-Function 563: SetMusicPan() (2 input parameters)
+Function 565: SetMusicPan() (2 input parameters)
Name: SetMusicPan
Return type: void
Description: Set pan for a music (0.5 is center)
Param[1]: music (type: Music)
Param[2]: pan (type: float)
-Function 564: GetMusicTimeLength() (1 input parameters)
+Function 566: GetMusicTimeLength() (1 input parameters)
Name: GetMusicTimeLength
Return type: float
Description: Get music time length (in seconds)
Param[1]: music (type: Music)
-Function 565: GetMusicTimePlayed() (1 input parameters)
+Function 567: GetMusicTimePlayed() (1 input parameters)
Name: GetMusicTimePlayed
Return type: float
Description: Get current music time played (in seconds)
Param[1]: music (type: Music)
-Function 566: LoadAudioStream() (3 input parameters)
+Function 568: LoadAudioStream() (3 input parameters)
Name: LoadAudioStream
Return type: AudioStream
Description: Load audio stream (to stream raw audio pcm data)
Param[1]: sampleRate (type: unsigned int)
Param[2]: sampleSize (type: unsigned int)
Param[3]: channels (type: unsigned int)
-Function 567: IsAudioStreamValid() (1 input parameters)
+Function 569: IsAudioStreamValid() (1 input parameters)
Name: IsAudioStreamValid
Return type: bool
Description: Checks if an audio stream is valid (buffers initialized)
Param[1]: stream (type: AudioStream)
-Function 568: UnloadAudioStream() (1 input parameters)
+Function 570: UnloadAudioStream() (1 input parameters)
Name: UnloadAudioStream
Return type: void
Description: Unload audio stream and free memory
Param[1]: stream (type: AudioStream)
-Function 569: UpdateAudioStream() (3 input parameters)
+Function 571: UpdateAudioStream() (3 input parameters)
Name: UpdateAudioStream
Return type: void
Description: Update audio stream buffers with data
Param[1]: stream (type: AudioStream)
Param[2]: data (type: const void *)
Param[3]: frameCount (type: int)
-Function 570: IsAudioStreamProcessed() (1 input parameters)
+Function 572: IsAudioStreamProcessed() (1 input parameters)
Name: IsAudioStreamProcessed
Return type: bool
Description: Check if any audio stream buffers requires refill
Param[1]: stream (type: AudioStream)
-Function 571: PlayAudioStream() (1 input parameters)
+Function 573: PlayAudioStream() (1 input parameters)
Name: PlayAudioStream
Return type: void
Description: Play audio stream
Param[1]: stream (type: AudioStream)
-Function 572: PauseAudioStream() (1 input parameters)
+Function 574: PauseAudioStream() (1 input parameters)
Name: PauseAudioStream
Return type: void
Description: Pause audio stream
Param[1]: stream (type: AudioStream)
-Function 573: ResumeAudioStream() (1 input parameters)
+Function 575: ResumeAudioStream() (1 input parameters)
Name: ResumeAudioStream
Return type: void
Description: Resume audio stream
Param[1]: stream (type: AudioStream)
-Function 574: IsAudioStreamPlaying() (1 input parameters)
+Function 576: IsAudioStreamPlaying() (1 input parameters)
Name: IsAudioStreamPlaying
Return type: bool
Description: Check if audio stream is playing
Param[1]: stream (type: AudioStream)
-Function 575: StopAudioStream() (1 input parameters)
+Function 577: StopAudioStream() (1 input parameters)
Name: StopAudioStream
Return type: void
Description: Stop audio stream
Param[1]: stream (type: AudioStream)
-Function 576: SetAudioStreamVolume() (2 input parameters)
+Function 578: SetAudioStreamVolume() (2 input parameters)
Name: SetAudioStreamVolume
Return type: void
Description: Set volume for audio stream (1.0 is max level)
Param[1]: stream (type: AudioStream)
Param[2]: volume (type: float)
-Function 577: SetAudioStreamPitch() (2 input parameters)
+Function 579: SetAudioStreamPitch() (2 input parameters)
Name: SetAudioStreamPitch
Return type: void
Description: Set pitch for audio stream (1.0 is base level)
Param[1]: stream (type: AudioStream)
Param[2]: pitch (type: float)
-Function 578: SetAudioStreamPan() (2 input parameters)
+Function 580: SetAudioStreamPan() (2 input parameters)
Name: SetAudioStreamPan
Return type: void
Description: Set pan for audio stream (0.5 is centered)
Param[1]: stream (type: AudioStream)
Param[2]: pan (type: float)
-Function 579: SetAudioStreamBufferSizeDefault() (1 input parameters)
+Function 581: SetAudioStreamBufferSizeDefault() (1 input parameters)
Name: SetAudioStreamBufferSizeDefault
Return type: void
Description: Default size for new audio streams
Param[1]: size (type: int)
-Function 580: SetAudioStreamCallback() (2 input parameters)
+Function 582: SetAudioStreamCallback() (2 input parameters)
Name: SetAudioStreamCallback
Return type: void
Description: Audio thread callback to request new data
Param[1]: stream (type: AudioStream)
Param[2]: callback (type: AudioCallback)
-Function 581: AttachAudioStreamProcessor() (2 input parameters)
+Function 583: AttachAudioStreamProcessor() (2 input parameters)
Name: AttachAudioStreamProcessor
Return type: void
Description: Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo)
Param[1]: stream (type: AudioStream)
Param[2]: processor (type: AudioCallback)
-Function 582: DetachAudioStreamProcessor() (2 input parameters)
+Function 584: DetachAudioStreamProcessor() (2 input parameters)
Name: DetachAudioStreamProcessor
Return type: void
Description: Detach audio stream processor from stream
Param[1]: stream (type: AudioStream)
Param[2]: processor (type: AudioCallback)
-Function 583: AttachAudioMixedProcessor() (1 input parameters)
+Function 585: AttachAudioMixedProcessor() (1 input parameters)
Name: AttachAudioMixedProcessor
Return type: void
Description: Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo)
Param[1]: processor (type: AudioCallback)
-Function 584: DetachAudioMixedProcessor() (1 input parameters)
+Function 586: DetachAudioMixedProcessor() (1 input parameters)
Name: DetachAudioMixedProcessor
Return type: void
Description: Detach audio stream processor from the entire audio pipeline
diff --git a/tools/parser/output/raylib_api.xml b/tools/parser/output/raylib_api.xml
index d99187adf..fb409158f 100644
--- a/tools/parser/output/raylib_api.xml
+++ b/tools/parser/output/raylib_api.xml
@@ -679,7 +679,7 @@
-
+
@@ -1054,7 +1054,7 @@
-
+
@@ -2435,6 +2435,13 @@
+
+
+
+
+
+
+
diff --git a/tools/rexm/Makefile b/tools/rexm/Makefile
index 4ac96a1ab..f5e7d1fe4 100644
--- a/tools/rexm/Makefile
+++ b/tools/rexm/Makefile
@@ -35,7 +35,7 @@ PROJECT_BUILD_PATH ?= .
PROJECT_SOURCE_FILES ?= rexm.c
# raylib library variables
-RAYLIB_SRC_PATH ?= C:\raylib\raylib\src
+RAYLIB_SRC_PATH ?= ..\..\src
RAYLIB_INCLUDE_PATH ?= $(RAYLIB_SRC_PATH)
RAYLIB_LIB_PATH ?= $(RAYLIB_SRC_PATH)
@@ -205,7 +205,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
LDFLAGS += $(PROJECT_NAME).rc.data
# -Wl,--subsystem,windows hides the console window
ifeq ($(BUILD_MODE), RELEASE)
- LDFLAGS += -Wl,--subsystem,windows
+ #LDFLAGS += -Wl,--subsystem,windows
endif
endif
ifeq ($(PLATFORM_OS),BSD)
@@ -264,9 +264,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
# Libraries for Windows desktop compilation
# NOTE: WinMM library required to set high-res timer resolution
- LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm -lcomdlg32 -lole32
+ LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm
# Required for physac examples
- LDLIBS += -static -lpthread
+ #LDLIBS += -static -lpthread
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
diff --git a/tools/rexm/VS2022/raylib/raylib.vcxproj b/tools/rexm/VS2022/raylib/raylib.vcxproj
new file mode 100644
index 000000000..df2831b33
--- /dev/null
+++ b/tools/rexm/VS2022/raylib/raylib.vcxproj
@@ -0,0 +1,340 @@
+
+
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}
+ Win32Proj
+ raylib
+ 10.0
+ $(ProjectDir)..\..\..\..\src
+
+
+
+ StaticLibrary
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ StaticLibrary
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ DynamicLibrary
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ DynamicLibrary
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ StaticLibrary
+ false
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ StaticLibrary
+ false
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ DynamicLibrary
+ false
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ DynamicLibrary
+ false
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+
+
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP
+ CompileAsC
+ $(RaylibSrcPath)\external\glfw\include
+
+
+ Windows
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP
+ CompileAsC
+ $(RaylibSrcPath)\external\glfw\include
+
+
+ Windows
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED
+ CompileAsC
+ $(RaylibSrcPath)\external\glfw\include
+ MultiThreadedDebug
+
+
+ Windows
+ kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED
+ CompileAsC
+ $(RaylibSrcPath)\external\glfw\include
+ MultiThreadedDebug
+
+
+ Windows
+ kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ %(AdditionalLibraryDirectories)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP
+ $(RaylibSrcPath)\external\glfw\include
+ CompileAsC
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP
+ $(RaylibSrcPath)\external\glfw\include
+ CompileAsC
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED
+ $(RaylibSrcPath)\external\glfw\include
+ CompileAsC
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP;BUILD_LIBTYPE_SHARED
+ $(RaylibSrcPath)\external\glfw\include
+ CompileAsC
+ MultiThreaded
+
+
+
+ Windows
+ true
+ true
+ kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tools/rexm/VS2022/rexm.sln b/tools/rexm/VS2022/rexm.sln
new file mode 100644
index 000000000..5939d2b47
--- /dev/null
+++ b/tools/rexm/VS2022/rexm.sln
@@ -0,0 +1,61 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31912.275
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rexm", "rexm\rexm.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib", "raylib\raylib.vcxproj", "{E89D61AC-55DE-4482-AFD4-DF7242EBC859}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug.DLL|x64 = Debug.DLL|x64
+ Debug.DLL|x86 = Debug.DLL|x86
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release.DLL|x64 = Release.DLL|x64
+ Release.DLL|x86 = Release.DLL|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x64.ActiveCfg = Debug|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x64.Build.0 = Debug|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.ActiveCfg = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Debug|x86.Build.0 = Debug|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x64.ActiveCfg = Release|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x64.Build.0 = Release|x64
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.ActiveCfg = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.Build.0 = Release|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.ActiveCfg = Debug|x64
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x64.Build.0 = Debug|x64
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.ActiveCfg = Debug|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Debug|x86.Build.0 = Debug|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x64.Build.0 = Release.DLL|x64
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release.DLL|x86.Build.0 = Release.DLL|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.ActiveCfg = Release|x64
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x64.Build.0 = Release|x64
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.ActiveCfg = Release|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
+ EndGlobalSection
+EndGlobal
diff --git a/tools/rexm/VS2022/rexm/rexm.vcxproj b/tools/rexm/VS2022/rexm/rexm.vcxproj
new file mode 100644
index 000000000..42c353436
--- /dev/null
+++ b/tools/rexm/VS2022/rexm/rexm.vcxproj
@@ -0,0 +1,366 @@
+
+
+
+
+ Debug.DLL
+ Win32
+
+
+ Debug.DLL
+ x64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release.DLL
+ Win32
+
+
+ Release.DLL
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}
+ Win32Proj
+ rexm
+ rexm
+ 10.0
+ $(ProjectDir)..\..\..\..\src
+
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ true
+ $(DefaultPlatformToolset)
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+ Application
+ false
+ $(DefaultPlatformToolset)
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ true
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\
+ $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\..\src;$(SolutionDir)..\..\..\src\external;$(RaylibSrcPath);%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\..\src;$(SolutionDir)..\..\..\src\external;$(RaylibSrcPath);%(AdditionalIncludeDirectories)
+ /FS %(AdditionalOptions)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\..\src;$(SolutionDir)..\..\..\src\external;$(RaylibSrcPath);%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+
+
+ Level3
+ Disabled
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ CompileAsC
+ $(SolutionDir)..\..\..\src;$(SolutionDir)..\..\..\src\external;$(RaylibSrcPath);%(AdditionalIncludeDirectories)
+
+
+ Console
+ true
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+ Copy Debug DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ $(SolutionDir)..\..\..\src;$(SolutionDir)..\..\..\src\external;$(RaylibSrcPath);%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ $(SolutionDir)..\..\..\src;$(SolutionDir)..\..\..\src\external;$(RaylibSrcPath);%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ $(SolutionDir)..\..\..\src;$(SolutionDir)..\..\..\src\external;$(RaylibSrcPath);%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)
+ $(SolutionDir)..\..\..\src;$(SolutionDir)..\..\..\src\external;$(RaylibSrcPath);%(AdditionalIncludeDirectories)
+ CompileAsC
+ true
+
+
+ Console
+ true
+ true
+ true
+ raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+ $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\
+
+
+ xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"
+
+
+ Copy Release DLL to output directory
+
+
+
+
+ {e89d61ac-55de-4482-afd4-df7242ebc859}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tools/rexm/examples_report.md b/tools/rexm/examples_report.md
index 6fa79bd50..1c08d9270 100644
--- a/tools/rexm/examples_report.md
+++ b/tools/rexm/examples_report.md
@@ -16,166 +16,169 @@ Example elements validated:
- [RDME] : Not listed in README.md
- [JS] : Not listed in Web (examples.js)
- [WOUT] : Missing Web build (.html/.data/.wasm/.js)
+ - [WMETA] : Missing Web .html example metadata
```
-| **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|
-|:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|
-| core_basic_window | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_input_keys | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_input_mouse | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_input_mouse_wheel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_input_gamepad | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_input_multitouch | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_input_gestures | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_input_virtual_controls | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_2d_camera | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_2d_camera_mouse_zoom | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_2d_camera_platformer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_2d_camera_split_screen | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_3d_camera_mode | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_3d_camera_free | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_3d_camera_first_person | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_3d_camera_split_screen | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_3d_picking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_world_screen | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_custom_logging | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_window_flags | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_window_letterbox | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_window_should_close | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_drop_files | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_random_values | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_storage_values | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_vr_simulator | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_loading_thread | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_scissor_test | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_basic_screen_manager | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_custom_frame_control | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_smooth_pixelperfect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_random_sequence | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_basic_window_web | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ❌ |
-| core_input_gestures_web | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ |
-| core_automation_events | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| core_high_dpi | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
-| shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_colors_palette | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_logo_raylib_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_rectangle_scaling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_lines_bezier | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_collision_area | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_following_eyes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_easings_ball_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_easings_box_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_easings_rectangle_array | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_draw_ring | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_draw_circle_sector | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_draw_rectangle_rounded | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_top_down_lights | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_rectangle_advanced | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_splines_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shapes_digital_clock | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
-| shapes_double_pendulum | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
-| textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_image_generation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_image_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_image_processing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_image_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_to_image | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_raw_data | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_particles_blending | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_npatch_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_background_scrolling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_sprite_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_sprite_button | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_sprite_explosion | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_bunnymark | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_mouse_painting | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
-| textures_blend_modes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_draw_tiled | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_polygon | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_fog_of_war | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_gif_player | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_image_kernel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_image_channel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_image_rotate | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| textures_textured_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_raylib_fonts | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_font_spritefont | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_font_filters | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_font_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_font_sdf | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_format_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_input_box | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_writing_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_rectangle_bounds | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_unicode | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_draw_3d | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| text_codepoints_loading | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_animation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_billboard | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_box_collisions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_cubicmap | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_first_person_maze | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_geometric_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_mesh_generation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_mesh_picking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_loading_gltf | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_loading_vox | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_loading_m3d | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_orthographic_projection | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_point_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_rlgl_solar_system | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_yaw_pitch_roll | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_waving_cubes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_heightmap | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_skybox | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_draw_cube_texture | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_gpu_skinning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_bone_socket | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| models_tesseract_view | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_basic_lighting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_model_shader | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_shapes_textures | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_custom_uniform | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_postprocessing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_palette_switch | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_raymarching | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_texture_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_texture_outline | ✔ | ✔ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_texture_waves | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_julia_set | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_eratosthenes | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_fog | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_simple_mask | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_hot_reloading | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_mesh_instancing | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_multi_sample2d | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_normalmap | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ❌ | ❌ | ❌ | ❌ |
-| shaders_spotlight | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_deferred_render | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_hybrid_render | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_texture_tiling | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_shadowmap | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_vertex_displacement | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_write_depth | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_basic_pbr | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_lightmap | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| shaders_rounded_rectangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
-| shaders_view_depth | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
-| audio_module_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| audio_music_stream | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| audio_raw_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| audio_sound_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| audio_mixed_processor | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| audio_stream_effects | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| audio_sound_multi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| audio_sound_positioning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
-| rlgl_standalone | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ❌ |
-| rlgl_compute_shader | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ❌ |
-| easings_testbed | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ❌ |
-| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ❌ | ✔ | ❌ | ❌ |
-| embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ❌ |
-| raymath_vector_angle | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ❌ | ✔ | ❌ | ❌ |
+| **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]|
+|:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:|
+| core_basic_window | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_input_keys | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_input_mouse | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_input_mouse_wheel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_input_gamepad | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_input_multitouch | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_input_gestures | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_input_virtual_controls | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_2d_camera | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_2d_camera_mouse_zoom | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_2d_camera_platformer | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_2d_camera_split_screen | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_3d_camera_mode | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_3d_camera_free | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_3d_camera_first_person | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_3d_camera_split_screen | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_3d_fps_controller | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_3d_picking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_world_screen | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_custom_logging | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_window_flags | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_window_letterbox | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_window_should_close | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_drop_files | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_random_values | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_storage_values | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_vr_simulator | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_loading_thread | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_scissor_test | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_basic_screen_manager | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_custom_frame_control | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_smooth_pixelperfect | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_random_sequence | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_basic_window_web | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ❌ | ✔ |
+| core_input_gestures_web | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
+| core_automation_events | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_high_dpi | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_basic_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_bouncing_ball | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_colors_palette | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_logo_raylib_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_rectangle_scaling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_lines_bezier | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_collision_area | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_following_eyes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_easings_ball_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_easings_box_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_easings_rectangle_array | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_draw_ring | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_draw_circle_sector | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_draw_rectangle_rounded | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_top_down_lights | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_rectangle_advanced | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_splines_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_digital_clock | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_double_pendulum | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_logo_raylib | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_srcrec_dstrec | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_image_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_image_generation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_image_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_image_processing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_image_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_to_image | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_raw_data | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_particles_blending | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_npatch_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_background_scrolling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_sprite_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_sprite_button | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_sprite_explosion | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_bunnymark | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_mouse_painting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_blend_modes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_draw_tiled | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_polygon | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_fog_of_war | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_gif_player | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_image_kernel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_image_channel | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_image_rotate | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| textures_textured_curve | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_raylib_fonts | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_font_spritefont | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_font_filters | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_font_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_font_sdf | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_format_text | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_input_box | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_writing_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_rectangle_bounds | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_unicode | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_draw_3d | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_codepoints_loading | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_animation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_billboard | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_box_collisions | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_cubicmap | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_first_person_maze | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_geometric_shapes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_mesh_generation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_mesh_picking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_loading_gltf | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_loading_vox | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_loading_m3d | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_orthographic_projection | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_point_rendering | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_rlgl_solar_system | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_yaw_pitch_roll | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_waving_cubes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_heightmap | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_skybox | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_draw_cube_texture | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_gpu_skinning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_bone_socket | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_tesseract_view | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_basic_lighting | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_model_shader | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_shapes_textures | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_custom_uniform | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_postprocessing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_palette_switch | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_raymarching | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_texture_drawing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_texture_outline | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_texture_waves | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_julia_set | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_eratosthenes | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_fog | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_simple_mask | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_hot_reloading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_mesh_instancing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_multi_sample2d | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_normal_map | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_spotlight | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_deferred_render | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_hybrid_render | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_texture_tiling | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_shadowmap | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_vertex_displacement | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_write_depth | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_basic_pbr | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_lightmap | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_rounded_rectangle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_view_depth | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_module_playing | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_music_stream | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_raw_stream | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_sound_loading | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_mixed_processor | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_stream_effects | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_sound_multi | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_sound_positioning | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| rlgl_standalone | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| rlgl_compute_shader | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| easings_testbed | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
+| embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| raymath_vector_angle | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
+| text_unicode_ranges | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
diff --git a/tools/rexm/examples_report_issues.md b/tools/rexm/examples_report_issues.md
new file mode 100644
index 000000000..12e8c656e
--- /dev/null
+++ b/tools/rexm/examples_report_issues.md
@@ -0,0 +1,40 @@
+# EXAMPLES COLLECTION - VALIDATION REPORT
+
+```
+Example elements validated:
+
+ - [C] : Missing .c source file
+ - [CAT] : Not a recognized category
+ - [INFO] : Inconsistent example header info (stars, author...)
+ - [PNG] : Missing screenshot .png
+ - [WPNG] : Invalid png screenshot (using default one)
+ - [RES] : Missing resources listed in the code
+ - [MK] : Not listed in Makefile
+ - [MKWEB] : Not listed in Makefile.Web
+ - [VCX] : Missing Visual Studio project file
+ - [SOL] : Project not included in solution file
+ - [RDME] : Not listed in README.md
+ - [JS] : Not listed in Web (examples.js)
+ - [WOUT] : Missing Web build (.html/.data/.wasm/.js)
+ - [WMETA] : Missing Web .html example metadata
+```
+| **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]|
+|:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:|
+| core_input_virtual_controls | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| core_basic_window_web | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ❌ | ✔ |
+| core_input_gestures_web | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
+| core_high_dpi | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shapes_digital_clock | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_font_sdf | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_draw_3d | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| text_codepoints_loading | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| models_loading_m3d | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| shaders_texture_outline | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| audio_music_stream | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| rlgl_standalone | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| rlgl_compute_shader | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| easings_testbed | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
+| embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| raymath_vector_angle | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
+| text_unicode_ranges | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c
index 7cdd6175e..9ab4950c8 100644
--- a/tools/rexm/rexm.c
+++ b/tools/rexm/rexm.c
@@ -7,6 +7,7 @@
* - add
* - rename
* - remove
+* - build
* - validate
* - update
*
@@ -78,8 +79,10 @@ typedef struct {
float verUpdated; // Example raylib last update version
char author[64]; // Example author
char authorGitHub[64]; // Example author, GitHub user name
- int resCount; // Example resources counter
+
int status; // Example validation status info
+ int resCount; // Example resources counter
+ char **resPaths; // Example resources paths (MAX: 256)
} rlExampleInfo;
// Validation status for a single example
@@ -97,8 +100,9 @@ typedef enum {
VALID_NOT_IN_JS = 1 << 9, // Not listed in examples.js
VALID_INCONSISTENT_INFO = 1 << 10, // Inconsistent info between collection and example header (stars, author...)
VALID_MISSING_WEB_OUTPUT = 1 << 11, // Missing .html/.data/.wasm/.js
- VALID_INVALID_CATEGORY = 1 << 12, // Not a recognized category
- VALID_UNKNOWN_ERROR = 1 << 13 // Unknown failure case (fallback)
+ VALID_MISSING_WEB_METADATA = 1 << 12, // Missing .html example metadata
+ VALID_INVALID_CATEGORY = 1 << 13, // Not a recognized category
+ VALID_UNKNOWN_ERROR = 1 << 14 // Unknown failure case (fallback)
} rlExampleValidationStatus;
// Example management operations
@@ -110,6 +114,7 @@ typedef enum {
OP_REMOVE = 4, // Remove existing example
OP_VALIDATE = 5, // Validate examples, using [examples_list.txt] as main source by default
OP_UPDATE = 6, // Validate and update required examples (as far as possible)
+ OP_BUILD = 7, // Build example for desktop and web, copy web output
} rlExampleOperation;
static const char *exCategories[REXM_MAX_EXAMPLE_CATEGORIES] = { "core", "shapes", "textures", "text", "models", "shaders", "audio", "others" };
@@ -121,6 +126,7 @@ static const char *exWebPath = NULL; // Env: REXM_EXAMPLES_WEB_PATH
static const char *exTemplateFilePath = NULL; // Env: REXM_EXAMPLES_TEMPLATE_FILE_PATH
static const char *exTemplateScreenshot = NULL; // Env: REXM_EXAMPLES_TEMPLATE_SCREENSHOT_PATH
static const char *exCollectionFilePath = NULL; // Env: REXM_EXAMPLES_COLLECTION_FILE_PATH
+static const char *exVSProjectSolutionFile = NULL; // Env REXM_EXAMPLES_VS2022_SLN_FILE
//----------------------------------------------------------------------------------
// Module specific functions declaration
@@ -142,11 +148,6 @@ static int UpdateRequiredFiles(void);
static rlExampleInfo *LoadExamplesData(const char *fileName, const char *category, bool sort, int *exCount);
static void UnloadExamplesData(rlExampleInfo *exInfo);
-// Get text lines (by line-breaks '\n')
-// WARNING: It does not copy text data, just returns line pointers
-static char **LoadTextLines(const char *text, int *count);
-static void UnloadTextLines(char **text);
-
// Load example info from file header
static rlExampleInfo *LoadExampleInfo(const char *exFileName);
static void UnloadExampleInfo(rlExampleInfo *exInfo);
@@ -165,8 +166,15 @@ static char **ScanExampleResources(const char *filePath, int *resPathCount);
// Clear resource paths scanned
static void ClearExampleResources(char **resPaths);
-// Add VS project (.vcxproj) to existing VS solution (.sol)
-static int AddVSProjectToSolution(const char *projFile, const char *solFile);
+// Add VS project (.vcxproj) to existing VS solution (.sln)
+static int AddVSProjectToSolution(const char *projFile, const char *slnFile, const char *category);
+
+// Generate unique UUID v4 string
+// Output format: {9A2F48CC-0DA8-47C0-884E-02E37F9BE6C1}
+static const char *GenerateUUIDv4(void);
+
+// Update generated Web example .html file metadata
+static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath);
//------------------------------------------------------------------------------------
// Program main entry point
@@ -179,12 +187,14 @@ int main(int argc, char *argv[])
exTemplateFilePath = getenv("REXM_EXAMPLES_TEMPLATE_FILE_PATH");
exTemplateScreenshot = getenv("REXM_EXAMPLES_TEMPLATE_SCREENSHOT_PATH");
exCollectionFilePath = getenv("REXM_EXAMPLES_COLLECTION_FILE_PATH");
+ exVSProjectSolutionFile = getenv("REXM_EXAMPLES_VS2022_SLN_FILE");
if (!exBasePath) exBasePath = "C:/GitHub/raylib/examples";
if (!exWebPath) exWebPath = "C:/GitHub/raylib.com/examples";
if (!exTemplateFilePath) exTemplateFilePath = "C:/GitHub/raylib/examples/examples_template.c";
if (!exTemplateScreenshot) exTemplateScreenshot = "C:/GitHub/raylib/examples/examples_template.png";
if (!exCollectionFilePath) exCollectionFilePath = "C:/GitHub/raylib/examples/examples_list.txt";
+ if (!exVSProjectSolutionFile) exVSProjectSolutionFile = "C:/GitHub/raylib/projects/VS2022/raylib.sln";
char inFileName[1024] = { 0 }; // Example input filename (to be added)
@@ -347,6 +357,31 @@ int main(int argc, char *argv[])
opCode = OP_UPDATE;
}
+ else if (strcmp(argv[1], "build") == 0)
+ {
+ // Build example for PLATFORM_DESKTOP and PLATFORM_WEB
+ // NOTE: Build outputs to default directory, usually where the .c file is located,
+ // to avoid issues with copying resources (at least on Desktop)
+ // Web build files (.html, .wasm, .js, .data) are copied to raylib.com/examples repo
+ // Check for valid upcoming argument
+ if (argc == 2) LOG("WARNING: No example name provided to build\n");
+ else if (argc > 3) LOG("WARNING: Too many arguments provided\n");
+ else
+ {
+ // Verify example exists in collection to be removed
+ char *exColInfo = LoadFileText(exCollectionFilePath);
+ if ((TextFindIndex(exColInfo, argv[2]) != -1) && // Example in the collection
+ (TextFindIndex(exName, "_") != -1)) // Valid example name
+ {
+
+ strcpy(exName, argv[2]); // Register example name for removal
+ strncpy(exCategory, exName, TextFindIndex(exName, "_"));
+ opCode = OP_BUILD;
+ }
+ else LOG("WARNING: REMOVE: Example not available in the collection\n");
+ UnloadFileText(exColInfo);
+ }
+ }
}
switch (opCode)
@@ -447,7 +482,7 @@ int main(int argc, char *argv[])
char *exCollectionList = LoadFileText(exCollectionFilePath);
if (TextFindIndex(exCollectionList, exName) == -1) // Example not found
{
- char *exCollectionListUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated list copy, 2MB
+ char *exCollectionListUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated list copy, 2MB
// Add example to the main list, by category
// by default add it last in the category list
@@ -518,8 +553,10 @@ int main(int argc, char *argv[])
"..\\..\\examples\\core", TextFormat("..\\..\\examples\\%s", exCategory));
// Edit: raylib/projects/VS2022/raylib.sln --> Add new example project
+ // WARNING: This function uses TextFormat() extensively inside,
+ // we must store provided file paths because pointers will be overwriten
AddVSProjectToSolution(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName),
- TextFormat("%s/../projects/VS2022/raylib.sln", exBasePath));
+ exVSProjectSolutionFile, exCategory);
//------------------------------------------------------------------------------------------------
// Recompile example (on raylib side)
@@ -529,25 +566,19 @@ int main(int argc, char *argv[])
// Compile to: raylib.com/examples//_example_name.wasm
// Compile to: raylib.com/examples//_example_name.js
//------------------------------------------------------------------------------------------------
- // TODO: Avoid platform-specific .BAT file
- /*
- SET RAYLIB_PATH=C:\GitHub\raylib
- SET COMPILER_PATH=C:\raylib\w64devkit\bin
- ENV_SET PATH=$(COMPILER_PATH)
- SET MAKE=mingw32-make
- $(MAKE) -f Makefile.Web shaders/shaders_deferred_render PLATFORM=$(PLATFORM) -B
-
- //int putenv(char *string); // putenv takes a string of the form NAME=VALUE
- //int setenv(const char *envname, const char *envval, int overwrite);
- //int unsetenv(const char *name); //unset variable
- putenv("RAYLIB_DIR=C:\\GitHub\\raylib");
+ // WARNING 1: EMSDK_PATH must be set to proper location when calling from GitHub Actions
+ // WARNING 2: raylib.a and raylib.web.a must be available when compiling locally
+#if defined(_WIN32)
+ //putenv("RAYLIB_DIR=C:\\GitHub\\raylib");
putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
- setenv("RAYLIB_DIR", "C:\\GitHub\\raylib", 1);
- unsetenv("RAYLIB_DIR");
- getenv("RAYLIB_DIR");
- system(TextFormat("make -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exCategory, exName));
- */
- system(TextFormat("%s/build_example_web.bat %s/%s", exBasePath, exCategory, exName));
+ system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
+#else
+ system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
+#endif
+ // Update generated .html metadata
+ char exHtmlPath[512] = { 0 };
+ strcpy(exHtmlPath, TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName)); // WARNING: Cache path for saving
+ UpdateWebMetadata(exHtmlPath, TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
// Copy results to web side
FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName),
@@ -572,9 +603,9 @@ int main(int argc, char *argv[])
TextFormat("%s;%s", exRecategory, exRename));
// Edit: Rename example code and screenshot files .c and .png
- rename(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName),
+ FileRename(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName),
TextFormat("%s/%s/%s.c", exBasePath, exCategory, exRename));
- rename(TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName),
+ FileRename(TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName),
TextFormat("%s/%s/%s.png", exBasePath, exCategory, exRename));
// NOTE: Example resource files do not need to be changed...
@@ -584,10 +615,12 @@ int main(int argc, char *argv[])
FileTextReplace(TextFormat("%s/Makefile", exBasePath), exName, exRename);
FileTextReplace(TextFormat("%s/Makefile.Web", exBasePath), exName, exRename);
FileTextReplace(TextFormat("%s/README.md", exBasePath), exName, exRename);
- FileTextReplace(TextFormat("%s/../common/examples.js", exWebPath), exName, exRename);
+ FileTextReplace(TextFormat("%s/../common/examples.js", exWebPath),
+ exName + strlen(exCategory) + 1, exRename + strlen(exRecategory) + 1); // Skip category
// Edit: Rename example project and solution
- rename(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName),
+ FileTextReplace(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName), exName, exRename);
+ FileRename(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName),
TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exRename));
FileTextReplace(TextFormat("%s/../projects/VS2022/raylib.sln", exBasePath), exName, exRename);
}
@@ -604,26 +637,34 @@ int main(int argc, char *argv[])
// Edit: Rename example code file (copy and remove)
FileCopy(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName),
TextFormat("%s/%s/%s.c", exBasePath, exCategory, exRename));
- remove(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
// Edit: Rename example screenshot file (copy and remove)
FileCopy(TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName),
TextFormat("%s/%s/%s.png", exBasePath, exCategory, exRename));
- remove(TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName));
// Edit: Update required files: Makefile, Makefile.Web, README.md, examples.js
UpdateRequiredFiles();
}
// Remove old web compilation
- remove(TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName));
- remove(TextFormat("%s/%s/%s.data", exWebPath, exCategory, exName));
- remove(TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName));
- remove(TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.data", exWebPath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName));
// Recompile example (on raylib side)
- // NOTE: Tools requirements: emscripten, w64devkit
- // TODO: Avoid platform-specific .BAT file
- system(TextFormat("%s/build_example_web.bat %s/%s", exBasePath, exRecategory, exRename));
+ // WARNING: EMSDK_PATH must be set to proper location when calling from GitHub Actions
+#if defined(_WIN32)
+ putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
+ system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename));
+#else
+ system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exRecategory, exRename));
+#endif
+ // Update generated .html metadata
+ char exHtmlPath[512] = { 0 };
+ strcpy(exHtmlPath, TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName)); // WARNING: Cache path for saving
+ UpdateWebMetadata(exHtmlPath, TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
// Copy results to web side
FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exRecategory, exRename),
@@ -644,7 +685,7 @@ int main(int argc, char *argv[])
int exIndex = TextFindIndex(exCollectionList, TextFormat("%s;%s", exCategory, exName));
if (exIndex > 0) // Example found
{
- char *exCollectionListUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated list copy, 2MB
+ char *exCollectionListUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated list copy, 2MB
memcpy(exCollectionListUpdated, exCollectionList, exIndex);
int lineLen = 0;
@@ -681,11 +722,11 @@ int main(int argc, char *argv[])
for (int v = 0; v < 3; v++)
{
char *resPathUpdated = TextReplace(resPaths[r], "glsl%i", TextFormat("glsl%i", glslVer[v]));
- remove(TextFormat("%s/%s/%s", exBasePath, exCategory, resPathUpdated));
+ FileRemove(TextFormat("%s/%s/%s", exBasePath, exCategory, resPathUpdated));
RL_FREE(resPathUpdated);
}
}
- else remove(TextFormat("%s/%s/%s", exBasePath, exCategory, resPaths[r]));
+ else FileRemove(TextFormat("%s/%s/%s", exBasePath, exCategory, resPaths[r]));
}
}
@@ -695,17 +736,18 @@ int main(int argc, char *argv[])
// Remove: raylib/examples//_example_name.c
// Remove: raylib/examples//_example_name.png
- remove(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
- remove(TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.png", exBasePath, exCategory, exName));
// Edit: Update required files: Makefile, Makefile.Web, README.md, examples.js
UpdateRequiredFiles();
// Remove: raylib/projects/VS2022/examples/_example_name.vcxproj
- remove(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName));
+ FileRemove(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName));
- // TODO: Edit: raylib/projects/VS2022/raylib.sln --> Remove example project
+ // Edit: raylib/projects/VS2022/raylib.sln --> Remove example project
//---------------------------------------------------------------------------
+ // TODO: Remove project from solution
//RemoveVSProjectFromSolution(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName),
// TextFormat("%s/../projects/VS2022/raylib.sln", exBasePath));
//---------------------------------------------------------------------------
@@ -714,10 +756,10 @@ int main(int argc, char *argv[])
// Remove: raylib.com/examples//_example_name.data
// Remove: raylib.com/examples//_example_name.wasm
// Remove: raylib.com/examples//_example_name.js
- remove(TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName));
- remove(TextFormat("%s/%s/%s.data", exWebPath, exCategory, exName));
- remove(TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName));
- remove(TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.data", exWebPath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName));
+ FileRemove(TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName));
} break;
case OP_VALIDATE: // Validate: report and actions
@@ -740,11 +782,60 @@ int main(int argc, char *argv[])
VALID_INVALID_CATEGORY
*/
+ // TODO: Log more details about the validation process
+
+ // Scan available example .c files and add to collection missing ones
+ // NOTE: Source of truth is what we have in the examples directories (on validation/update)
+ FilePathList list = LoadDirectoryFilesEx(exBasePath, ".c", true);
+
+ char *exList = LoadFileText(exCollectionFilePath);
+ char *exListUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1);
+ bool listUpdated = false;
+
+ int exListLen = (int)strlen(exList);
+ strcpy(exListUpdated, exList);
+
+ for (unsigned int i = 0; i < list.count; i++)
+ {
+ if ((strcmp("examples_template", GetFileNameWithoutExt(list.paths[i])) != 0) && // HACK: Skip "examples_template"
+ (TextFindIndex(exList, GetFileNameWithoutExt(list.paths[i])) == -1))
+ {
+ // Add example to the examples collection list
+ // WARNING: Added to the end of the list, order must be set by users and
+ // defines placement on raylib webpage
+ rlExampleInfo *exInfo = LoadExampleInfo(list.paths[i]);
+
+ // Get example difficulty stars
+ char starsText[16] = { 0 };
+ for (int i = 0; i < 4; i++)
+ {
+ // NOTE: Every UTF-8 star are 3 bytes
+ if (i < exInfo->stars) strcpy(starsText + 3*i, "⭐️");
+ else strcpy(starsText + 3*i, "☆");
+ }
+
+ exListLen += sprintf(exListUpdated + exListLen,
+ TextFormat("%s;%s;%s;%.1f;%.1f;\"%s\";@%s\n",
+ exInfo->category, exInfo->name, starsText, exInfo->verCreated,
+ exInfo->verUpdated, exInfo->author, exInfo->authorGitHub));
+
+ listUpdated = true;
+ UnloadExampleInfo(exInfo);
+ }
+ }
+
+ if (listUpdated) SaveFileText(exCollectionFilePath, exListUpdated);
+
+ UnloadFileText(exList);
+ RL_FREE(exListUpdated);
+
+ UnloadDirectoryFiles(list);
+
// Check all examples in collection [examples_list.txt] -> Source of truth!
int exCollectionCount = 0;
rlExampleInfo *exCollection = LoadExamplesData(exCollectionFilePath, "ALL", false, &exCollectionCount);
- // TODO: Validate: Duplicate entries in collection list?
+ // TODO: Validate: Check duplicate entries in collection list?
// Set status information for all examples, using "status" field in the struct
for (int i = 0; i < exCollectionCount; i++)
@@ -786,6 +877,7 @@ int main(int argc, char *argv[])
// Validate: raylib/examples//resources/.. -> Example resources available?
// Scan resources used in example to check for missing resource files
+ // WARNING: Some paths could be for files to save, not files to load, verify it
char **resPaths = ScanExampleResources(TextFormat("%s/%s/%s.c", exBasePath, exInfo->category, exInfo->name), &exInfo->resCount);
if (exInfo->resCount > 0)
{
@@ -825,11 +917,31 @@ int main(int argc, char *argv[])
// Validate: raylib.com/examples//_example_name.data -> File exists?
// Validate: raylib.com/examples//_example_name.wasm -> File exists?
// Validate: raylib.com/examples//_example_name.js -> File exists?
- if (!FileExists(TextFormat("%s/%s/%s.html", exWebPath, exInfo->category, exInfo->name)) ||
- !FileExists(TextFormat("%s/%s/%s.wasm", exWebPath, exInfo->category, exInfo->name)) ||
- !FileExists(TextFormat("%s/%s/%s.js", exWebPath, exInfo->category, exInfo->name)) ||
- ((exInfo->resCount > 0) && !FileExists(TextFormat("%s/%s/%s.data", exWebPath, exInfo->category, exInfo->name))))
+ if (!TextIsEqual(exInfo->category, "others") &&
+ (!FileExists(TextFormat("%s/%s/%s.html", exWebPath, exInfo->category, exInfo->name)) ||
+ !FileExists(TextFormat("%s/%s/%s.wasm", exWebPath, exInfo->category, exInfo->name)) ||
+ !FileExists(TextFormat("%s/%s/%s.js", exWebPath, exInfo->category, exInfo->name)) ||
+ ((exInfo->resCount > 0) && !FileExists(TextFormat("%s/%s/%s.data", exWebPath, exInfo->category, exInfo->name)))))
+ {
exInfo->status |= VALID_MISSING_WEB_OUTPUT;
+ }
+
+ // Validate: raylib.com/examples//_example_name.html -> Metadata
+ if (FileExists(TextFormat("%s/%s/%s.html", exWebPath, exInfo->category, exInfo->name)))
+ {
+ char *exHtmlText = LoadFileText(TextFormat("%s/%s/%s.html", exWebPath, exInfo->category, exInfo->name));
+
+ if ((TextFindIndex(exHtmlText, "raylib web game") > -1) || // title
+ (TextFindIndex(exHtmlText, "New raylib web videogame, developed using raylib videogames library") > -1) || // description
+ (TextFindIndex(exHtmlText, "https://www.raylib.com/common/raylib_logo.png") > -1) || // image
+ (TextFindIndex(exHtmlText, "https://www.raylib.com/games.html") > -1) || // url
+ (TextFindIndex(exHtmlText, "https://github.com/raysan5/raylib';") > -1)) // source code button
+ {
+ exInfo->status |= VALID_MISSING_WEB_METADATA;
+ }
+
+ UnloadFileText(exHtmlText);
+ }
// NOTE: Additional validation elements
// Validate: Example naming conventions: /_example_name, valid category
@@ -853,7 +965,107 @@ int main(int argc, char *argv[])
UnloadExampleInfo(exInfoHeader);
}
+ if (opCode == OP_UPDATE)
+ {
+ // Actions to fix/review anything possible from validation results
+ //------------------------------------------------------------------------------------------------
+ // Check examples "status" information
+ for (int i = 0; i < exCollectionCount; i++)
+ {
+ rlExampleInfo *exInfo = &exCollection[i];
+
+ if (exInfo->status & VALID_MISSING_C) LOG("WARNING: [%s] Missing code file\n", exInfo->name);
+ else
+ {
+ // NOTE: Some issues can not be automatically fixed, only logged
+ if (exInfo->status & VALID_MISSING_PNG) LOG("WARNING: [%s] Missing screenshot file\n", exInfo->name);
+ if (exInfo->status & VALID_INVALID_PNG) LOG("WARNING: [%s] Invalid screenshot file (using template)\n", exInfo->name);
+ if (exInfo->status & VALID_MISSING_RESOURCES) LOG("WARNING: [%s] Missing resources detected\n", exInfo->name);
+ if (exInfo->status & VALID_INCONSISTENT_INFO) LOG("WARNING: [%s] Inconsistent example header info\n", exInfo->name);
+ if (exInfo->status & VALID_INVALID_CATEGORY) LOG("WARNING: [%s] Invalid example category\n", exInfo->name);
+
+ // NOTE: Some examples should be excluded from VS2022 solution because
+ // they have specific platform/linkage requirements:
+ if ((strcmp(exInfo->name, "core_basic_window_web") == 0) ||
+ (strcmp(exInfo->name, "core_input_gestures_web") == 0) ||
+ (strcmp(exInfo->name, "raylib_opengl_interop") == 0) ||
+ (strcmp(exInfo->name, "raymath_vector_angle") == 0)) continue;
+
+ // Review: Add: raylib/projects/VS2022/examples/_example_name.vcxproj
+ // Review: Add: raylib/projects/VS2022/raylib.sln
+ // Solves: VALID_MISSING_VCXPROJ, VALID_NOT_IN_VCXSOL
+ if (exInfo->status & VALID_MISSING_VCXPROJ)
+ {
+ FileCopy(TextFormat("%s/../projects/VS2022/examples/core_basic_window.vcxproj", exBasePath),
+ TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name));
+ FileTextReplace(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name),
+ "core_basic_window", exInfo->name);
+ FileTextReplace(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name),
+ "..\\..\\examples\\core", TextFormat("..\\..\\examples\\%s", exInfo->category));
+
+ exInfo->status &= ~VALID_MISSING_VCXPROJ;
+ }
+
+ // Add project (.vcxproj) to raylib solution (.sln)
+ if (exInfo->status & VALID_NOT_IN_VCXSOL)
+ {
+ AddVSProjectToSolution(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name),
+ exVSProjectSolutionFile, exInfo->category);
+
+ exInfo->status &= ~VALID_NOT_IN_VCXSOL;
+ }
+
+ // Review: Add/Remove: raylib.com/examples//_example_name.html
+ // Review: Add/Remove: raylib.com/examples//_example_name.data
+ // Review: Add/Remove: raylib.com/examples//_example_name.wasm
+ // Review: Add/Remove: raylib.com/examples//_example_name.js
+ // Solves: VALID_MISSING_WEB_OUTPUT
+ if ((strcmp(exInfo->category, "others") != 0) && // Skipping "others" category
+ ((exInfo->status & VALID_MISSING_WEB_OUTPUT) || (exInfo->status & VALID_MISSING_WEB_METADATA)))
+ {
+ // Build example for PLATFORM_WEB
+ #if defined(_WIN32)
+ putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
+ system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name));
+ #else
+ system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exInfo->category, exInfo->name));
+ #endif
+
+ // Update generated .html metadata
+ char exHtmlPath[512] = { 0 };
+ strcpy(exHtmlPath, TextFormat("%s/%s/%s.html", exBasePath, exInfo->category, exInfo->name)); // WARNING: Cache path for saving
+ UpdateWebMetadata(exHtmlPath, TextFormat("%s/%s/%s.c", exBasePath, exInfo->category, exInfo->name));
+
+ // Copy results to web side
+ FileCopy(exHtmlPath, TextFormat("%s/%s/%s.html", exWebPath, exInfo->category, exInfo->name));
+ FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exInfo->category, exInfo->name),
+ TextFormat("%s/%s/%s.data", exWebPath, exInfo->category, exInfo->name));
+ FileCopy(TextFormat("%s/%s/%s.wasm", exBasePath, exInfo->category, exInfo->name),
+ TextFormat("%s/%s/%s.wasm", exWebPath, exInfo->category, exInfo->name));
+ FileCopy(TextFormat("%s/%s/%s.js", exBasePath, exInfo->category, exInfo->name),
+ TextFormat("%s/%s/%s.js", exWebPath, exInfo->category, exInfo->name));
+
+ exInfo->status &= ~VALID_MISSING_WEB_OUTPUT;
+ exInfo->status &= ~VALID_MISSING_WEB_METADATA;
+ }
+ }
+ }
+
+ // Update files: Makefile, Makefile.Web, README.md, examples.js
+ // Solves: VALID_NOT_IN_MAKEFILE, VALID_NOT_IN_MAKEFILE_WEB, VALID_NOT_IN_README, VALID_NOT_IN_JS
+ UpdateRequiredFiles();
+ for (int i = 0; i < exCollectionCount; i++)
+ {
+ exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE;
+ exCollection[i].status &= ~VALID_NOT_IN_MAKEFILE_WEB;
+ exCollection[i].status &= ~VALID_NOT_IN_README;
+ exCollection[i].status &= ~VALID_NOT_IN_JS;
+ }
+ //------------------------------------------------------------------------------------------------
+ }
+
// Generate validation report/table with results (.md)
+ //-----------------------------------------------------------------------------------------------------
/*
Columns:
[C] VALID_MISSING_C // Missing .c source file
@@ -867,14 +1079,15 @@ int main(int argc, char *argv[])
[RDME] VALID_NOT_IN_README // Not listed in README.md
[JS] VALID_NOT_IN_JS // Not listed in examples.js
[WOUT] VALID_MISSING_WEB_OUTPUT // Missing .html/.data/.wasm/.js
+ [WMETA] VALID_MISSING_WEB_METADATA // Missing .html example metadata
[INFO] VALID_INCONSISTENT_INFO // Inconsistent info between collection and example header (stars, author...)
[CAT] VALID_INVALID_CATEGORY // Not a recognized category
- | [EXAMPLE NAME] | [C] |[CAT]|[INFO]|[PNG]|[WPNG]|[RES]|[MK] |[MKWEB]|[VCX]|[SOL]|[RDME]|[JS] |[WOUT]|
- |:-----------------------------|:---:|:---:|:----:|:---:|:----:|:---:|:---:|:-----:|:---:|:---:|:----:|:---:|:----:|
- | core_basic_window | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
- | shapes_colors_palette | ✘ | ✔ | ✘ | ✔ | ✘ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
- | text_format_text | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ | ✔ | ✔ | ✔ |
+ | [EXAMPLE NAME] | [C] |[CAT]|[INFO]|[PNG]|[WPNG]|[RES]|[MK] |[MKWEB]|[VCX]|[SOL]|[RDME]|[JS] |[WOUT]|[WMETA]|
+ |:-----------------------------|:---:|:---:|:----:|:---:|:----:|:---:|:---:|:-----:|:---:|:---:|:----:|:---:|:----:|:-----:|
+ | core_basic_window | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+ | shapes_colors_palette | ✘ | ✔ | ✘ | ✔ | ✘ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+ | text_format_text | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ |
*/
char *report = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1);
@@ -895,14 +1108,15 @@ int main(int argc, char *argv[])
repIndex += sprintf(report + repIndex, " - [SOL] : Project not included in solution file\n");
repIndex += sprintf(report + repIndex, " - [RDME] : Not listed in README.md\n");
repIndex += sprintf(report + repIndex, " - [JS] : Not listed in Web (examples.js)\n");
- repIndex += sprintf(report + repIndex, " - [WOUT] : Missing Web build (.html/.data/.wasm/.js)\n```\n");
+ repIndex += sprintf(report + repIndex, " - [WOUT] : Missing Web build (.html/.data/.wasm/.js)\n");
+ repIndex += sprintf(report + repIndex, " - [WMETA] : Missing Web .html example metadata\n```\n");
- repIndex += sprintf(report + repIndex, "| **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|\n");
- repIndex += sprintf(report + repIndex, "|:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|\n");
+ repIndex += sprintf(report + repIndex, "| **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]|\n");
+ repIndex += sprintf(report + repIndex, "|:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:|\n");
for (int i = 0; i < exCollectionCount; i++)
{
- repIndex += sprintf(report + repIndex, "| %-32s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s |\n",
+ repIndex += sprintf(report + repIndex, "| %-32s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s |\n",
exCollection[i].name,
(exCollection[i].status & VALID_MISSING_C)? "❌" : "✔",
(exCollection[i].status & VALID_INVALID_CATEGORY)? "❌" : "✔",
@@ -916,76 +1130,114 @@ int main(int argc, char *argv[])
(exCollection[i].status & VALID_NOT_IN_VCXSOL)? "❌" : "✔",
(exCollection[i].status & VALID_NOT_IN_README)? "❌" : "✔",
(exCollection[i].status & VALID_NOT_IN_JS)? "❌" : "✔",
- (exCollection[i].status & VALID_MISSING_WEB_OUTPUT)? "❌" : "✔");
+ (exCollection[i].status & VALID_MISSING_WEB_OUTPUT)? "❌" : "✔",
+ (exCollection[i].status & VALID_MISSING_WEB_METADATA)? "❌" : "✔");
}
SaveFileText(TextFormat("%s/../tools/rexm/%s", exBasePath, "examples_report.md"), report);
RL_FREE(report);
+ //-----------------------------------------------------------------------------------------------------
- //UnloadExamplesData(exCollection); // Done at the end, it can be required for fixing
+ // Generate a report with only the examples missing some elements
+ //-----------------------------------------------------------------------------------------------------
+ char *reportIssues = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1);
- if (opCode == OP_UPDATE)
+ repIndex = 0;
+ repIndex += sprintf(reportIssues + repIndex, "# EXAMPLES COLLECTION - VALIDATION REPORT\n\n");
+
+ repIndex += sprintf(reportIssues + repIndex, "```\nExample elements validated:\n\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [C] : Missing .c source file\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [CAT] : Not a recognized category\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [INFO] : Inconsistent example header info (stars, author...)\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [PNG] : Missing screenshot .png\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [WPNG] : Invalid png screenshot (using default one)\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [RES] : Missing resources listed in the code\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [MK] : Not listed in Makefile\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [MKWEB] : Not listed in Makefile.Web\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [VCX] : Missing Visual Studio project file\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [SOL] : Project not included in solution file\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [RDME] : Not listed in README.md\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [JS] : Not listed in Web (examples.js)\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [WOUT] : Missing Web build (.html/.data/.wasm/.js)\n");
+ repIndex += sprintf(reportIssues + repIndex, " - [WMETA] : Missing Web .html example metadata\n```\n");
+
+ repIndex += sprintf(reportIssues + repIndex, "| **EXAMPLE NAME** | [C] | [CAT]| [INFO]|[PNG]|[WPNG]| [RES]| [MK] |[MKWEB]| [VCX]| [SOL]|[RDME]|[JS] | [WOUT]|[WMETA]|\n");
+ repIndex += sprintf(reportIssues + repIndex, "|:---------------------------------|:---:|:----:|:-----:|:---:|:----:|:----:|:----:|:-----:|:----:|:----:|:----:|:---:|:-----:|:-----:|\n");
+
+ for (int i = 0; i < exCollectionCount; i++)
{
- // Actions to fix/review anything possible from validation results
- //------------------------------------------------------------------------------------------------
- // Check examples "status" information
- for (int i = 0; i < exCollectionCount; i++)
+ if (exCollection[i].status > 0)
{
- rlExampleInfo *exInfo = &exCollection[i];
-
- if (exInfo->status & VALID_MISSING_C) LOG("WARNING: [%s] Missing code file\n", exInfo->name);
- else
- {
- // NOTE: Some issues can not be automatically fixed, only logged
- //if (exInfo->status & VALID_MISSING_PNG) LOG("WARNING: [%s] Missing screenshot file\n", exInfo->name);
- //if (exInfo->status & VALID_INVALID_PNG) LOG("WARNING: [%s] Invalid screenshot file (using template)\n", exInfo->name);
- //if (exInfo->status & VALID_MISSING_RESOURCES) LOG("WARNING: [%s] Missing resources detected\n", exInfo->name);
- //if (exInfo->status & VALID_INCONSISTENT_INFO) LOG("WARNING: [%s] Inconsistent example header info\n", exInfo->name);
- //if (exInfo->status & VALID_INVALID_CATEGORY) LOG("WARNING: [%s] Invalid example category\n", exInfo->name);
-
- // Review: Add: raylib/projects/VS2022/examples/_example_name.vcxproj
- // Review: Add: raylib/projects/VS2022/raylib.sln
- // Solves: VALID_MISSING_VCXPROJ, VALID_NOT_IN_VCXSOL
- if (exInfo->status & VALID_MISSING_VCXPROJ)
- {
- FileCopy(TextFormat("%s/../projects/VS2022/examples/core_basic_window.vcxproj", exBasePath),
- TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name));
- FileTextReplace(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name),
- "core_basic_window", exInfo->name);
- FileTextReplace(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exInfo->name),
- "..\\..\\examples\\core", TextFormat("..\\..\\examples\\%s", exInfo->category));
- }
-
- // WARNING: Adding a .vcxproj to .sln can not be automated with
- // "dotnet" tool (C# projects only)
- // "devenv" tool (no adding support, only building)
- // It must be done manually editing the .sln file
- if (exInfo->status & VALID_NOT_IN_VCXSOL)
- {
- AddVSProjectToSolution(TextFormat("%s/../projects/VS2022/examples/%s.vcxproj", exBasePath, exName),
- TextFormat("%s/../projects/VS2022/raylib.sln", exBasePath));
- }
-
- // Review: Add/Remove: raylib.com/examples//_example_name.html
- // Review: Add/Remove: raylib.com/examples//_example_name.data
- // Review: Add/Remove: raylib.com/examples//_example_name.wasm
- // Review: Add/Remove: raylib.com/examples//_example_name.js
- // Solves: VALID_MISSING_WEB_OUTPUT
- //if (exInfo->status & VALID_MISSING_WEB_OUTPUT)
- // system(TextFormat("%s/build_example_web.bat %s/%s", exBasePath, exInfo->category, exInfo->name));
- }
+ repIndex += sprintf(reportIssues + repIndex, "| %-32s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s |\n",
+ exCollection[i].name,
+ (exCollection[i].status & VALID_MISSING_C)? "❌" : "✔",
+ (exCollection[i].status & VALID_INVALID_CATEGORY)? "❌" : "✔",
+ (exCollection[i].status & VALID_INCONSISTENT_INFO)? "❌" : "✔",
+ (exCollection[i].status & VALID_MISSING_PNG)? "❌" : "✔",
+ (exCollection[i].status & VALID_INVALID_PNG)? "❌" : "✔",
+ (exCollection[i].status & VALID_MISSING_RESOURCES)? "❌" : "✔",
+ (exCollection[i].status & VALID_NOT_IN_MAKEFILE)? "❌" : "✔",
+ (exCollection[i].status & VALID_NOT_IN_MAKEFILE_WEB)? "❌" : "✔",
+ (exCollection[i].status & VALID_MISSING_VCXPROJ)? "❌" : "✔",
+ (exCollection[i].status & VALID_NOT_IN_VCXSOL)? "❌" : "✔",
+ (exCollection[i].status & VALID_NOT_IN_README)? "❌" : "✔",
+ (exCollection[i].status & VALID_NOT_IN_JS)? "❌" : "✔",
+ (exCollection[i].status & VALID_MISSING_WEB_OUTPUT)? "❌" : "✔",
+ (exCollection[i].status & VALID_MISSING_WEB_METADATA)? "❌" : "✔");
}
-
- // Update files: Makefile, Makefile.Web, README.md, examples.js
- // Solves: VALID_NOT_IN_MAKEFILE, VALID_NOT_IN_MAKEFILE_WEB, VALID_NOT_IN_README, VALID_NOT_IN_JS
- UpdateRequiredFiles();
- //------------------------------------------------------------------------------------------------
}
+ SaveFileText(TextFormat("%s/../tools/rexm/%s", exBasePath, "examples_report_issues.md"), reportIssues);
+ RL_FREE(reportIssues);
+ //-----------------------------------------------------------------------------------------------------
+
UnloadExamplesData(exCollection);
//------------------------------------------------------------------------------------------------
} break;
+ case OP_BUILD:
+ {
+ // Build: raylib.com/examples//_example_name.html
+ // Build: raylib.com/examples//_example_name.data
+ // Build: raylib.com/examples//_example_name.wasm
+ // Build: raylib.com/examples//_example_name.js
+ if (strcmp(exCategory, "others") != 0) // Skipping "others" category
+ {
+ // Build example for PLATFORM_DESKTOP
+ #if defined(_WIN32)
+ //putenv(TextFormat("RAYLIB_DIR=%s\\..", exBasePath));
+ putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
+ //putenv("MAKE=mingw32-make");
+ //ChangeDirectory(exBasePath);
+ system(TextFormat("mingw32-make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName));
+ #else
+ system(TextFormat("make -C %s %s/%s PLATFORM=PLATFORM_DESKTOP -B", exBasePath, exCategory, exName));
+ #endif
+
+ // Build example for PLATFORM_WEB
+ #if defined(_WIN32)
+ putenv("PATH=%PATH%;C:\\raylib\\w64devkit\\bin");
+ system(TextFormat("mingw32-make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
+ #else
+ system(TextFormat("make -C %s -f Makefile.Web %s/%s PLATFORM=PLATFORM_WEB -B", exBasePath, exCategory, exName));
+ #endif
+
+ // Update generated .html metadata
+ char exHtmlPath[512] = { 0 };
+ strcpy(exHtmlPath, TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName)); // WARNING: Cache path for saving
+ UpdateWebMetadata(exHtmlPath, TextFormat("%s/%s/%s.c", exBasePath, exCategory, exName));
+
+ // Copy results to web side
+ FileCopy(TextFormat("%s/%s/%s.html", exBasePath, exCategory, exName),
+ TextFormat("%s/%s/%s.html", exWebPath, exCategory, exName));
+ FileCopy(TextFormat("%s/%s/%s.data", exBasePath, exCategory, exName),
+ TextFormat("%s/%s/%s.data", exWebPath, exCategory, exName));
+ FileCopy(TextFormat("%s/%s/%s.wasm", exBasePath, exCategory, exName),
+ TextFormat("%s/%s/%s.wasm", exWebPath, exCategory, exName));
+ FileCopy(TextFormat("%s/%s/%s.js", exBasePath, exCategory, exName),
+ TextFormat("%s/%s/%s.js", exWebPath, exCategory, exName));
+ }
+ } break;
default: // Help
{
// Supported commands:
@@ -1005,20 +1257,25 @@ int main(int argc, char *argv[])
printf("////////////////////////////////////////////////////////////////////////////////////////////\n\n");
printf("USAGE:\n\n");
- printf(" > rexm help|create|add|rename|remove []\n");
+ printf(" > rexm []\n");
- printf("\nOPTIONS:\n\n");
+ printf("\COMMANDS:\n\n");
printf(" help : Provides command-line usage information\n");
printf(" create : Creates an empty example, from internal template\n");
printf(" add : Add existing example, category extracted from name\n");
printf(" Supported categories: core, shapes, textures, text, models\n");
printf(" rename : Rename an existing example\n");
- printf(" remove : Remove an existing example\n\n");
+ printf(" remove : Remove an existing example\n");
+ printf(" build : Build example for Desktop and Web platforms\n");
+ printf(" validate : Validate examples collection, generates report\n");
+ printf(" update : Validate and update examples collection, generates report\n\n");
printf("\nEXAMPLES:\n\n");
printf(" > rexm add shapes_custom_stars\n");
printf(" Add and updates new example provided \n\n");
printf(" > rexm rename core_basic_window core_cool_window\n");
printf(" Renames and updates example to \n\n");
+ printf(" > rexm update\n");
+ printf(" Validates all examples in collection and updates missing elements\n\n");
} break;
}
@@ -1037,7 +1294,7 @@ static int UpdateRequiredFiles(void)
// Edit: raylib/examples/Makefile --> Update from collection
//------------------------------------------------------------------------------------------------
char *mkText = LoadFileText(TextFormat("%s/Makefile", exBasePath));
- char *mkTextUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated Makefile copy, 2MB
+ char *mkTextUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated Makefile copy, 2MB
int mkListStartIndex = TextFindIndex(mkText, "#EXAMPLES_LIST_START");
int mkListEndIndex = TextFindIndex(mkText, "#EXAMPLES_LIST_END");
@@ -1072,7 +1329,7 @@ static int UpdateRequiredFiles(void)
// NOTE: We avoid the "others" category on web building
//------------------------------------------------------------------------------------------------
char *mkwText = LoadFileText(TextFormat("%s/Makefile.Web", exBasePath));
- char *mkwTextUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated Makefile copy, 2MB
+ char *mkwTextUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated Makefile copy, 2MB
int mkwListStartIndex = TextFindIndex(mkwText, "#EXAMPLES_LIST_START");
int mkwListEndIndex = TextFindIndex(mkwText, "#EXAMPLES_LIST_END");
@@ -1192,7 +1449,7 @@ static int UpdateRequiredFiles(void)
// NOTE: Using [examples_list.txt] to update/regen README.md
// Lines format: | 01 | [core_basic_window](core/core_basic_window.c) |
| ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
char *mdText = LoadFileText(TextFormat("%s/README.md", exBasePath));
- char *mdTextUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated examples.js copy, 2MB
+ char *mdTextUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated examples.js copy, 2MB
int mdListStartIndex = TextFindIndex(mdText, "## EXAMPLES COLLECTION");
@@ -1298,7 +1555,7 @@ static int UpdateRequiredFiles(void)
// NOTE: Entries format: exampleEntry('⭐️☆☆☆' , 'core' , 'basic_window'),
//------------------------------------------------------------------------------------------------
char *jsText = LoadFileText(TextFormat("%s/../common/examples.js", exWebPath));
- char *jsTextUpdated = (char *)RL_CALLOC(2*1024*1024, 1); // Updated examples.js copy, 2MB
+ char *jsTextUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1); // Updated examples.js copy, 2MB
int jsListStartIndex = TextFindIndex(jsText, "//EXAMPLE_DATA_LIST_START");
int jsListEndIndex = TextFindIndex(jsText, "//EXAMPLE_DATA_LIST_END");
@@ -1474,7 +1731,11 @@ static int FileRename(const char *fileName, const char *fileRename)
{
int result = 0;
- if (FileExists(fileName)) rename(fileName, TextFormat("%s/%s", GetDirectoryPath(fileName), fileRename));
+ if (FileExists(fileName))
+ {
+ result = rename(fileName, fileRename);
+ }
+ else result = -1;
return result;
}
@@ -1484,7 +1745,11 @@ static int FileRemove(const char *fileName)
{
int result = 0;
- if (FileExists(fileName)) remove(fileName);
+ if (FileExists(fileName))
+ {
+ result = remove(fileName);
+ }
+ else result = -1;
return result;
}
@@ -1500,49 +1765,18 @@ static int FileMove(const char *srcPath, const char *dstPath)
FileCopy(srcPath, dstPath);
remove(srcPath);
}
+ else result = -1;
return result;
}
-// Load text lines
-static char **LoadTextLines(const char *text, int *count)
-{
- #define MAX_TEXT_LINES 512
- #define MAX_TEXT_LINE_LEN 256
-
- char **lines = (char **)RL_CALLOC(MAX_TEXT_LINES, sizeof(char *));
- for (int i = 0; i < MAX_TEXT_LINES; i++) lines[i] = (char *)RL_CALLOC(MAX_TEXT_LINE_LEN, 1);
- int textSize = (int)strlen(text);
- int k = 0;
-
- for (int i = 0, len = 0; (i < textSize) && (k < MAX_TEXT_LINES); i++)
- {
- if (text[i] == '\n')
- {
- strncpy(lines[k], &text[i - len], len);
- len = 0;
- k++;
- }
- else len++;
- }
-
- *count += k;
- return lines;
-}
-
-// Unload text lines
-static void UnloadTextLines(char **lines)
-{
- for (int i = 0; i < MAX_TEXT_LINES; i++) RL_FREE(lines[i]);
- RL_FREE(lines);
-}
-
-// Get example info from file header
+// Get example info from example file header
+// NOTE: Expecting the example to follow raylib_example_template.c
rlExampleInfo *LoadExampleInfo(const char *exFileName)
{
rlExampleInfo *exInfo = (rlExampleInfo *)RL_CALLOC(1, sizeof(rlExampleInfo));
- if (IsFileExtension(exFileName, ".c"))
+ if (FileExists(exFileName) && IsFileExtension(exFileName, ".c"))
{
strcpy(exInfo->name, GetFileNameWithoutExt(exFileName));
strncpy(exInfo->category, exInfo->name, TextFindIndex(exInfo->name, "_"));
@@ -1612,6 +1846,8 @@ rlExampleInfo *LoadExampleInfo(const char *exFileName)
}
UnloadFileText(exText);
+
+ exInfo->resPaths = ScanExampleResources(exFileName, &exInfo->resCount);
}
return exInfo;
@@ -1620,6 +1856,7 @@ rlExampleInfo *LoadExampleInfo(const char *exFileName)
// Unload example information
static void UnloadExampleInfo(rlExampleInfo *exInfo)
{
+ ClearExampleResources(exInfo->resPaths);
RL_FREE(exInfo);
}
@@ -1711,32 +1948,43 @@ static char **ScanExampleResources(const char *filePath, int *resPathCount)
char *end = strchr(start, '"');
if (!end) break;
- int len = (int)(end - start);
- if ((len > 0) && (len < REXM_MAX_RESOURCE_PATH_LEN))
+ // WARNING: Some paths could be for saving files, not loading, those "resource" files must be omitted
+ // HACK: Just check previous position from pointer for function name including the string...
+ // This is a dirty solution, the good one would be getting the data loading function names...
+ if (TextFindIndex(ptr - 40, "ExportImage") == -1)
{
- char buffer[REXM_MAX_RESOURCE_PATH_LEN] = { 0 };
- strncpy(buffer, start, len);
- buffer[len] = '\0';
-
- // Check for known extensions
- for (int i = 0; i < extCount; i++)
+ int len = (int)(end - start);
+ if ((len > 0) && (len < REXM_MAX_RESOURCE_PATH_LEN))
{
- if (IsFileExtension(buffer, exts[i]))
+ char buffer[REXM_MAX_RESOURCE_PATH_LEN] = { 0 };
+ strncpy(buffer, start, len);
+ buffer[len] = '\0';
+
+ // TODO: Make sure buffer is a path (and not a TraceLog() string)
+
+ // Check for known extensions
+ for (int i = 0; i < extCount; i++)
{
- // Avoid duplicates
- bool found = false;
- for (int j = 0; j < resCounter; j++)
+ // TODO: WARNING: IsFileExtension() expects a NULL terminated fileName,
+ // but in this case buffer can contain any kind of string,
+ // including not paths strings, for example TraceLog() string
+ if (IsFileExtension(buffer, exts[i]))
{
- if (TextIsEqual(paths[j], buffer)) { found = true; break; }
- }
+ // Avoid duplicates
+ bool found = false;
+ for (int j = 0; j < resCounter; j++)
+ {
+ if (strcmp(paths[j], buffer) == 0) { found = true; break; }
+ }
- if (!found && (resCounter < REXM_MAX_RESOURCE_PATHS))
- {
- strcpy(paths[resCounter], buffer);
- resCounter++;
- }
+ if (!found && (resCounter < REXM_MAX_RESOURCE_PATHS))
+ {
+ strcpy(paths[resCounter], buffer);
+ resCounter++;
+ }
- break;
+ break;
+ }
}
}
}
@@ -1759,56 +2007,207 @@ static void ClearExampleResources(char **resPaths)
RL_FREE(resPaths);
}
-// TODO: Add VS project (.vcxproj) to existing VS solution (.sol)
-static int AddVSProjectToSolution(const char *projFile, const char *solFile)
+// Add VS project (.vcxproj) to existing VS solution (.sln)
+// WARNING: Adding a .vcxproj to .sln can not be automated with:
+// - "dotnet" tool (C# projects only)
+// - "devenv" tool (no adding support, only building)
+// It must be done manually editing the .sln file
+static int AddVSProjectToSolution(const char *projFile, const char *slnFile, const char *category)
{
int result = 0;
- // Generate unique UUID:
- // C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\uuidgen.exe > saved_uuid.txt
+ // WARNING: Function uses extensively TextFormat(),
+ // *projFile ptr will be overwriten after a while
- // Add project to the list:
+ // Generate unique UUID
+ const char *uuid = GenerateUUIDv4();
+
+ // Replace default UUID (core_basic_window) on project file by new one
+ FileTextReplace(projFile, "0981CA98-E4A5-4DF1-987F-A41D09131EFC", uuid);
+
+ char *slnText = LoadFileText(slnFile);
+ char *slnTextUpdated = (char *)RL_CALLOC(REXM_MAX_BUFFER_SIZE, 1);
+
+ // Add project to solution
+ //----------------------------------------------------------------------------------------
// Format: Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "", "examples\.vcxproj", "{}"
- /*
- Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_basic_window", "examples\core_basic_window.vcxproj", "{0981CA98-E4A5-4DF1-987F-A41D09131EFC}"
- EndProject
- */
+ // NOTE: Find a position to insert new project: At the end of the projects list, same strategy as VS2022 "Add Project"
+ int prjStartIndex = TextFindIndex(slnText, "Global");
- // Update project config:
- /*
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|ARM64.Build.0 = Debug|ARM64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x64.ActiveCfg = Debug|x64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x64.Build.0 = Debug|x64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x86.ActiveCfg = Debug|Win32
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Debug|x86.Build.0 = Debug|Win32
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x64.Build.0 = Release.DLL|x64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release.DLL|x86.Build.0 = Release.DLL|Win32
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|ARM64.ActiveCfg = Release|ARM64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|ARM64.Build.0 = Release|ARM64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x64.ActiveCfg = Release|x64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x64.Build.0 = Release|x64
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x86.ActiveCfg = Release|Win32
- {D3493FFE-8873-4C53-8F6C-74DEF78EA3C4}.Release|x86.Build.0 = Release|Win32
- */
+ // Add new project info
+ // WARNING: UUID can actually be duplicated and it still works...
+ strncpy(slnTextUpdated, slnText, prjStartIndex);
+ int offsetIndex = sprintf(slnTextUpdated + prjStartIndex,
+ TextFormat("Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"%s\", \"examples\\%s\", \"{%s}\"\n",
+ GetFileNameWithoutExt(projFile), GetFileName(projFile), uuid));
+ offsetIndex += prjStartIndex;
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "EndProject\n");
+ //----------------------------------------------------------------------------------------
+
+ // Update project config
+ //----------------------------------------------------------------------------------------
+ // Find position to add project config: At the end of global section, same strategy as VS2022 "Add Project"
+ int projConfStartIndex = TextFindIndex(slnText, "GlobalSection(ProjectConfigurationPlatforms) = postSolution");
+ strncpy(slnTextUpdated + offsetIndex, slnText + prjStartIndex, projConfStartIndex - prjStartIndex);
+ offsetIndex += (projConfStartIndex - prjStartIndex);
- // Update projects to folders:
- // {project_uuid} = {solution_folder_uuid}
- /*
- GlobalSection(NestedProjects) = preSolution
- {0981CA98-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
- */
+ int projConfEndIndex = TextFindIndex(slnText + projConfStartIndex, "EndGlobalSection");
+ projConfEndIndex += projConfStartIndex;
+
+ strncpy(slnTextUpdated + offsetIndex, slnText + projConfStartIndex, projConfEndIndex - projConfStartIndex);
+ offsetIndex += (projConfEndIndex - projConfStartIndex);
+
+ // Add project config lines
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t{%s}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x64.Build.0 = Debug.DLL|x64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|ARM64.ActiveCfg = Debug|ARM64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|ARM64.Build.0 = Debug|ARM64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x64.ActiveCfg = Debug|x64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x64.Build.0 = Debug|x64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x86.ActiveCfg = Debug|Win32\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Debug|x86.Build.0 = Debug|Win32\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x64.ActiveCfg = Release.DLL|x64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x64.Build.0 = Release.DLL|x64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release.DLL|x86.Build.0 = Release.DLL|Win32\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|ARM64.ActiveCfg = Release|ARM64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|ARM64.Build.0 = Release|ARM64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x64.ActiveCfg = Release|x64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x64.Build.0 = Release|x64\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x86.ActiveCfg = Release|Win32\n", uuid));
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s}.Release|x86.Build.0 = Release|Win32\n", uuid));
+ // Write next section directly to avoid copy logic
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\tEndGlobalSection\n");
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\tGlobalSection(SolutionProperties) = preSolution\n");
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\t\tHideSolutionNode = FALSE\n");
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\tEndGlobalSection\n\t");
+ //----------------------------------------------------------------------------------------
+
+ // Place project to explorer folder
+ //----------------------------------------------------------------------------------------
+ // Find position to add project folder: At the end of global section, same strategy as VS2022 "Add Project"
+ int projFolderStartIndex = TextFindIndex(slnText, "GlobalSection(NestedProjects) = preSolution");
+ int projFolderEndIndex = TextFindIndex(slnText + projFolderStartIndex, "\tEndGlobalSection");
+ projFolderEndIndex += projFolderStartIndex;
+
+ strncpy(slnTextUpdated + offsetIndex, slnText + projFolderStartIndex, projFolderEndIndex - projFolderStartIndex);
+ offsetIndex += (projFolderEndIndex - projFolderStartIndex);
+
+ // Add project folder line
+ // NOTE: Folder uuid depends on category
+ if (strcmp(category, "core") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}\n", uuid));
+ else if (strcmp(category, "shapes") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {278D8859-20B1-428F-8448-064F46E1F021}\n", uuid));
+ else if (strcmp(category, "textures") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}\n", uuid));
+ else if (strcmp(category, "text") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}\n", uuid));
+ else if (strcmp(category, "models") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}\n", uuid));
+ else if (strcmp(category, "shaders") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9}\n", uuid));
+ else if (strcmp(category, "audio") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {CC132A4D-D081-4C26-BFB9-AB11984054F8}\n", uuid));
+ else if (strcmp(category, "other") == 0) offsetIndex += sprintf(slnTextUpdated + offsetIndex, TextFormat("\t\t{%s} = {E9D708A5-9C1F-4B84-A795-C5F191801762}\n", uuid));
+ else LOG("WARNING: Provided category is not valid: %s\n", category);
+ //----------------------------------------------------------------------------------------
+
+ // Write end of file, no need to copy from original file
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\tEndGlobalSection\n");
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\tGlobalSection(ExtensibilityGlobals) = postSolution\n");
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\t\tSolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}\n");
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "\tEndGlobalSection\n");
+ offsetIndex += sprintf(slnTextUpdated + offsetIndex, "EndGlobal\n");
+
+ SaveFileText(slnFile, slnTextUpdated);
+ UnloadFileText(slnText);
+ RL_FREE(slnTextUpdated);
return result;
}
+
+// Generate unique UUID v4 string
+// Output format: {9A2F48CC-0DA8-47C0-884E-02E37F9BE6C1}
+static const char *GenerateUUIDv4(void)
+{
+ static char uuid[38] = { 0 };
+ memset(uuid, 0, 38);
+
+ unsigned char bytes[16] = { 0 };
+
+ for (int i = 0; i < 16; i++) bytes[i] = (unsigned char)GetRandomValue(0, 255);
+
+ // Set version (4) and variant (RFC 4122)
+ bytes[6] = (bytes[6] & 0x0F) | 0x40; // Version
+ bytes[8] = (bytes[8] & 0x3F) | 0x80; // Variant
+
+ snprintf(uuid, 38,
+ "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ bytes[0], bytes[1], bytes[2], bytes[3],
+ bytes[4], bytes[5],
+ bytes[6], bytes[7],
+ bytes[8], bytes[9],
+ bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15]);
+
+ return uuid;
+}
+
+// Update generated Web example .html file metadata
+static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath)
+{
+ if (FileExists(exHtmlPath) && IsFileExtension(exHtmlPath, ".html"))
+ {
+ char *fileText = LoadFileText(exHtmlPath);
+ char *fileTextUpdated[6] = { 0 }; // Pointers to multiple updated text versions
+
+ char exName[64] = { 0 }; // Example name: fileName without extension
+ char exCategory[16] = { 0 }; // Example category: core, shapes, text, textures, models, audio, shaders
+ char exDescription[256] = { 0 }; // Example description: example text line #3
+ char exTitle[64] = { 0 }; // Example title: fileName without extension, replacing underscores by spaces
+
+ memset(exName, 0, 64);
+ memset(exTitle, 0, 64);
+ memset(exDescription, 0, 256);
+ memset(exCategory, 0, 16);
+
+ // Get example name: replace underscore by spaces
+ strcpy(exName, GetFileNameWithoutExt(exHtmlPath));
+ strcpy(exTitle, exName);
+ for (int i = 0; (i < 256) && (exTitle[i] != '\0'); i++) { if (exTitle[i] == '_') exTitle[i] = ' '; }
+
+ // Get example category from exName: copy until first underscore
+ for (int i = 0; (exName[i] != '_'); i++) exCategory[i] = exName[i];
+
+ // Get example description: copy line #3 from example file
+ char *exText = LoadFileText(exFilePath);
+ int lineCount = 0;
+ char **lines = LoadTextLines(exText, &lineCount);
+ int lineLength = (int)strlen(lines[2]);
+ strncpy(exDescription, lines[2] + 4, lineLength - 4);
+ UnloadTextLines(lines);
+ UnloadFileText(exText);
+
+ // Update example.html required text
+ fileTextUpdated[0] = TextReplace(fileText, "raylib web game", exTitle);
+ fileTextUpdated[1] = TextReplace(fileTextUpdated[0], "New raylib web videogame, developed using raylib videogames library", exDescription);
+ fileTextUpdated[2] = TextReplace(fileTextUpdated[1], "https://www.raylib.com/common/raylib_logo.png",
+ TextFormat("https://raw.githubusercontent.com/raysan5/raylib/master/examples/%s/%s.png", exCategory, exName));
+ fileTextUpdated[3] = TextReplace(fileTextUpdated[2], "https://www.raylib.com/games.html",
+ TextFormat("https://www.raylib.com/examples/%s/%s.html", exCategory, exName));
+ fileTextUpdated[4] = TextReplace(fileTextUpdated[3], "raylib - example", TextFormat("raylib - %s", exName)); // og:site_name
+ fileTextUpdated[5] = TextReplace(fileTextUpdated[4], "https://github.com/raysan5/raylib",
+ TextFormat("https://github.com/raysan5/raylib/blob/master/examples/%s/%s.c", exCategory, exName));
+
+ SaveFileText(exHtmlPath, fileTextUpdated[5]);
+
+ //LOG("INFO: [%s] Updated successfully\n",files.paths[i]);
+ //LOG(" - Name / Title: %s / %s\n", exName, exTitle);
+ //LOG(" - Description: %s\n", exDescription);
+ //LOG(" - URL: %s\n", TextFormat("https://www.raylib.com/examples/%s/%s.html", exCategory, exName));
+ //LOG(" - URL Source: %s\n", TextFormat("https://github.com/raysan5/raylib/blob/master/examples/%s/%s.c", exCategory, exName));
+
+ for (int i = 0; i < 6; i++) { MemFree(fileTextUpdated[i]); fileTextUpdated[i] = NULL; }
+
+ UnloadFileText(fileText);
+ }
+}
diff --git a/tools/rexm/rexm.ico b/tools/rexm/rexm.ico
index 0cedcc55c..1f917e5dd 100644
Binary files a/tools/rexm/rexm.ico and b/tools/rexm/rexm.ico differ
diff --git a/tools/rexm/rexm.rc.data b/tools/rexm/rexm.rc.data
new file mode 100644
index 000000000..2a44de667
Binary files /dev/null and b/tools/rexm/rexm.rc.data differ