Merge branch 'master' into master

This commit is contained in:
Ray 2026-02-10 18:10:38 +01:00 committed by GitHub
commit a81828e910
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
291 changed files with 35128 additions and 8184 deletions

View File

@ -84,8 +84,10 @@ jobs:
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_NAME }}.tar.gz
path: ./build/${{ env.RELEASE_NAME }}.tar.gz
name: ${{ env.RELEASE_NAME }}
path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1

View File

@ -114,8 +114,10 @@ jobs:
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_NAME }}.tar.gz
path: ./build/${{ env.RELEASE_NAME }}.tar.gz
name: ${{ env.RELEASE_NAME }}
path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1

View File

@ -101,8 +101,10 @@ jobs:
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_NAME }}.tar.gz
path: ./build/${{ env.RELEASE_NAME }}.tar.gz
name: ${{ env.RELEASE_NAME }}
path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.tar.gz
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1

View File

@ -71,8 +71,10 @@ jobs:
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_NAME }}.zip
path: ./build/${{ env.RELEASE_NAME }}.zip
name: ${{ env.RELEASE_NAME }}
path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.zip
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1

View File

@ -142,8 +142,10 @@ jobs:
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_NAME }}.zip
path: ./build/${{ env.RELEASE_NAME }}.zip
name: ${{ env.RELEASE_NAME }}
path: |
./build/${{ env.RELEASE_NAME }}
!./build/${{ env.RELEASE_NAME }}.zip
- name: Upload Artifact to Release
uses: softprops/action-gh-release@v1

View File

@ -22,7 +22,7 @@ jobs:
- name: Diff parse files
id: diff
run: |
git add -N tools/rlparser
git add -N tools/rlparser/output
git diff --name-only --exit-code
continue-on-error: true
@ -32,6 +32,6 @@ jobs:
set -x
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add tools/rlparser
git add tools/rlparser/output
git commit -m "rlparser: update raylib_api.* by CI"
git push

View File

@ -29,8 +29,9 @@ jobs:
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
# "rexm validate" validates examples collection, looking for inconsistencies, it does not rebuild examples
# "rexm update" validates and updates all examples with inconsistencies, pushing fixes to raylib and raylib.com repos
# note that rexm 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"
@ -47,7 +48,7 @@ jobs:
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
./rexm validate
shell: bash
- name: Commit changes to raylib repo (DISABLED)

12
.gitignore vendored
View File

@ -58,14 +58,23 @@ packages/
*.h.pch
./*.obj
# Ignore SDL libs for testing
src/external/SDL2
src/external/SDL3
# Emscripten
emsdk
# Ignore wasm data in examples/
examples/**/*
!examples/**/*.*
!examples/**/*/
examples/**/*.exe
examples/**/*.wasm
examples/**/*.data
examples/**/*.js
examples/**/*.html
examples/**/logs/*
# Ignore files build by xcode
*.mode*v*
@ -115,7 +124,8 @@ build-*/
docgen_tmp/
# Tools stuff
tools/parser/raylib_parser
tools/parser/rlparser.exe
tools/parser/rlparser
tools/rexm/rexm.exe
tools/rexm/rexm

View File

@ -21,6 +21,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
| [raylib](https://github.com/fosskers/raylib) | 5.5 | [Common Lisp](https://common-lisp.net) | MPL-2.0 |
| [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 |
| [chicken-raylib](https://github.com/meowstr/chicken-raylib) | 5.5 | [CHICKEN Scheme](https://wiki.call-cc.org) | MIT |
| [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT |
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 |
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
@ -28,9 +29,12 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib |
| [DenoRaylib550](https://github.com/JJLDonley/DenoRaylib550) | **5.5** | [Deno](https://deno.land) | MIT |
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.5** | [Go](https://golang.org) | Zlib |
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
@ -82,6 +86,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib-v](https://github.com/vlang/raylib) | 5.5 | [V](https://vlang.io) | MIT/Unlicense |
| [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib |
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **5.0** | [Vala](https://vala.dev) | Zlib |
| [raylib-wave](https://github.com/wavefnd/raylib-wave) | **auto** |[Wave](http://wave-lang.dev) | Zlib |
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
| [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 |
@ -90,6 +95,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD |
| [raylib-bqn](https://github.com/Brian-ED/raylib-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
| [rayjs](https://github.com/mode777/rayjs) | 4.6-dev | [QuickJS](https://bellard.org/quickjs) | MIT |
| [rayjule](https://github.com/SabeDoesThings/rayjule) | **5.5** | [Jule](https://jule.dev/) | MIT |
| [raylib-raku](https://github.com/vushu/raylib-raku) | **auto** | [Raku](https://www.raku.org) | Artistic License 2.0 |
| [Raylib.lean](https://github.com/KislyjKisel/Raylib.lean) | **5.5-dev** | [Lean4](https://lean-lang.org) | BSD-3-Clause |
| [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain |
@ -98,6 +104,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
| [Rayua](https://github.com/uiua-lang/rayua) | **5.5** | [Uiua](https://www.uiua.org/) | **???** |
### Utility Wrapers
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's paradigm.

View File

@ -565,7 +565,7 @@ Detailed changes:
[rtext] ADDED: SetTextLineSpacing() to define line breaks text drawing spacing by @raysan5
[rtext] RENAMED: LoadFont*() parameter names for consistency and coherence by @raysan5
[rtext] REVIEWED: GetCodepointCount(), ignore unused return value of GetCodepointNext by @ashn-dot-dev
[rtext] REVIEWED: TextFormat() warn user if buffer overflow occured (#3399) by @Murlocohol
[rtext] REVIEWED: TextFormat() warn user if buffer overflow occurred (#3399) by @Murlocohol
[rtext] REVIEWED: TextFormat(), added "..." for truncation (#3366) by @raysan5
[rtext] REVIEWED: GetGlyphIndex() (#3000) by @raysan5
[rtext] REVIEWED: GetCodepointNext() to return default value by @chocolate42

View File

@ -6,7 +6,7 @@ if(EMSCRIPTEN)
# When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default
SET(PLATFORM Web CACHE STRING "Platform to build for.")
endif()
enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM;SDL" "Platform to build for.")
enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM;SDL;RGFW" "Platform to build for.")
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")

View File

@ -41,6 +41,7 @@ while (!WindowShouldClose())
}
// Always use accumulators as `x++` instead of `++x`
for (int i = 0; i < NUM_VALUES; i++) printf("%i", i);
// Be careful with the switch formatting!

View File

@ -1,4 +1,4 @@
Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
This software is provided "as-is", without any express or implied warranty. In no event
will the authors be held liable for any damages arising from the use of this software.

View File

@ -140,7 +140,7 @@ contributors
------------
<a href="https://github.com/raysan5/raylib/graphs/contributors">
<img src="https://contrib.rocks/image?repo=raysan5/raylib&max=500&columns=20&anon=1" />
<img src="https://contrib.rocks/image?repo=raysan5/raylib&max=800&columns=24&anon=0" />
</a>
license

View File

@ -15,13 +15,13 @@ _Current version of raylib is complete and functional but there is always room f
**raylib 5.x**
- [ ] `rcore`: Support additional platforms: iOS, consoles?
- [ ] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK
- [x] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK
- [ ] `rlgl`: Review GLSL shaders naming conventions for consistency
- [ ] `textures`: Improve compressed textures support, loading and saving
- [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf)
- [ ] `raudio`: Implement miniaudio high-level provided features
- [ ] `examples`: Review all examples, add more and better code explanations
- [ ] Software renderer backend? Maybe using `Image` provided API
- [x] `examples`: Review all examples, add more and better code explanations
- [x] Software renderer backend? Maybe using `Image` provided API
**raylib 4.x**
- [x] Split core module into separate platforms?

18
SECURITY.md Normal file
View File

@ -0,0 +1,18 @@
# Security Policy
## Supported Versions
Most considerations of errors and defects can be handled using the project Issues and/or Discussions.
| Version | Supported |
| ------- | ------------------ |
| 6.0.x | :white_check_mark: |
| < 5.5 | :x: |
## Reporting a Vulnerability
Discovered vulnerability can be directly reported using the project Issues and/or Discussions.
_TODO: Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc._

View File

@ -2,7 +2,7 @@ const std = @import("std");
const builtin = @import("builtin");
/// Minimum supported version of Zig
const min_ver = "0.15.1";
const min_ver = "0.16.0-dev.2349+204fa8959";
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
const emccOutputFile = "index.html";
@ -106,9 +106,9 @@ const config_h_flags = outer: {
if (std.mem.startsWith(u8, line, "//")) continue;
if (std.mem.startsWith(u8, line, "#if")) continue;
var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace
var flag = std.mem.trimStart(u8, line, " \t"); // Trim whitespace
flag = flag["#define ".len - 1 ..]; // Remove #define
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace
flag = std.mem.trimStart(u8, flag, " \t"); // Trim whitespace
flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
flag = "-D" ++ flag; // Prepend with -D
@ -155,9 +155,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
);
}
// Sets a flag indiciating the use of a custom `config.h`
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
if (options.config.len > 0) {
// Sets a flag indicating the use of a custom `config.h`
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
// Splits a space-separated list of config flags into multiple flags
//
// Note: This means certain flags like `-x c++` won't be processed properly.
@ -187,17 +187,17 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
try raylib_flags_arr.append(b.allocator, flag);
}
} else {
// Set default config if no custome config got set
// Set default config if no custom config got set
try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
}
// No GLFW required on PLATFORM_DRM
if (options.platform != .drm) {
raylib.addIncludePath(b.path("src/external/glfw/include"));
raylib.root_module.addIncludePath(b.path("src/external/glfw/include"));
}
var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2);
c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c", "src/utils.c" });
c_source_files.appendSliceAssumeCapacity(&.{"src/rcore.c"});
if (options.rshapes) {
try c_source_files.append(b.allocator, "src/rshapes.c");
@ -224,7 +224,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), "");
}
raylib.addIncludePath(b.path("src/platforms"));
raylib.root_module.addIncludePath(b.path("src/platforms"));
switch (target.result.os.tag) {
.windows => {
switch (options.platform) {
@ -348,7 +348,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
}
},
.freebsd, .openbsd, .netbsd, .dragonfly => {
try c_source_files.append(b.allocator, "rglfw.c");
try c_source_files.append(b.allocator, "src/rglfw.c");
raylib.root_module.linkSystemLibrary("GL", .{});
raylib.root_module.linkSystemLibrary("rt", .{});
raylib.root_module.linkSystemLibrary("dl", .{});
@ -438,7 +438,7 @@ pub const Options = struct {
pub fn getOptions(b: *std.Build) Options {
return .{
.platform = b.option(PlatformBackend, "platform", "Choose the platform backedn for desktop target") orelse defaults.platform,
.platform = b.option(PlatformBackend, "platform", "Choose the platform backend for desktop target") orelse defaults.platform,
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
@ -448,7 +448,7 @@ pub const Options = struct {
.linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend,
.opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version,
.config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{},
.android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse std.process.getEnvVarOwned(b.allocator, "ANDROID_NDK_HOME") catch "",
.android_ndk = b.option([]const u8, "android_ndk", "specify path to android ndk") orelse b.graph.environ_map.get("ANDROID_NDK_HOME") orelse "",
.android_api_version = b.option([]const u8, "android_api_version", "specify target android API level") orelse defaults.android_api_version,
};
}
@ -523,15 +523,17 @@ fn addExamples(
) !*std.Build.Step {
const all = b.step(module, "All " ++ module ++ " examples");
const module_subpath = b.pathJoin(&.{ "examples", module });
var dir = try std.fs.cwd().openDir(b.pathFromRoot(module_subpath), .{ .iterate = true });
defer dir.close();
var dir = try std.Io.Dir.cwd().openDir(b.graph.io, b.pathFromRoot(module_subpath), .{ .iterate = true });
defer dir.close(b.graph.io);
var iter = dir.iterate();
while (try iter.next()) |entry| {
while (try iter.next(b.graph.io)) |entry| {
if (entry.kind != .file) continue;
const extension_idx = std.mem.lastIndexOf(u8, entry.name, ".c") orelse continue;
const name = entry.name[0..extension_idx];
const path = b.pathJoin(&.{ module_subpath, entry.name });
const filename = try std.fmt.allocPrint(b.allocator, "{s}.c", .{name});
const path = b.pathJoin(&.{ module_subpath, filename });
// zig's mingw headers do not include pthread.h
if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue;
@ -553,12 +555,11 @@ fn addExamples(
});
if (std.mem.eql(u8, name, "rlgl_standalone")) {
//TODO: Make rlgl_standalone example work
continue;
exe_mod.addIncludePath(b.path("src"));
exe_mod.addIncludePath(b.path("src/external/glfw/include"));
}
if (std.mem.eql(u8, name, "raylib_opengl_interop")) {
//TODO: Make raylib_opengl_interop example work
continue;
exe_mod.addIncludePath(b.path("src/external"));
}
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize });
@ -650,6 +651,7 @@ fn addExamples(
all.dependOn(&install_cmd.step);
}
}
return all;
}

View File

@ -27,6 +27,12 @@ if (${PLATFORM} MATCHES "Desktop")
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
find_package(OpenGL QUIET)
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} winmm)
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "QNX")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
find_library(GLESV2 GLESv2)
find_library(EGL EGL)
set(LIBS_PUBLIC m)
set(LIBS_PRIVATE ${GLESV2} ${EGL} atomic pthread dl)
elseif (UNIX)
find_library(pthread NAMES pthread)
find_package(OpenGL QUIET)
@ -141,6 +147,26 @@ elseif ("${PLATFORM}" MATCHES "SDL")
add_compile_definitions(USING_SDL2_PACKAGE)
endif()
endif()
elseif ("${PLATFORM}" MATCHES "RGFW")
set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW")
if (APPLE)
find_library(COCOA Cocoa)
find_library(OPENGL OpenGL)
set(LIBS_PRIVATE ${COCOA} ${OPENGL})
elseif (WIN32)
find_package(OpenGL REQUIRED)
set(LIBS_PRIVATE ${OPENGL_LIBRARIES} gdi32)
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "QNX")
message(FATAL_ERROR "RGFW platform does not support QNX. Use PLATFORM=Desktop or PLATFORM=SDL instead.")
elseif (UNIX)
find_package(X11 REQUIRED)
find_package(OpenGL REQUIRED)
set(LIBS_PRIVATE ${X11_LIBRARIES} ${OPENGL_LIBRARIES})
endif ()
endif ()
if (NOT ${OPENGL_VERSION} MATCHES "OFF")

View File

@ -30,7 +30,7 @@
# > PLATFORM_ANDROID:
# - Android (ARM, ARM64)
#
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@ -205,15 +205,17 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
endif
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make
endif
endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(OS),Windows_NT)
ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make
else
EMMAKE != type emmake
EMMAKE := $(shell command -v emmake)
ifneq (, $(EMMAKE))
MAKE = emmake make
MAKE = $(EMMAKE) make
else
MAKE = mingw32-make
endif
@ -231,7 +233,7 @@ endif
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -Wno-unused-value ignore unused return values of some functions (i.e. fread())
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result
CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wno-unused-result
ifeq ($(BUILD_MODE),DEBUG)
CFLAGS += -g -D_DEBUG
@ -486,7 +488,19 @@ endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
# Libraries for DRM compiling
# NOTE: Required packages: libasound2-dev (ALSA)
LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic
LDLIBS = -lraylib -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl -latomic
# TODO: Examples compilation does not define GRAPHICS, is it required?
#ifeq ($(GRAPHICS),GRAPHICS_API_OPENGL_ES2)
# LDLIBS += -lGLESv2 -lEGL
#endif
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_WIN32)
# Libraries for Windows desktop compilation
LDFLAGS += -L..\src
LDLIBS = -lraylib -lgdi32 -lwinmm -lshcore
ifneq ($(GRAPHICS),GRAPHICS_API_OPENGL_11_SOFTWARE)
LDLIBS += -lopengl32
endif
endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
# Libraries for web (HTML5) compiling
@ -513,12 +527,13 @@ CORE = \
core/core_basic_screen_manager \
core/core_basic_window \
core/core_clipboard_text \
core/core_compute_hash \
core/core_custom_frame_control \
core/core_custom_logging \
core/core_delta_time \
core/core_directory_files \
core/core_drop_files \
core/core_high_dpi \
core/core_highdpi_demo \
core/core_highdpi_testbed \
core/core_input_actions \
core/core_input_gamepad \
@ -529,6 +544,7 @@ CORE = \
core/core_input_mouse_wheel \
core/core_input_multitouch \
core/core_input_virtual_controls \
core/core_keyboard_testbed \
core/core_monitor_detector \
core/core_random_sequence \
core/core_random_values \
@ -539,6 +555,7 @@ CORE = \
core/core_storage_values \
core/core_text_file_loading \
core/core_undo_redo \
core/core_viewport_scaling \
core/core_vr_simulator \
core/core_window_flags \
core/core_window_letterbox \
@ -546,6 +563,7 @@ CORE = \
core/core_world_screen
SHAPES = \
shapes/shapes_ball_physics \
shapes/shapes_basic_shapes \
shapes/shapes_bouncing_ball \
shapes/shapes_bullet_hell \
@ -560,17 +578,23 @@ SHAPES = \
shapes/shapes_easings_box \
shapes/shapes_easings_rectangles \
shapes/shapes_following_eyes \
shapes/shapes_hilbert_curve \
shapes/shapes_kaleidoscope \
shapes/shapes_lines_bezier \
shapes/shapes_lines_drawing \
shapes/shapes_logo_raylib \
shapes/shapes_logo_raylib_anim \
shapes/shapes_math_angle_rotation \
shapes/shapes_math_sine_cosine \
shapes/shapes_mouse_trail \
shapes/shapes_penrose_tile \
shapes/shapes_pie_chart \
shapes/shapes_rectangle_advanced \
shapes/shapes_rectangle_scaling \
shapes/shapes_recursive_tree \
shapes/shapes_ring_drawing \
shapes/shapes_rlgl_color_wheel \
shapes/shapes_rlgl_triangle \
shapes/shapes_rounded_rectangle_drawing \
shapes/shapes_simple_particles \
shapes/shapes_splines_drawing \
@ -583,7 +607,9 @@ TEXTURES = \
textures/textures_background_scrolling \
textures/textures_blend_modes \
textures/textures_bunnymark \
textures/textures_cellular_automata \
textures/textures_fog_of_war \
textures/textures_framebuffer_rendering \
textures/textures_gif_player \
textures/textures_image_channel \
textures/textures_image_drawing \
@ -599,9 +625,11 @@ TEXTURES = \
textures/textures_particles_blending \
textures/textures_polygon_drawing \
textures/textures_raw_data \
textures/textures_screen_buffer \
textures/textures_sprite_animation \
textures/textures_sprite_button \
textures/textures_sprite_explosion \
textures/textures_sprite_stacking \
textures/textures_srcrec_dstrec \
textures/textures_textured_curve \
textures/textures_tiled_drawing \
@ -619,6 +647,7 @@ TEXT = \
text/text_input_box \
text/text_rectangle_bounds \
text/text_sprite_fonts \
text/text_strings_management \
text/text_unicode_emojis \
text/text_unicode_ranges \
text/text_words_alignment \
@ -632,6 +661,8 @@ MODELS = \
models/models_bone_socket \
models/models_box_collisions \
models/models_cubicmap_rendering \
models/models_decals \
models/models_directional_billboard \
models/models_first_person_maze \
models/models_geometric_shapes \
models/models_heightmap_rendering \
@ -655,12 +686,14 @@ SHADERS = \
shaders/shaders_ascii_rendering \
shaders/shaders_basic_lighting \
shaders/shaders_basic_pbr \
shaders/shaders_color_correction \
shaders/shaders_custom_uniform \
shaders/shaders_deferred_rendering \
shaders/shaders_depth_rendering \
shaders/shaders_depth_writing \
shaders/shaders_eratosthenes_sieve \
shaders/shaders_fog_rendering \
shaders/shaders_game_of_life \
shaders/shaders_hot_reloading \
shaders/shaders_hybrid_rendering \
shaders/shaders_julia_set \
@ -692,6 +725,7 @@ AUDIO = \
audio/audio_sound_loading \
audio/audio_sound_multi \
audio/audio_sound_positioning \
audio/audio_spectrum_visualizer \
audio/audio_stream_effects
OTHERS = \

View File

@ -130,7 +130,7 @@ ifeq ($(ANDROID_ARCH),ARM)
CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
endif
ifeq ($(ANDROID_ARCH),ARM64)
CFLAGS = -std=c99 -target aarch64 -mfix-cortex-a53-835769
CFLAGS = -std=c99 -mfix-cortex-a53-835769
endif
# Compilation functions attributes options
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC

View File

@ -30,7 +30,7 @@
# > PLATFORM_ANDROID:
# - Android (ARM, ARM64)
#
# Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
# Copyright (c) 2013-2026 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
@ -208,12 +208,12 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
MAKE = mingw32-make
endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
ifeq ($(OS),Windows_NT)
ifeq ($(PLATFORM_OS),WINDOWS)
MAKE = mingw32-make
else
EMMAKE != type emmake
EMMAKE := $(shell command -v emmake)
ifneq (, $(EMMAKE))
MAKE = emmake make
MAKE = $(EMMAKE) make
else
MAKE = mingw32-make
endif
@ -513,12 +513,13 @@ CORE = \
core/core_basic_screen_manager \
core/core_basic_window \
core/core_clipboard_text \
core/core_compute_hash \
core/core_custom_frame_control \
core/core_custom_logging \
core/core_delta_time \
core/core_directory_files \
core/core_drop_files \
core/core_high_dpi \
core/core_highdpi_demo \
core/core_highdpi_testbed \
core/core_input_actions \
core/core_input_gamepad \
@ -529,6 +530,7 @@ CORE = \
core/core_input_mouse_wheel \
core/core_input_multitouch \
core/core_input_virtual_controls \
core/core_keyboard_testbed \
core/core_monitor_detector \
core/core_random_sequence \
core/core_random_values \
@ -539,6 +541,7 @@ CORE = \
core/core_storage_values \
core/core_text_file_loading \
core/core_undo_redo \
core/core_viewport_scaling \
core/core_vr_simulator \
core/core_window_flags \
core/core_window_letterbox \
@ -546,6 +549,7 @@ CORE = \
core/core_world_screen
SHAPES = \
shapes/shapes_ball_physics \
shapes/shapes_basic_shapes \
shapes/shapes_bouncing_ball \
shapes/shapes_bullet_hell \
@ -560,17 +564,23 @@ SHAPES = \
shapes/shapes_easings_box \
shapes/shapes_easings_rectangles \
shapes/shapes_following_eyes \
shapes/shapes_hilbert_curve \
shapes/shapes_kaleidoscope \
shapes/shapes_lines_bezier \
shapes/shapes_lines_drawing \
shapes/shapes_logo_raylib \
shapes/shapes_logo_raylib_anim \
shapes/shapes_math_angle_rotation \
shapes/shapes_math_sine_cosine \
shapes/shapes_mouse_trail \
shapes/shapes_penrose_tile \
shapes/shapes_pie_chart \
shapes/shapes_rectangle_advanced \
shapes/shapes_rectangle_scaling \
shapes/shapes_recursive_tree \
shapes/shapes_ring_drawing \
shapes/shapes_rlgl_color_wheel \
shapes/shapes_rlgl_triangle \
shapes/shapes_rounded_rectangle_drawing \
shapes/shapes_simple_particles \
shapes/shapes_splines_drawing \
@ -583,7 +593,9 @@ TEXTURES = \
textures/textures_background_scrolling \
textures/textures_blend_modes \
textures/textures_bunnymark \
textures/textures_cellular_automata \
textures/textures_fog_of_war \
textures/textures_framebuffer_rendering \
textures/textures_gif_player \
textures/textures_image_channel \
textures/textures_image_drawing \
@ -599,9 +611,11 @@ TEXTURES = \
textures/textures_particles_blending \
textures/textures_polygon_drawing \
textures/textures_raw_data \
textures/textures_screen_buffer \
textures/textures_sprite_animation \
textures/textures_sprite_button \
textures/textures_sprite_explosion \
textures/textures_sprite_stacking \
textures/textures_srcrec_dstrec \
textures/textures_textured_curve \
textures/textures_tiled_drawing \
@ -619,6 +633,7 @@ TEXT = \
text/text_input_box \
text/text_rectangle_bounds \
text/text_sprite_fonts \
text/text_strings_management \
text/text_unicode_emojis \
text/text_unicode_ranges \
text/text_words_alignment \
@ -632,6 +647,8 @@ MODELS = \
models/models_bone_socket \
models/models_box_collisions \
models/models_cubicmap_rendering \
models/models_decals \
models/models_directional_billboard \
models/models_first_person_maze \
models/models_geometric_shapes \
models/models_heightmap_rendering \
@ -655,12 +672,14 @@ SHADERS = \
shaders/shaders_ascii_rendering \
shaders/shaders_basic_lighting \
shaders/shaders_basic_pbr \
shaders/shaders_color_correction \
shaders/shaders_custom_uniform \
shaders/shaders_deferred_rendering \
shaders/shaders_depth_rendering \
shaders/shaders_depth_writing \
shaders/shaders_eratosthenes_sieve \
shaders/shaders_fog_rendering \
shaders/shaders_game_of_life \
shaders/shaders_hot_reloading \
shaders/shaders_hybrid_rendering \
shaders/shaders_julia_set \
@ -692,6 +711,7 @@ AUDIO = \
audio/audio_sound_loading \
audio/audio_sound_multi \
audio/audio_sound_positioning \
audio/audio_spectrum_visualizer \
audio/audio_stream_effects
# Default target entry
@ -748,6 +768,9 @@ core/core_basic_window: core/core_basic_window.c
core/core_clipboard_text: core/core_clipboard_text.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_compute_hash: core/core_compute_hash.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_custom_frame_control: core/core_custom_frame_control.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -763,7 +786,7 @@ core/core_directory_files: core/core_directory_files.c
core/core_drop_files: core/core_drop_files.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_high_dpi: core/core_high_dpi.c
core/core_highdpi_demo: core/core_highdpi_demo.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_highdpi_testbed: core/core_highdpi_testbed.c
@ -798,6 +821,9 @@ core/core_input_multitouch: core/core_input_multitouch.c
core/core_input_virtual_controls: core/core_input_virtual_controls.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_keyboard_testbed: core/core_keyboard_testbed.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_monitor_detector: core/core_monitor_detector.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -829,6 +855,9 @@ core/core_text_file_loading: core/core_text_file_loading.c
core/core_undo_redo: core/core_undo_redo.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_viewport_scaling: core/core_viewport_scaling.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
core/core_vr_simulator: core/core_vr_simulator.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file core/resources/shaders/glsl100/distortion.fs@resources/shaders/glsl100/distortion.fs
@ -846,6 +875,9 @@ core/core_world_screen: core/core_world_screen.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
# Compile SHAPES examples
shapes/shapes_ball_physics: shapes/shapes_ball_physics.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_basic_shapes: shapes/shapes_basic_shapes.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -888,24 +920,36 @@ shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_hilbert_curve: shapes/shapes_hilbert_curve.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_lines_drawing: shapes/shapes_lines_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_math_angle_rotation: shapes/shapes_math_angle_rotation.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_penrose_tile: shapes/shapes_penrose_tile.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_pie_chart: shapes/shapes_pie_chart.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -921,6 +965,12 @@ shapes/shapes_recursive_tree: shapes/shapes_recursive_tree.c
shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_rlgl_color_wheel: shapes/shapes_rlgl_color_wheel.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_rlgl_triangle: shapes/shapes_rlgl_triangle.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
shapes/shapes_rounded_rectangle_drawing: shapes/shapes_rounded_rectangle_drawing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
@ -956,11 +1006,17 @@ textures/textures_blend_modes: textures/textures_blend_modes.c
textures/textures_bunnymark: textures/textures_bunnymark.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/wabbit_alpha.png@resources/wabbit_alpha.png
--preload-file textures/resources/raybunny.png@resources/raybunny.png
textures/textures_cellular_automata: textures/textures_cellular_automata.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_fog_of_war: textures/textures_fog_of_war.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_framebuffer_rendering: textures/textures_framebuffer_rendering.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_gif_player: textures/textures_gif_player.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/scarfy_run.gif@resources/scarfy_run.gif
@ -1022,6 +1078,9 @@ textures/textures_raw_data: textures/textures_raw_data.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/fudesumi.raw@resources/fudesumi.raw
textures/textures_screen_buffer: textures/textures_screen_buffer.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
textures/textures_sprite_animation: textures/textures_sprite_animation.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/scarfy.png@resources/scarfy.png
@ -1036,6 +1095,10 @@ textures/textures_sprite_explosion: textures/textures_sprite_explosion.c
--preload-file textures/resources/boom.wav@resources/boom.wav \
--preload-file textures/resources/explosion.png@resources/explosion.png
textures/textures_sprite_stacking: textures/textures_sprite_stacking.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/booth.png@resources/booth.png
textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/scarfy.png@resources/scarfy.png
@ -1102,6 +1165,9 @@ text/text_sprite_fonts: text/text_sprite_fonts.c
--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_strings_management: text/text_strings_management.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
text/text_unicode_emojis: text/text_unicode_emojis.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file text/resources/dejavu.fnt@resources/dejavu.fnt \
@ -1156,6 +1222,16 @@ models/models_cubicmap_rendering: models/models_cubicmap_rendering.c
--preload-file models/resources/cubicmap.png@resources/cubicmap.png \
--preload-file models/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png
models/models_decals: models/models_decals.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file models/resources/models/obj/character.obj@resources/models/obj/character.obj \
--preload-file models/resources/models/obj/character_diffuse.png@resources/models/obj/character_diffuse.png \
--preload-file models/resources/raylib_logo.png@resources/raylib_logo.png
models/models_directional_billboard: models/models_directional_billboard.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file models/resources/skillbot.png@resources/skillbot.png
models/models_first_person_maze: models/models_first_person_maze.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file models/resources/cubicmap.png@resources/cubicmap.png \
@ -1261,6 +1337,14 @@ shaders/shaders_basic_pbr: shaders/shaders_basic_pbr.c
--preload-file shaders/resources/road_mra.png@resources/road_mra.png \
--preload-file shaders/resources/road_n.png@resources/road_n.png
shaders/shaders_color_correction: shaders/shaders_color_correction.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/parrots.png@resources/parrots.png \
--preload-file shaders/resources/cat.png@resources/cat.png \
--preload-file shaders/resources/mandrill.png@resources/mandrill.png \
--preload-file shaders/resources/fudesumi.png@resources/fudesumi.png \
--preload-file shaders/resources/shaders/glsl100/color_correction.fs@resources/shaders/glsl100/color_correction.fs
shaders/shaders_custom_uniform: shaders/shaders_custom_uniform.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/models/barracks.obj@resources/models/barracks.obj \
@ -1292,6 +1376,19 @@ shaders/shaders_fog_rendering: shaders/shaders_fog_rendering.c
--preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs \
--preload-file shaders/resources/shaders/glsl100/fog.fs@resources/shaders/glsl100/fog.fs
shaders/shaders_game_of_life: shaders/shaders_game_of_life.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/shaders/glsl100/game_of_life.fs@resources/shaders/glsl100/game_of_life.fs \
--preload-file shaders/resources/game_of_life/r_pentomino.png@resources/game_of_life/r_pentomino.png \
--preload-file shaders/resources/game_of_life/glider.png@resources/game_of_life/glider.png \
--preload-file shaders/resources/game_of_life/acorn.png@resources/game_of_life/acorn.png \
--preload-file shaders/resources/game_of_life/spaceships.png@resources/game_of_life/spaceships.png \
--preload-file shaders/resources/game_of_life/still_lifes.png@resources/game_of_life/still_lifes.png \
--preload-file shaders/resources/game_of_life/oscillators.png@resources/game_of_life/oscillators.png \
--preload-file shaders/resources/game_of_life/puffer_train.png@resources/game_of_life/puffer_train.png \
--preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \
--preload-file shaders/resources/game_of_life/breeder.png@resources/game_of_life/breeder.png
shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file shaders/resources/shaders/glsl100/reload.fs@resources/shaders/glsl100/reload.fs
@ -1444,6 +1541,11 @@ audio/audio_sound_positioning: audio/audio_sound_positioning.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file audio/resources/coin.wav@resources/coin.wav
audio/audio_spectrum_visualizer: audio/audio_spectrum_visualizer.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file audio/resources/shaders/glsl100/fft.fs@resources/shaders/glsl100/fft.fs \
--preload-file audio/resources/country.mp3@resources/country.mp3
audio/audio_stream_effects: audio/audio_stream_effects.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file audio/resources/country.mp3@resources/country.mp3

View File

@ -17,11 +17,11 @@ 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: 187]
## EXAMPLES COLLECTION [TOTAL: 208]
### category: core [45]
### category: core [48]
Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality.
Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality.
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
@ -43,7 +43,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
| [core_3d_camera_free](core/core_3d_camera_free.c) | <img src="core/core_3d_camera_free.png" alt="core_3d_camera_free" width="80"> | ⭐☆☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | <img src="core/core_3d_camera_first_person.png" alt="core_3d_camera_first_person" width="80"> | ⭐⭐☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_3d_camera_split_screen](core/core_3d_camera_split_screen.c) | <img src="core/core_3d_camera_split_screen.png" alt="core_3d_camera_split_screen" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Jeffery Myers](https://github.com/JeffM2501) |
| [core_3d_camera_fps](core/core_3d_camera_fps.c) | <img src="core/core_3d_camera_fps.png" alt="core_3d_camera_fps" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) |
| [core_3d_camera_fps](core/core_3d_camera_fps.c) | <img src="core/core_3d_camera_fps.png" alt="core_3d_camera_fps" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
| [core_3d_picking](core/core_3d_picking.c) | <img src="core/core_3d_picking.png" alt="core_3d_picking" width="80"> | ⭐⭐☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_world_screen](core/core_world_screen.c) | <img src="core/core_world_screen.png" alt="core_world_screen" width="80"> | ⭐⭐☆☆ | 1.3 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_window_flags](core/core_window_flags.c) | <img src="core/core_window_flags.png" alt="core_window_flags" width="80"> | ⭐⭐⭐☆ | 3.5 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
@ -61,17 +61,20 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
| [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) |
| [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐☆☆☆ | 5.0 | 5.0 | [Dalton Overmyer](https://github.com/REDl3east) |
| [core_automation_events](core/core_automation_events.c) | <img src="core/core_automation_events.png" alt="core_automation_events" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_high_dpi](core/core_high_dpi.c) | <img src="core/core_high_dpi.png" alt="core_high_dpi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) |
| [core_highdpi_demo](core/core_highdpi_demo.c) | <img src="core/core_highdpi_demo.png" alt="core_highdpi_demo" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) |
| [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_undo_redo](core/core_undo_redo.c) | <img src="core/core_undo_redo.png" alt="core_undo_redo" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
| [core_viewport_scaling](core/core_viewport_scaling.c) | <img src="core/core_viewport_scaling.png" alt="core_viewport_scaling" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
| [core_input_actions](core/core_input_actions.c) | <img src="core/core_input_actions.png" alt="core_input_actions" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) |
| [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
| [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ananth S](https://github.com/Ananth1839) |
| [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
| [core_keyboard_testbed](core/core_keyboard_testbed.c) | <img src="core/core_keyboard_testbed.png" alt="core_keyboard_testbed" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
### category: shapes [32]
### category: shapes [39]
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
@ -105,11 +108,19 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| [shapes_pie_chart](shapes/shapes_pie_chart.c) | <img src="shapes/shapes_pie_chart.png" alt="shapes_pie_chart" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Gideon Serfontein](https://github.com/GideonSerf) |
| [shapes_kaleidoscope](shapes/shapes_kaleidoscope.c) | <img src="shapes/shapes_kaleidoscope.png" alt="shapes_kaleidoscope" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
| [shapes_clock_of_clocks](shapes/shapes_clock_of_clocks.c) | <img src="shapes/shapes_clock_of_clocks.png" alt="shapes_clock_of_clocks" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
| [shapes_math_sine_cosine](shapes/shapes_math_sine_cosine.c) | <img src="shapes/shapes_math_sine_cosine.png" alt="shapes_math_sine_cosine" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
| [shapes_mouse_trail](shapes/shapes_mouse_trail.c) | <img src="shapes/shapes_mouse_trail.png" alt="shapes_mouse_trail" width="80"> | ⭐☆☆☆ | 5.6 | 5.6-dev | [Balamurugan R](https://github.com/Bala050814) |
| [shapes_simple_particles](shapes/shapes_simple_particles.c) | <img src="shapes/shapes_simple_particles.png" alt="shapes_simple_particles" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
| [shapes_starfield_effect](shapes/shapes_starfield_effect.c) | <img src="shapes/shapes_starfield_effect.png" alt="shapes_starfield_effect" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
| [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | <img src="shapes/shapes_lines_drawing.png" alt="shapes_lines_drawing" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
| [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | <img src="shapes/shapes_math_angle_rotation.png" alt="shapes_math_angle_rotation" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6 | [Kris](https://github.com/krispy-snacc) |
| [shapes_rlgl_color_wheel](shapes/shapes_rlgl_color_wheel.c) | <img src="shapes/shapes_rlgl_color_wheel.png" alt="shapes_rlgl_color_wheel" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | <img src="shapes/shapes_hilbert_curve.png" alt="shapes_hilbert_curve" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
### category: textures [26]
### category: textures [30]
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
@ -140,9 +151,13 @@ Examples using raylib textures functionality, including image/textures loading/g
| [textures_image_kernel](textures/textures_image_kernel.c) | <img src="textures/textures_image_kernel.png" alt="textures_image_kernel" width="80"> | ⭐⭐⭐⭐️ | 1.3 | 1.3 | [Karim Salem](https://github.com/kimo-s) |
| [textures_image_channel](textures/textures_image_channel.c) | <img src="textures/textures_image_channel.png" alt="textures_image_channel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Bruno Cabral](https://github.com/brccabral) |
| [textures_image_rotate](textures/textures_image_rotate.c) | <img src="textures/textures_image_rotate.png" alt="textures_image_rotate" width="80"> | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [textures_screen_buffer](textures/textures_screen_buffer.c) | <img src="textures/textures_screen_buffer.png" alt="textures_screen_buffer" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
| [textures_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) |
| [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
| [textures_framebuffer_rendering](textures/textures_framebuffer_rendering.c) | <img src="textures/textures_framebuffer_rendering.png" alt="textures_framebuffer_rendering" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jack Boakes](https://github.com/jackboakes) |
### category: text [15]
### category: text [16]
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
@ -163,8 +178,9 @@ Examples using raylib text functionality, including sprite fonts loading/generat
| [text_codepoints_loading](text/text_codepoints_loading.c) | <img src="text/text_codepoints_loading.png" alt="text_codepoints_loading" width="80"> | ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
| [text_inline_styling](text/text_inline_styling.c) | <img src="text/text_inline_styling.png" alt="text_inline_styling" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Wagner Barongello](https://github.com/SultansOfCode) |
| [text_words_alignment](text/text_words_alignment.c) | <img src="text/text_words_alignment.png" alt="text_words_alignment" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
| [text_strings_management](text/text_strings_management.c) | <img src="text/text_strings_management.png" alt="text_strings_management" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
### category: models [25]
### category: models [27]
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
@ -195,8 +211,10 @@ Examples using raylib models functionality, including models loading/generation
| [models_tesseract_view](models/models_tesseract_view.c) | <img src="models/models_tesseract_view.png" alt="models_tesseract_view" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) |
| [models_basic_voxel](models/models_basic_voxel.c) | <img src="models/models_basic_voxel.png" alt="models_basic_voxel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) |
| [models_rotating_cube](models/models_rotating_cube.c) | <img src="models/models_rotating_cube.png" alt="models_rotating_cube" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
| [models_decals](models/models_decals.c) | <img src="models/models_decals.png" alt="models_decals" width="80"> | ⭐⭐⭐⭐️ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
| [models_directional_billboard](models/models_directional_billboard.c) | <img src="models/models_directional_billboard.png" alt="models_directional_billboard" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
### category: shaders [31]
### category: shaders [33]
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module.
@ -214,6 +232,8 @@ Examples using raylib shaders functionality, including shaders loading, paramete
| [shaders_texture_outline](shaders/shaders_texture_outline.c) | <img src="shaders/shaders_texture_outline.png" alt="shaders_texture_outline" width="80"> | ⭐⭐⭐☆ | 4.0 | 4.0 | [Serenity Skiff](https://github.com/GoldenThumbs) |
| [shaders_texture_waves](shaders/shaders_texture_waves.c) | <img src="shaders/shaders_texture_waves.png" alt="shaders_texture_waves" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) |
| [shaders_julia_set](shaders/shaders_julia_set.c) | <img src="shaders/shaders_julia_set.png" alt="shaders_julia_set" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [Josh Colclough](https://github.com/joshcol9232) |
| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | <img src="shaders/shaders_mandelbrot_set.png" alt="shaders_mandelbrot_set" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
| [shaders_color_correction](shaders/shaders_color_correction.c) | <img src="shaders/shaders_color_correction.png" alt="shaders_color_correction" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
| [shaders_eratosthenes_sieve](shaders/shaders_eratosthenes_sieve.c) | <img src="shaders/shaders_eratosthenes_sieve.png" alt="shaders_eratosthenes_sieve" width="80"> | ⭐⭐⭐☆ | 2.5 | 4.0 | [ProfJski](https://github.com/ProfJski) |
| [shaders_fog_rendering](shaders/shaders_fog_rendering.c) | <img src="shaders/shaders_fog_rendering.png" alt="shaders_fog_rendering" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
| [shaders_simple_mask](shaders/shaders_simple_mask.c) | <img src="shaders/shaders_simple_mask.png" alt="shaders_simple_mask" width="80"> | ⭐⭐☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
@ -232,9 +252,9 @@ Examples using raylib shaders functionality, including shaders loading, paramete
| [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) | <img src="shaders/shaders_lightmap_rendering.png" alt="shaders_lightmap_rendering" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
| [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) | <img src="shaders/shaders_rounded_rectangle.png" alt="shaders_rounded_rectangle" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) |
| [shaders_depth_rendering](shaders/shaders_depth_rendering.c) | <img src="shaders/shaders_depth_rendering.png" alt="shaders_depth_rendering" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) |
| [shaders_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | <img src="shaders/shaders_mandelbrot_set.png" alt="shaders_mandelbrot_set" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
| [shaders_game_of_life](shaders/shaders_game_of_life.c) | <img src="shaders/shaders_game_of_life.png" alt="shaders_game_of_life" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
### category: audio [8]
### category: audio [9]
Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib.
@ -248,6 +268,7 @@ Examples using raylib audio functionality, including sound/music loading and pla
| [audio_stream_effects](audio/audio_stream_effects.c) | <img src="audio/audio_stream_effects.png" alt="audio_stream_effects" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
| [audio_sound_multi](audio/audio_sound_multi.c) | <img src="audio/audio_sound_multi.png" alt="audio_sound_multi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [Jeffery Myers](https://github.com/JeffM2501) |
| [audio_sound_positioning](audio/audio_sound_positioning.c) | <img src="audio/audio_sound_positioning.png" alt="audio_sound_positioning" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | <img src="audio/audio_spectrum_visualizer.png" alt="audio_spectrum_visualizer" width="80"> | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) |
### category: others [6]

View File

@ -36,6 +36,12 @@ int main(void)
float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f]
bool pause = false; // Music playing paused
float pan = 0.0f; // Default audio pan center [-1.0f..1.0f]
SetMusicPan(music, pan);
float volume = 0.8f; // Default audio volume [0.0f..1.0f]
SetMusicVolume(music, volume);
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
//--------------------------------------------------------------------------------------
@ -62,6 +68,34 @@ int main(void)
else ResumeMusicStream(music);
}
// Set audio pan
if (IsKeyDown(KEY_LEFT))
{
pan -= 0.05f;
if (pan < -1.0f) pan = -1.0f;
SetMusicPan(music, pan);
}
else if (IsKeyDown(KEY_RIGHT))
{
pan += 0.05f;
if (pan > 1.0f) pan = 1.0f;
SetMusicPan(music, pan);
}
// Set audio volume
if (IsKeyDown(KEY_DOWN))
{
volume -= 0.05f;
if (volume < 0.0f) volume = 0.0f;
SetMusicVolume(music, volume);
}
else if (IsKeyDown(KEY_UP))
{
volume += 0.05f;
if (volume > 1.0f) volume = 1.0f;
SetMusicVolume(music, volume);
}
// Get normalized time played for current music stream
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music);
@ -76,6 +110,11 @@ int main(void)
DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE);
DrawRectangle(300, 100, 200, 12, LIGHTGRAY);
DrawRectangleLines(300, 100, 200, 12, GRAY);
DrawRectangle((int)(300 + (pan + 1.0f)/2.0f*200 - 5), 92, 10, 28, DARKGRAY);
DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON);
DrawRectangleLines(200, 200, 400, 12, GRAY);
@ -83,6 +122,11 @@ int main(void)
DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY);
DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY);
DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN);
DrawRectangle(300, 360, 200, 12, LIGHTGRAY);
DrawRectangleLines(300, 360, 200, 12, GRAY);
DrawRectangle((int)(300 + volume*200 - 5), 352, 10, 28, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}

View File

@ -69,6 +69,7 @@ int main(void)
};
SetSoundPosition(camera, sound, spherePos, 20.0f);
if (!IsSoundPlaying(sound)) PlaySound(sound);
//----------------------------------------------------------------------------------
@ -94,6 +95,8 @@ int main(void)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------

View File

@ -0,0 +1,285 @@
/*******************************************************************************************
*
* raylib [audio] example - spectrum visualizer
*
* Example complexity rating: [] 3/4
*
* Example originally created with raylib 6.0, last time updated with raylib 5.6-dev
*
* Inspired by Inigo Quilez's https://www.shadertoy.com/
* Resources/specification: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8
*
* Example created by created by IANN (@meisei4) 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 IANN (@meisei4)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330
#else // PLATFORM_ANDROID, PLATFORM_WEB
#define GLSL_VERSION 100
#endif
#define MONO 1
#define SAMPLE_RATE 44100
#define SAMPLE_RATE_F 44100.0f
#define FFT_WINDOW_SIZE 1024
#define BUFFER_SIZE 512
#define PER_SAMPLE_BIT_DEPTH 16
#define AUDIO_STREAM_RING_BUFFER_SIZE (FFT_WINDOW_SIZE*2)
#define EFFECTIVE_SAMPLE_RATE (SAMPLE_RATE_F*0.5f)
#define WINDOW_TIME ((double)FFT_WINDOW_SIZE/(double)EFFECTIVE_SAMPLE_RATE)
#define FFT_HISTORICAL_SMOOTHING_DUR 2.0f
#define MIN_DECIBELS (-100.0f) // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/minDecibels
#define MAX_DECIBELS (-30.0f) // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/maxDecibels
#define INVERSE_DECIBEL_RANGE (1.0f/(MAX_DECIBELS - MIN_DECIBELS))
#define DB_TO_LINEAR_SCALE (20.0f/2.302585092994046f)
#define SMOOTHING_TIME_CONSTANT 0.8f // https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/smoothingTimeConstant
#define TEXTURE_HEIGHT 1
#define FFT_ROW 0
#define UNUSED_CHANNEL 0.0f
typedef struct FFTComplex { float real, imaginary; } FFTComplex;
typedef struct FFTData {
FFTComplex *spectrum;
FFTComplex *workBuffer;
float *prevMagnitudes;
float (*fftHistory)[BUFFER_SIZE];
int fftHistoryLen;
int historyPos;
double lastFftTime;
float tapbackPos;
} FFTData;
static void CaptureFrame(FFTData *fftData, const float *audioSamples);
static void RenderFrame(const FFTData *fftData, Image *fftImage);
static void CooleyTukeyFFTSlow(FFTComplex *spectrum, int n);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//----------------------------------------------------------------------------------- ---
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - spectrum visualizer");
Image fftImage = GenImageColor(BUFFER_SIZE, TEXTURE_HEIGHT, WHITE);
Texture2D fftTexture = LoadTextureFromImage(fftImage);
RenderTexture2D bufferA = LoadRenderTexture(screenWidth, screenHeight);
Vector2 iResolution = { (float)screenWidth, (float)screenHeight };
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/fft.fs", GLSL_VERSION));
int iResolutionLocation = GetShaderLocation(shader, "iResolution");
int iChannel0Location = GetShaderLocation(shader, "iChannel0");
SetShaderValue(shader, iResolutionLocation, &iResolution, SHADER_UNIFORM_VEC2);
SetShaderValueTexture(shader, iChannel0Location, fftTexture);
InitAudioDevice();
SetAudioStreamBufferSizeDefault(AUDIO_STREAM_RING_BUFFER_SIZE);
// WARNING: Memory out-of-bounds on PLATFORM_WEB
Wave wav = LoadWave("resources/country.mp3");
WaveFormat(&wav, SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO);
AudioStream audioStream = LoadAudioStream(SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO);
PlayAudioStream(audioStream);
int fftHistoryLen = (int)ceilf(FFT_HISTORICAL_SMOOTHING_DUR/WINDOW_TIME) + 1;
FFTData fft = {
.spectrum = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE),
.workBuffer = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE),
.prevMagnitudes = RL_CALLOC(BUFFER_SIZE, sizeof(float)),
.fftHistory = RL_CALLOC(fftHistoryLen, sizeof(float[BUFFER_SIZE])),
.fftHistoryLen = fftHistoryLen,
.historyPos = 0,
.lastFftTime = 0.0,
.tapbackPos = 0.01f
};
int wavCursor = 0;
const short *wavPCM16 = wav.data;
short chunkSamples[AUDIO_STREAM_RING_BUFFER_SIZE] = { 0 };
float audioSamples[FFT_WINDOW_SIZE] = { 0 };
SetTargetFPS(60);
//----------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
while (IsAudioStreamProcessed(audioStream))
{
for (int i = 0; i < AUDIO_STREAM_RING_BUFFER_SIZE; i++)
{
int left = (wav.channels == 2)? wavPCM16[wavCursor*2 + 0] : wavPCM16[wavCursor];
int right = (wav.channels == 2)? wavPCM16[wavCursor*2 + 1] : left;
chunkSamples[i] = (short)((left + right)/2);
if (++wavCursor >= wav.frameCount) wavCursor = 0;
}
UpdateAudioStream(audioStream, chunkSamples, AUDIO_STREAM_RING_BUFFER_SIZE);
for (int i = 0; i < FFT_WINDOW_SIZE; i++) audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f;
}
CaptureFrame(&fft, audioSamples);
RenderFrame(&fft, &fftImage);
UpdateTexture(fftTexture, fftImage.data);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginShaderMode(shader);
SetShaderValueTexture(shader, iChannel0Location, fftTexture);
DrawTextureRec(bufferA.texture,
(Rectangle){ 0, 0, (float)screenWidth, (float)-screenHeight },
(Vector2){ 0, 0 }, WHITE);
EndShaderMode();
EndDrawing();
//------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadShader(shader);
UnloadRenderTexture(bufferA);
UnloadTexture(fftTexture);
UnloadImage(fftImage);
UnloadAudioStream(audioStream);
UnloadWave(wav);
CloseAudioDevice();
RL_FREE(fft.spectrum);
RL_FREE(fft.workBuffer);
RL_FREE(fft.prevMagnitudes);
RL_FREE(fft.fftHistory);
CloseWindow(); // Close window and OpenGL context
//----------------------------------------------------------------------------------
return 0;
}
// CooleyTukey FFT https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Data_reordering,_bit_reversal,_and_in-place_algorithms
static void CooleyTukeyFFTSlow(FFTComplex *spectrum, int n)
{
int j = 0;
for (int i = 1; i < n - 1; i++)
{
int bit = n >> 1;
while (j >= bit)
{
j -= bit;
bit >>= 1;
}
j += bit;
if (i < j)
{
FFTComplex temp = spectrum[i];
spectrum[i] = spectrum[j];
spectrum[j] = temp;
}
}
for (int len = 2; len <= n; len <<= 1)
{
float angle = -2.0f*PI/len;
FFTComplex twiddleUnit = { cosf(angle), sinf(angle) };
for (int i = 0; i < n; i += len)
{
FFTComplex twiddleCurrent = { 1.0f, 0.0f };
for (int j = 0; j < len/2; j++)
{
FFTComplex even = spectrum[i + j];
FFTComplex odd = spectrum[i + j + len/2];
FFTComplex twiddledOdd = {
odd.real*twiddleCurrent.real - odd.imaginary*twiddleCurrent.imaginary,
odd.real*twiddleCurrent.imaginary + odd.imaginary*twiddleCurrent.real
};
spectrum[i + j].real = even.real + twiddledOdd.real;
spectrum[i + j].imaginary = even.imaginary + twiddledOdd.imaginary;
spectrum[i + j + len/2].real = even.real - twiddledOdd.real;
spectrum[i + j + len/2].imaginary = even.imaginary - twiddledOdd.imaginary;
float twiddleRealNext = twiddleCurrent.real*twiddleUnit.real - twiddleCurrent.imaginary*twiddleUnit.imaginary;
twiddleCurrent.imaginary = twiddleCurrent.real*twiddleUnit.imaginary + twiddleCurrent.imaginary*twiddleUnit.real;
twiddleCurrent.real = twiddleRealNext;
}
}
}
}
static void CaptureFrame(FFTData *fftData, const float *audioSamples)
{
for (int i = 0; i < FFT_WINDOW_SIZE; i++)
{
float x = (2.0f*PI*i)/(FFT_WINDOW_SIZE - 1.0f);
float blackmanWeight = 0.42f - 0.5f*cosf(x) + 0.08f*cosf(2.0f*x); // https://en.wikipedia.org/wiki/Window_function#Blackman_window
fftData->workBuffer[i].real = audioSamples[i]*blackmanWeight;
fftData->workBuffer[i].imaginary = 0.0f;
}
CooleyTukeyFFTSlow(fftData->workBuffer, FFT_WINDOW_SIZE);
memcpy(fftData->spectrum, fftData->workBuffer, sizeof(FFTComplex)*FFT_WINDOW_SIZE);
float smoothedSpectrum[BUFFER_SIZE];
for (int bin = 0; bin < BUFFER_SIZE; bin++)
{
float re = fftData->workBuffer[bin].real;
float im = fftData->workBuffer[bin].imaginary;
float linearMagnitude = sqrtf(re*re + im*im)/FFT_WINDOW_SIZE;
float smoothedMagnitude = SMOOTHING_TIME_CONSTANT*fftData->prevMagnitudes[bin] + (1.0f - SMOOTHING_TIME_CONSTANT)*linearMagnitude;
fftData->prevMagnitudes[bin] = smoothedMagnitude;
float db = logf(fmaxf(smoothedMagnitude, 1e-40f))*DB_TO_LINEAR_SCALE;
float normalized = (db - MIN_DECIBELS)*INVERSE_DECIBEL_RANGE;
smoothedSpectrum[bin] = Clamp(normalized, 0.0f, 1.0f);
}
fftData->lastFftTime = GetTime();
memcpy(fftData->fftHistory[fftData->historyPos], smoothedSpectrum, sizeof(smoothedSpectrum));
fftData->historyPos = (fftData->historyPos + 1)%fftData->fftHistoryLen;
}
static void RenderFrame(const FFTData *fftData, Image *fftImage)
{
double framesSinceTapback = floor(fftData->tapbackPos/WINDOW_TIME);
framesSinceTapback = Clamp(framesSinceTapback, 0.0, fftData->fftHistoryLen - 1);
int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback)%fftData->fftHistoryLen;
if (historyPosition < 0) historyPosition += fftData->fftHistoryLen;
const float *amplitude = fftData->fftHistory[historyPosition];
for (int bin = 0; bin < BUFFER_SIZE; bin++) ImageDrawPixel(fftImage, bin, FFT_ROW, ColorFromNormalized((Vector4){ amplitude[bin], UNUSED_CHANNEL, UNUSED_CHANNEL, UNUSED_CHANNEL }));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,37 @@
#version 100
precision mediump float;
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
// Input uniform values
uniform vec2 iResolution;
uniform sampler2D iChannel0;
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
const float FFT_ROW = 0.0;
const float NUM_OF_BINS = 512.0;
void main()
{
vec2 fragCoord = fragTexCoord*iResolution;
float cellWidth = iResolution.x/NUM_OF_BINS;
float binIndex = floor(fragCoord.x/cellWidth);
float localX = mod(fragCoord.x, cellWidth);
float barWidth = cellWidth - 1.0;
vec4 color = WHITE;
if (localX <= barWidth)
{
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
if (fragTexCoord.y < amplitude) color = BLACK;
}
gl_FragColor = color;
}

View File

@ -0,0 +1,35 @@
#version 120
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
// Input uniform values
uniform vec2 iResolution;
uniform sampler2D iChannel0;
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
const float FFT_ROW = 0.0;
const float NUM_OF_BINS = 512.0;
void main()
{
vec2 fragCoord = fragTexCoord*iResolution;
float cellWidth = iResolution.x/NUM_OF_BINS;
float binIndex = floor(fragCoord.x/cellWidth);
float localX = mod(fragCoord.x, cellWidth);
float barWidth = cellWidth - 1.0;
vec4 color = WHITE;
if (localX <= barWidth)
{
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
if (fragTexCoord.y < amplitude) color = BLACK;
}
gl_FragColor = color;
}

View File

@ -0,0 +1,35 @@
#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
out vec4 finalColor;
uniform vec2 iResolution;
uniform sampler2D iChannel0;
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
const float FFT_ROW = 0.0;
const float NUM_OF_BINS = 512.0;
void main()
{
vec2 fragCoord = fragTexCoord*iResolution;
float cellWidth = iResolution.x/NUM_OF_BINS;
float binIndex = floor(fragCoord.x/cellWidth);
float localX = mod(fragCoord.x, cellWidth);
float barWidth = cellWidth - 1.0;
vec4 color = WHITE;
if (localX <= barWidth)
{
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
if (fragTexCoord.y < amplitude) color = BLACK;
}
finalColor = color;
}

View File

@ -125,8 +125,8 @@ int main(void)
DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f));
DrawRectangleLines( 10, 10, 250, 113, BLUE);
DrawText("Free 2d camera controls:", 20, 20, 10, BLACK);
DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY);
DrawText("Free 2D camera controls:", 20, 20, 10, BLACK);
DrawText("- Right/Left to move player", 40, 40, 10, DARKGRAY);
DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY);
DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY);
DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -23,7 +23,7 @@
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main ()
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
@ -93,6 +93,7 @@ int main ()
// under the cursor to the screen space point under the cursor at any zoom
camera.target = mouseWorldPos;
}
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
{
// Zoom increment
@ -110,7 +111,6 @@ int main ()
ClearBackground(RAYWHITE);
BeginMode2D(camera);
// Draw the 3d grid, rotated 90 degrees and centered around 0,0
// just so we have something in the XY plane
rlPushMatrix();
@ -121,7 +121,6 @@ int main ()
// Draw a reference circle
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 50, MAROON);
EndMode2D();
// Draw mouse reference
@ -142,5 +141,6 @@ int main ()
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -226,10 +226,10 @@ void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envI
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera);
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera);
if (max.x < width) camera->offset.x = width - (max.x - width/2);
if (max.y < height) camera->offset.y = height - (max.y - height/2);
if (min.x > 0) camera->offset.x = width/2 - min.x;
if (min.y > 0) camera->offset.y = height/2 - min.y;
if (max.x < width) camera->offset.x = width - (max.x - (float)width/2);
if (max.y < height) camera->offset.y = height - (max.y - (float)height/2);
if (min.x > 0) camera->offset.x = (float)width/2 - min.x;
if (min.y > 0) camera->offset.y = (float)height/2 - min.y;
}
void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)

View File

@ -6,12 +6,12 @@
*
* 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 contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2025 Agnis Aldins (@nezvers)
* Copyright (c) 2025 Agnis Aldiņš (@nezvers)
*
********************************************************************************************/

View File

@ -225,10 +225,10 @@ int main(void)
Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera);
Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera);
if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - screenWidth/2);
if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - screenHeight/2);
if (min.x > 0) camera.offset.x = screenWidth/2 - min.x;
if (min.y > 0) camera.offset.y = screenHeight/2 - min.y;
if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - (float)screenWidth/2);
if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - (float)screenHeight/2);
if (min.x > 0) camera.offset.x = (float)screenWidth/2 - min.x;
if (min.y > 0) camera.offset.y = (float)screenHeight/2 - min.y;
//----------------------------------------------------------------------------------
// Events management

View File

@ -2,22 +2,25 @@
*
* raylib [core] example - clipboard text
*
* Example complexity rating: [] 1/4
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
*
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
* Example contributed by Ananth S (@Ananth1839) 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 Robin (@RobinsAviary)
* Copyright (c) 2025 Ananth S (@Ananth1839)
*
********************************************************************************************/
#include "raylib.h"
#include <stdio.h>
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
#define MAX_TEXT_SAMPLES 5
//------------------------------------------------------------------------------------
// Program main entry point
@ -31,28 +34,32 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [core] example - clipboard text");
// Define some sample texts
const char *sampleTexts[MAX_TEXT_SAMPLES] = {
"Hello from raylib!",
"The quick brown fox jumps over the lazy dog",
"Clipboard operations are useful!",
"raylib is a simple and easy-to-use library",
"Copy and paste me!"
};
const char *clipboardText = NULL;
char inputBuffer[256] = "Hello from raylib!"; // Random initial string
// List of text the user can switch through and copy
const char* copyableText[] = {"raylib is fun", "hello, clipboard!", "potato chips"};
// UI required variables
bool textBoxEditMode = false;
unsigned int textIndex = 0;
bool btnCutPressed = false;
bool btnCopyPressed = false;
bool btnPastePressed = false;
bool btnClearPressed = false;
bool btnRandomPressed = false;
const char* popupText = NULL;
// Set UI style
GuiSetStyle(DEFAULT, TEXT_SIZE, 20);
GuiSetIconScale(2);
// Initialize timers
// The amount of time the pop-up text is on screen, before fading
const float maxTime = 3.0f;
float textTimer = 0.0f;
// The length of time text is offset
const float animMaxTime = 0.1f;
float pasteAnim = 0.0f;
float copyAnim = 0.0f;
int copyAnimMult = 1;
float textAnim = 0.0f;
float textAlpha = 0.0f;
// Offset amount for animations
const int offsetAmount = -4;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
@ -60,95 +67,55 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
// Check if the user has pressed the copy/paste key combinations
bool pastePressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_V));
bool copyPressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C));
// Update animation timers
if (textTimer > 0) textTimer -= GetFrameTime();
if (pasteAnim > 0) pasteAnim -= GetFrameTime();
if (copyAnim > 0) copyAnim -= GetFrameTime();
if (textAnim > 0) textAnim -= GetFrameTime();
// React to the user pressing paste
if (pastePressed)
// Handle button interactions
if (btnCutPressed)
{
// Most operating systems hide this information until the user presses Ctrl-V on the window.
// Check to see if the clipboard contains an image
// This function does nothing outside of Windows, as it directly calls the Windows API
Image image = GetClipboardImage();
if (IsImageValid(image))
{
// Unload the image
UnloadImage(image);
// Update visuals
popupText = "clipboard contains image";
}
else
{
// Get text from the user's clipboard
SetClipboardText(inputBuffer);
clipboardText = GetClipboardText();
// Update visuals
popupText = "text pasted";
pasteAnim = animMaxTime;
inputBuffer[0] = '\0'; // Quick solution to clear text
//memset(inputBuffer, 0, 256); // Clear full buffer properly
}
// Reset animation values
textTimer = maxTime;
textAnim = animMaxTime;
textAlpha = 1;
if (btnCopyPressed)
{
SetClipboardText(inputBuffer); // Copy text to clipboard
clipboardText = GetClipboardText(); // Get text from clipboard
}
// React to the user pressing copy
if (copyPressed)
if (btnPastePressed)
{
// Set the text on the user's clipboard
SetClipboardText(copyableText[textIndex]);
// Reset values
textTimer = maxTime;
textAnim = animMaxTime;
copyAnim = animMaxTime;
copyAnimMult = 1;
textAlpha = 1;
// Update the text that pops up at the bottom of the screen
popupText = "text copied";
// Paste text from clipboard
clipboardText = GetClipboardText();
if (clipboardText != NULL) TextCopy(inputBuffer, clipboardText);
}
// Switch to the next item in the list when the user presses up
if (IsKeyPressed(KEY_UP))
if (btnClearPressed)
{
// Reset animation
copyAnim = animMaxTime;
copyAnimMult = 1;
textIndex += 1;
if (textIndex >= sizeof(copyableText) / sizeof(const char*)) // Length of array
{
// Loop back to the other end
textIndex = 0;
}
inputBuffer[0] = '\0'; // Quick solution to clear text
//memset(inputBuffer, 0, 256); // Clear full buffer properly
}
// Switch to the previous item in the list when the user presses down
if (IsKeyPressed(KEY_DOWN))
if (btnRandomPressed)
{
// Reset animation
copyAnim = animMaxTime;
copyAnimMult = -1;
if (textIndex == 0)
{
// Loop back to the other end
textIndex = (sizeof(copyableText) / sizeof(const char*)) - 1; // Length of array minus one
// Get random text from sample list
TextCopy(inputBuffer, sampleTexts[GetRandomValue(0, MAX_TEXT_SAMPLES - 1)]);
}
else
// Quick cut/copy/paste with keyboard shortcuts
if (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL))
{
textIndex -= 1;
if (IsKeyPressed(KEY_X))
{
SetClipboardText(inputBuffer);
inputBuffer[0] = '\0'; // Quick solution to clear text
}
if (IsKeyPressed(KEY_C)) SetClipboardText(inputBuffer);
if (IsKeyPressed(KEY_V))
{
clipboardText = GetClipboardText();
if (clipboardText != NULL) TextCopy(inputBuffer, clipboardText);
}
}
//----------------------------------------------------------------------------------
@ -159,41 +126,30 @@ int main(void)
ClearBackground(RAYWHITE);
// Draw the user's pasted text, if there is any yet
if (clipboardText)
{
// Offset animation
int offset = 0;
if (pasteAnim > 0) offset = offsetAmount;
// Draw instructions
GuiLabel((Rectangle){ 50, 20, 700, 36 }, "Use the BUTTONS or KEY SHORTCUTS:");
DrawText("[CTRL+X] - CUT | [CTRL+C] COPY | [CTRL+V] | PASTE", 50, 60, 20, MAROON);
// Draw the pasted text
DrawText("pasted clipboard:", 10, 10 + offset, 20, DARKGREEN);
DrawText(clipboardText, 10, 30 + offset, 20, DARKGRAY);
}
// Draw text box
if (GuiTextBox((Rectangle){ 50, 120, 652, 40 }, inputBuffer, 256, textBoxEditMode)) textBoxEditMode = !textBoxEditMode;
// Offset animation
int textOffset = 0;
if (copyAnim > 0) textOffset = offsetAmount;
// Random text button
btnRandomPressed = GuiButton((Rectangle){ 50 + 652 + 8, 120, 40, 40 }, "#77#");
// Draw copyable text and controls
DrawText(copyableText[textIndex], 10, 330 + (textOffset * copyAnimMult), 20, MAROON);
DrawText("up/down to change string, ctrl-c to copy, ctrl-v to paste", 10, 355, 20, DARKGRAY);
// Draw buttons
btnCutPressed = GuiButton((Rectangle){ 50, 180, 158, 40 }, "#17#CUT");
btnCopyPressed = GuiButton((Rectangle){ 50 + 165, 180, 158, 40 }, "#16#COPY");
btnPastePressed = GuiButton((Rectangle){ 50 + 165*2, 180, 158, 40 }, "#18#PASTE");
btnClearPressed = GuiButton((Rectangle){ 50 + 165*3, 180, 158, 40 }, "#143#CLEAR");
// Alpha / Offset animation
if (textAlpha > 0)
{
// Offset animation
int offset = 0;
if (textAnim > 0) offset = offsetAmount;
// Draw pop up text
DrawText(popupText, 10, 425 + offset, 20, ColorAlpha(DARKGREEN, textAlpha));
// Fade-out animation
if (textTimer < 0)
{
textAlpha -= GetFrameTime();
}
}
// Draw clipboard status
GuiSetState(STATE_DISABLED);
GuiLabel((Rectangle){ 50, 260, 700, 40 }, "Clipboard current text data:");
GuiSetStyle(TEXTBOX, TEXT_READONLY, 1);
GuiTextBox((Rectangle){ 50, 300, 700, 40 }, (char *)clipboardText, 256, false);
GuiSetStyle(TEXTBOX, TEXT_READONLY, 0);
GuiLabel((Rectangle){ 50, 360, 700, 40 }, "Try copying text from other applications and pasting here!");
GuiSetState(STATE_NORMAL);
EndDrawing();
//----------------------------------------------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -0,0 +1,143 @@
/*******************************************************************************************
*
* raylib [core] example - compute hash
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
static char *GetDataAsHexText(const unsigned int *data, int dataSize);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - compute hash");
// UI controls variables
char textInput[96] = "The quick brown fox jumps over the lazy dog.";
bool textBoxEditMode = false;
bool btnComputeHashes = false;
// Data hash values
unsigned int hashCRC32 = 0;
unsigned int *hashMD5 = NULL;
unsigned int *hashSHA1 = NULL;
unsigned int *hashSHA256 = NULL;
// Base64 encoded data
char *base64Text = NULL;
int base64TextSize = 0;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (btnComputeHashes)
{
int textInputLen = strlen(textInput);
// Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
base64Text = EncodeDataBase64((unsigned char *)textInput, textInputLen, &base64TextSize);
hashCRC32 = ComputeCRC32((unsigned char *)textInput, textInputLen); // Compute CRC32 hash code (4 bytes)
hashMD5 = ComputeMD5((unsigned char *)textInput, textInputLen); // Compute MD5 hash code, returns static int[4] (16 bytes)
hashSHA1 = ComputeSHA1((unsigned char *)textInput, textInputLen); // Compute SHA1 hash code, returns static int[5] (20 bytes)
hashSHA256 = ComputeSHA256((unsigned char *)textInput, textInputLen); // Compute SHA256 hash code, returns static int[8] (32 bytes)
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
GuiSetStyle(DEFAULT, TEXT_SIZE, 20);
GuiSetStyle(DEFAULT, TEXT_SPACING, 2);
GuiLabel((Rectangle){ 40, 26, 720, 32 }, "INPUT DATA (TEXT):");
GuiSetStyle(DEFAULT, TEXT_SPACING, 1);
GuiSetStyle(DEFAULT, TEXT_SIZE, 10);
if (GuiTextBox((Rectangle){ 40, 64, 720, 32 }, textInput, 95, textBoxEditMode)) textBoxEditMode = !textBoxEditMode;
btnComputeHashes = GuiButton((Rectangle){ 40, 64 + 40, 720, 32 }, "COMPUTE INPUT DATA HASHES");
GuiSetStyle(DEFAULT, TEXT_SIZE, 20);
GuiSetStyle(DEFAULT, TEXT_SPACING, 2);
GuiLabel((Rectangle){ 40, 160, 720, 32 }, "INPUT DATA HASH VALUES:");
GuiSetStyle(DEFAULT, TEXT_SPACING, 1);
GuiSetStyle(DEFAULT, TEXT_SIZE, 10);
GuiSetStyle(TEXTBOX, TEXT_READONLY, 1);
GuiLabel((Rectangle){ 40, 200, 120, 32 }, "CRC32 [32 bit]:");
GuiTextBox((Rectangle){ 40 + 120, 200, 720 - 120, 32 }, GetDataAsHexText(&hashCRC32, 1), 120, false);
GuiLabel((Rectangle){ 40, 200 + 36, 120, 32 }, "MD5 [128 bit]:");
GuiTextBox((Rectangle){ 40 + 120, 200 + 36, 720 - 120, 32 }, GetDataAsHexText(hashMD5, 4), 120, false);
GuiLabel((Rectangle){ 40, 200 + 36*2, 120, 32 }, "SHA1 [160 bit]:");
GuiTextBox((Rectangle){ 40 + 120, 200 + 36*2, 720 - 120, 32 }, GetDataAsHexText(hashSHA1, 5), 120, false);
GuiLabel((Rectangle){ 40, 200 + 36*3, 120, 32 }, "SHA256 [256 bit]:");
GuiTextBox((Rectangle){ 40 + 120, 200 + 36*3, 720 - 120, 32 }, GetDataAsHexText(hashSHA256, 8), 120, false);
GuiSetState(STATE_FOCUSED);
GuiLabel((Rectangle){ 40, 200 + 36*5 - 30, 320, 32 }, "BONUS - BAS64 ENCODED STRING:");
GuiSetState(STATE_NORMAL);
GuiLabel((Rectangle){ 40, 200 + 36*5, 120, 32 }, "BASE64 ENCODING:");
GuiTextBox((Rectangle){ 40 + 120, 200 + 36*5, 720 - 120, 32 }, base64Text, 120, false);
GuiSetStyle(TEXTBOX, TEXT_READONLY, 0);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
MemFree(base64Text); // Free Base64 text data
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
static char *GetDataAsHexText(const unsigned int *data, int dataSize)
{
static char text[128] = { 0 };
memset(text, 0, 128);
if ((data != NULL) && (dataSize > 0) && (dataSize < ((128/8) - 1)))
{
for (int i = 0; i < dataSize; i++) TextCopy(text + i*8, TextFormat("%08X", data[i]));
}
else TextCopy(text, "00000000");
return text;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -17,11 +17,11 @@
#include "raylib.h"
#include <stdio.h> // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen()
#include <stdio.h> // Required for: printf(), vprintf(), fprintf()
#include <time.h> // Required for: time_t, tm, time(), localtime(), strftime()
// Custom logging function
void CustomLog(int msgType, const char *text, va_list args)
void CustomTraceLog(int msgType, const char *text, va_list args)
{
char timeStr[64] = { 0 };
time_t now = time(NULL);
@ -54,7 +54,7 @@ int main(void)
const int screenHeight = 450;
// Set custom logger
SetTraceLogCallback(CustomLog);
SetTraceLogCallback(CustomTraceLog);
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging");

View File

@ -20,9 +20,7 @@
#define RAYGUI_IMPLEMENTATION
#include "raygui.h" // Required for GUI controls
#include <string.h> // Required for: strcpy()
#define MAX_FILEPATH_SIZE 2048
#define MAX_FILEPATH_SIZE 1024
//------------------------------------------------------------------------------------
// Program main entry point
@ -53,12 +51,10 @@ int main(void)
//----------------------------------------------------------------------------------
if (btnBackPressed)
{
strcpy(directory, GetPrevDirectoryPath(directory));
TextCopy(directory, GetPrevDirectoryPath(directory));
UnloadDirectoryFiles(files);
files = LoadDirectoryFiles(directory);
}
//----------------------------------------------------------------------------------
// Draw
@ -68,19 +64,20 @@ int main(void)
DrawText(directory, 100, 40, 20, DARKGRAY);
btnBackPressed = GuiButton((Rectangle){ 40.0f, 40.0f, 20, 20 }, "<");
btnBackPressed = GuiButton((Rectangle){ 40.0f, 38.0f, 48, 24 }, "<");
for (int i = 0; i < (int)files.count; i++)
{
Color color = Fade(LIGHTGRAY, 0.3f);
if (!IsPathFile(files.paths[i]))
if (!IsPathFile(files.paths[i]) && DirectoryExists(files.paths[i]))
{
if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, ""))
{
strcpy(directory, files.paths[i]);
TextCopy(directory, files.paths[i]);
UnloadDirectoryFiles(files);
files = LoadDirectoryFiles(directory);
continue;
}
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************************
*
* raylib [core] example - high dpi
* raylib [core] example - highdpi demo
*
* Example complexity rating: [] 2/4
*
@ -33,7 +33,7 @@ int main(void)
const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
InitWindow(screenWidth, screenHeight, "raylib [core] example - high dpi");
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi demo");
SetWindowMinSize(450, 450);
int logicalGridDescY = 120;

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -27,9 +27,15 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
// TODO: Load resources / Initialize variables at this point
Vector2 scaleDpi = GetWindowScaleDPI();
Vector2 mousePos = GetMousePosition();
int currentMonitor = GetCurrentMonitor();
Vector2 windowPos = GetWindowPosition();
int gridSpacing = 40; // Grid spacing in pixels
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
@ -39,7 +45,13 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update variables / Implement example logic at this point
mousePos = GetMousePosition();
currentMonitor = GetCurrentMonitor();
scaleDpi = GetWindowScaleDPI();
windowPos = GetWindowPosition();
if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed();
if (IsKeyPressed(KEY_F)) ToggleFullscreen();
//----------------------------------------------------------------------------------
// Draw
@ -48,11 +60,36 @@ int main(void)
ClearBackground(RAYWHITE);
// TODO: Draw everything that requires to be drawn at this point
// Draw grid
for (int h = 0; h < GetScreenHeight()/gridSpacing + 1; h++)
{
DrawText(TextFormat("%02i", h*gridSpacing), 4, h*gridSpacing - 4, 10, GRAY);
DrawLine(24, h*gridSpacing, GetScreenWidth(), h*gridSpacing, LIGHTGRAY);
}
for (int v = 0; v < GetScreenWidth()/gridSpacing + 1; v++)
{
DrawText(TextFormat("%02i", v*gridSpacing), v*gridSpacing - 10, 4, 10, GRAY);
DrawLine(v*gridSpacing, 20, v*gridSpacing, GetScreenHeight(), LIGHTGRAY);
}
DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
// Draw UI info
DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY);
DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY);
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);
DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 170, 20, DARKGRAY);
DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY);
// Draw reference rectangles, top-left and bottom-right corners
DrawRectangle(0, 0, 30, 60, RED);
DrawRectangle(GetScreenWidth() - 30, GetScreenHeight() - 60, 30, 60, BLUE);
// Draw mouse position
DrawCircleV(GetMousePosition(), 20, MAROON);
DrawRectangle(mousePos.x - 25, mousePos.y, 50, 2, BLACK);
DrawRectangle(mousePos.x, mousePos.y - 25, 2, 50, BLACK);
DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), mousePos.x - 44,
(mousePos.y > GetScreenHeight() - 60)? mousePos.y - 46 : mousePos.y + 30, 20, BLACK);
EndDrawing();
//----------------------------------------------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -71,6 +71,7 @@ int main(void)
// Set default actions
char actionSet = 0;
SetActionsDefault();
bool releaseAction = false;
Vector2 position = (Vector2){ 400.0f, 200.0f };
Vector2 size = (Vector2){ 40.0f, 40.0f };
@ -83,7 +84,8 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
gamepadIndex = 0; // set this to gamepad being checked
gamepadIndex = 0; // Set gamepad being checked
if (IsActionDown(ACTION_UP)) position.y -= 2;
if (IsActionDown(ACTION_DOWN)) position.y += 2;
if (IsActionDown(ACTION_LEFT)) position.x -= 2;
@ -94,6 +96,10 @@ int main(void)
position.y = (screenHeight-size.y)/2;
}
// Register release action for one frame
releaseAction = false;
if (IsActionReleased(ACTION_FIRE)) releaseAction = true;
// Switch control scheme by pressing TAB
if (IsKeyPressed(KEY_TAB))
{
@ -109,7 +115,7 @@ int main(void)
ClearBackground(GRAY);
DrawRectangleV(position, size, RED);
DrawRectangleV(position, size, releaseAction? BLUE : RED);
DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE);
DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN);

View File

@ -51,6 +51,8 @@ int main(void)
const float leftTriggerDeadzone = -0.9f;
const float rightTriggerDeadzone = -0.9f;
Rectangle vibrateButton = { 0 };
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@ -61,7 +63,12 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
// ...
if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--;
if (IsKeyPressed(KEY_RIGHT)) gamepad++;
Vector2 mousePosition = GetMousePosition();
vibrateButton = (Rectangle){ 10, 70.0f + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 };
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0);
//----------------------------------------------------------------------------------
// Draw
@ -70,9 +77,6 @@ int main(void)
ClearBackground(RAYWHITE);
if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--;
if (IsKeyPressed(KEY_RIGHT)) gamepad++;
if (IsGamepadAvailable(gamepad))
{
DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK);
@ -93,7 +97,8 @@ int main(void)
if (leftTrigger < leftTriggerDeadzone) leftTrigger = -1.0f;
if (rightTrigger < rightTriggerDeadzone) rightTrigger = -1.0f;
if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1 || TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1)
if ((TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1) ||
(TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1))
{
DrawTexture(texXboxPad, 0, 0, DARKGRAY);
@ -125,16 +130,14 @@ int main(void)
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
DrawCircle(259, 152, 39, BLACK);
DrawCircle(259, 152, 34, LIGHTGRAY);
DrawCircle(259 + (int)(leftStickX*20),
152 + (int)(leftStickY*20), 25, leftGamepadColor);
DrawCircle(259 + (int)(leftStickX*20), 152 + (int)(leftStickY*20), 25, leftGamepadColor);
// Draw axis: right joystick
Color rightGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
DrawCircle(461, 237, 38, BLACK);
DrawCircle(461, 237, 33, LIGHTGRAY);
DrawCircle(461 + (int)(rightStickX*20),
237 + (int)(rightStickY*20), 25, rightGamepadColor);
DrawCircle(461 + (int)(rightStickX*20), 237 + (int)(rightStickY*20), 25, rightGamepadColor);
// Draw axis: left-right triggers
DrawRectangle(170, 30, 15, 70, GRAY);
@ -177,16 +180,14 @@ int main(void)
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
DrawCircle(319, 255, 35, BLACK);
DrawCircle(319, 255, 31, LIGHTGRAY);
DrawCircle(319 + (int)(leftStickX*20),
255 + (int)(leftStickY*20), 25, leftGamepadColor);
DrawCircle(319 + (int)(leftStickX*20), 255 + (int)(leftStickY*20), 25, leftGamepadColor);
// Draw axis: right joystick
Color rightGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
DrawCircle(475, 255, 35, BLACK);
DrawCircle(475, 255, 31, LIGHTGRAY);
DrawCircle(475 + (int)(rightStickX*20),
255 + (int)(rightStickY*20), 25, rightGamepadColor);
DrawCircle(475 + (int)(rightStickX*20), 255 + (int)(rightStickY*20), 25, rightGamepadColor);
// Draw axis: left-right triggers
DrawRectangle(169, 48, 15, 70, GRAY);
@ -196,7 +197,6 @@ int main(void)
}
else
{
// Draw background: generic
DrawRectangleRounded((Rectangle){ 175, 110, 460, 220}, 0.3f, 16, DARKGRAY);
@ -237,23 +237,20 @@ int main(void)
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
DrawCircle(345, 260, 40, BLACK);
DrawCircle(345, 260, 35, LIGHTGRAY);
DrawCircle(345 + (int)(leftStickX*20),
260 + (int)(leftStickY*20), 25, leftGamepadColor);
DrawCircle(345 + (int)(leftStickX*20), 260 + (int)(leftStickY*20), 25, leftGamepadColor);
// Draw axis: right joystick
Color rightGamepadColor = BLACK;
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
DrawCircle(465, 260, 40, BLACK);
DrawCircle(465, 260, 35, LIGHTGRAY);
DrawCircle(465 + (int)(rightStickX*20),
260 + (int)(rightStickY*20), 25, rightGamepadColor);
DrawCircle(465 + (int)(rightStickX*20), 260 + (int)(rightStickY*20), 25, rightGamepadColor);
// Draw axis: left-right triggers
DrawRectangle(151, 110, 15, 70, GRAY);
DrawRectangle(644, 110, 15, 70, GRAY);
DrawRectangle(151, 110, 15, (int)(((1 + leftTrigger)/2)*70), RED);
DrawRectangle(644, 110, 15, (int)(((1 + rightTrigger)/2)*70), RED);
}
DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(gamepad)), 10, 50, 10, MAROON);
@ -263,13 +260,16 @@ int main(void)
DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(gamepad, i)), 20, 70 + 20*i, 10, DARKGRAY);
}
// Draw vibrate button
DrawRectangleRec(vibrateButton, SKYBLUE);
DrawText("VIBRATE", (int)(vibrateButton.x + 14), (int)(vibrateButton.y + 1), 10, DARKGRAY);
if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED);
else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY);
}
else
{
DrawText(TextFormat("GP%d: NOT DETECTED", gamepad), 10, 10, 10, GRAY);
DrawTexture(texXboxPad, 0, 0, LIGHTGRAY);
}

View File

@ -118,4 +118,6 @@ int main(void)
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -22,9 +22,9 @@
#define GESTURE_LOG_SIZE 20
#define MAX_TOUCH_COUNT 32
//----------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
static char const *GetGestureName(int gesture); // Get text string for gesture value
static Color GetGestureColor(int gesture); // Get color for gesture value
@ -69,7 +69,6 @@ int main(void)
float angleLength = 90.0f;
float currentAngleDegrees = 0.0f;
Vector2 finalVector = { 0.0f, 0.0f };
char currentAngleStr[7] = "";
Vector2 protractorPosition = { 266.0f, 315.0f };
SetTargetFPS(60); // Set our game to run at 60 frames-per-second

View File

@ -40,14 +40,8 @@ int main(void)
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_H))
{
if (IsCursorHidden())
{
ShowCursor();
}
else
{
HideCursor();
}
if (IsCursorHidden()) ShowCursor();
else HideCursor();
}
ballPosition = GetMousePosition();

View File

@ -46,7 +46,7 @@ int main(void)
// Clamp touch points available ( set the maximum touch points allowed )
if (tCount > MAX_TOUCH_POINTS) tCount = MAX_TOUCH_POINTS;
// Get touch points positions
for (int i = 0; i < tCount; ++i) touchPositions[i] = GetTouchPosition(i);
for (int i = 0; i < tCount; i++) touchPositions[i] = GetTouchPosition(i);
//----------------------------------------------------------------------------------
// Draw
@ -55,7 +55,7 @@ int main(void)
ClearBackground(RAYWHITE);
for (int i = 0; i < tCount; ++i)
for (int i = 0; i < tCount; i++)
{
// Make sure point is not (0, 0) as this means there is no touch for it
if ((touchPositions[i].x > 0) && (touchPositions[i].y > 0))

View File

@ -0,0 +1,333 @@
/*******************************************************************************************
*
* raylib [core] example - keyboard testbed
*
* Example complexity rating: [] 2/4
*
* NOTE: raylib defined keys refer to ENG-US Keyboard layout,
* mapping to other layouts is up to the user
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2026 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define KEY_REC_SPACING 4 // Space in pixels between key rectangles
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static const char *GetKeyText(int key);
static void GuiKeyboardKey(Rectangle bounds, int key);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - keyboard testbed");
SetExitKey(KEY_NULL); // Avoid exit on KEY_ESCAPE
// Keyboard line 01
int line01KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line01KeyWidths[i] = 45;
line01KeyWidths[13] = 62; // PRINTSCREEN
int line01Keys[15] = {
KEY_ESCAPE, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
KEY_F12, KEY_PRINT_SCREEN, KEY_PAUSE
};
// Keyboard line 02
int line02KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line02KeyWidths[i] = 45;
line02KeyWidths[0] = 25; // GRAVE
line02KeyWidths[13] = 82; // BACKSPACE
int line02Keys[15] = {
KEY_GRAVE, KEY_ONE, KEY_TWO, KEY_THREE, KEY_FOUR,
KEY_FIVE, KEY_SIX, KEY_SEVEN, KEY_EIGHT, KEY_NINE,
KEY_ZERO, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_DELETE };
// Keyboard line 03
int line03KeyWidths[15] = { 0 };
for (int i = 0; i < 15; i++) line03KeyWidths[i] = 45;
line03KeyWidths[0] = 50; // TAB
line03KeyWidths[13] = 57; // BACKSLASH
int line03Keys[15] = {
KEY_TAB, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y,
KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFT_BRACKET,
KEY_RIGHT_BRACKET, KEY_BACKSLASH, KEY_INSERT
};
// Keyboard line 04
int line04KeyWidths[14] = { 0 };
for (int i = 0; i < 14; i++) line04KeyWidths[i] = 45;
line04KeyWidths[0] = 68; // CAPS
line04KeyWidths[12] = 88; // ENTER
int line04Keys[14] = {
KEY_CAPS_LOCK, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G,
KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,
KEY_APOSTROPHE, KEY_ENTER, KEY_PAGE_UP
};
// Keyboard line 05
int line05KeyWidths[14] = { 0 };
for (int i = 0; i < 14; i++) line05KeyWidths[i] = 45;
line05KeyWidths[0] = 80; // LSHIFT
line05KeyWidths[11] = 76; // RSHIFT
int line05Keys[14] = {
KEY_LEFT_SHIFT, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B,
KEY_N, KEY_M, KEY_COMMA, KEY_PERIOD, /*KEY_MINUS*/
KEY_SLASH, KEY_RIGHT_SHIFT, KEY_UP, KEY_PAGE_DOWN
};
// Keyboard line 06
int line06KeyWidths[11] = { 0 };
for (int i = 0; i < 11; i++) line06KeyWidths[i] = 45;
line06KeyWidths[0] = 80; // LCTRL
line06KeyWidths[3] = 208; // SPACE
line06KeyWidths[7] = 60; // RCTRL
int line06Keys[11] = {
KEY_LEFT_CONTROL, KEY_LEFT_SUPER, KEY_LEFT_ALT,
KEY_SPACE, KEY_RIGHT_ALT, 162, KEY_NULL,
KEY_RIGHT_CONTROL, KEY_LEFT, KEY_DOWN, KEY_RIGHT
};
Vector2 keyboardOffset = { 26, 80 };
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
int key = GetKeyPressed(); // Get pressed keycode
if (key > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: KEY PRESSED: %d", key);
int ch = GetCharPressed(); // Get pressed char for text input, using OS mapping
if (ch > 0) TraceLog(LOG_INFO, "KEYBOARD TESTBED: CHAR PRESSED: %c (%d)", ch, ch);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("KEYBOARD LAYOUT: ENG-US", 26, 38, 20, LIGHTGRAY);
// Keyboard line 01 - 15 keys
// ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, IMP, CLOSE
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y, line01KeyWidths[i], 30 }, line01Keys[i]);
recOffsetX += line01KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 02 - 15 keys
// `, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, BACKSPACE, DEL
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + KEY_REC_SPACING, line02KeyWidths[i], 38 }, line02Keys[i]);
recOffsetX += line02KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 03 - 15 keys
// TAB, Q, W, E, R, T, Y, U, I, O, P, [, ], \, INS
for (int i = 0, recOffsetX = 0; i < 15; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38 + KEY_REC_SPACING*2, line03KeyWidths[i], 38 }, line03Keys[i]);
recOffsetX += line03KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 04 - 14 keys
// MAYUS, A, S, D, F, G, H, J, K, L, ;, ', ENTER, REPAG
for (int i = 0, recOffsetX = 0; i < 14; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*2 + KEY_REC_SPACING*3, line04KeyWidths[i], 38 }, line04Keys[i]);
recOffsetX += line04KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 05 - 14 keys
// LSHIFT, Z, X, C, V, B, N, M, ,, ., /, RSHIFT, UP, AVPAG
for (int i = 0, recOffsetX = 0; i < 14; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*3 + KEY_REC_SPACING*4, line05KeyWidths[i], 38 }, line05Keys[i]);
recOffsetX += line05KeyWidths[i] + KEY_REC_SPACING;
}
// Keyboard line 06 - 11 keys
// LCTRL, WIN, LALT, SPACE, ALTGR, \, FN, RCTRL, LEFT, DOWN, RIGHT
for (int i = 0, recOffsetX = 0; i < 11; i++)
{
GuiKeyboardKey((Rectangle){ keyboardOffset.x + recOffsetX, keyboardOffset.y + 30 + 38*4 + KEY_REC_SPACING*5, line06KeyWidths[i], 38 }, line06Keys[i]);
recOffsetX += line06KeyWidths[i] + KEY_REC_SPACING;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definition
//------------------------------------------------------------------------------------
// Get keyboard keycode as text (US keyboard)
// NOTE: Mapping for other keyboard layouts can be done here
static const char *GetKeyText(int key)
{
switch (key)
{
case KEY_APOSTROPHE : return "'"; // Key: '
case KEY_COMMA : return ","; // Key: ,
case KEY_MINUS : return "-"; // Key: -
case KEY_PERIOD : return "."; // Key: .
case KEY_SLASH : return "/"; // Key: /
case KEY_ZERO : return "0"; // Key: 0
case KEY_ONE : return "1"; // Key: 1
case KEY_TWO : return "2"; // Key: 2
case KEY_THREE : return "3"; // Key: 3
case KEY_FOUR : return "4"; // Key: 4
case KEY_FIVE : return "5"; // Key: 5
case KEY_SIX : return "6"; // Key: 6
case KEY_SEVEN : return "7"; // Key: 7
case KEY_EIGHT : return "8"; // Key: 8
case KEY_NINE : return "9"; // Key: 9
case KEY_SEMICOLON : return ";"; // Key: ;
case KEY_EQUAL : return "="; // Key: =
case KEY_A : return "A"; // Key: A | a
case KEY_B : return "B"; // Key: B | b
case KEY_C : return "C"; // Key: C | c
case KEY_D : return "D"; // Key: D | d
case KEY_E : return "E"; // Key: E | e
case KEY_F : return "F"; // Key: F | f
case KEY_G : return "G"; // Key: G | g
case KEY_H : return "H"; // Key: H | h
case KEY_I : return "I"; // Key: I | i
case KEY_J : return "J"; // Key: J | j
case KEY_K : return "K"; // Key: K | k
case KEY_L : return "L"; // Key: L | l
case KEY_M : return "M"; // Key: M | m
case KEY_N : return "N"; // Key: N | n
case KEY_O : return "O"; // Key: O | o
case KEY_P : return "P"; // Key: P | p
case KEY_Q : return "Q"; // Key: Q | q
case KEY_R : return "R"; // Key: R | r
case KEY_S : return "S"; // Key: S | s
case KEY_T : return "T"; // Key: T | t
case KEY_U : return "U"; // Key: U | u
case KEY_V : return "V"; // Key: V | v
case KEY_W : return "W"; // Key: W | w
case KEY_X : return "X"; // Key: X | x
case KEY_Y : return "Y"; // Key: Y | y
case KEY_Z : return "Z"; // Key: Z | z
case KEY_LEFT_BRACKET : return "["; // Key: [
case KEY_BACKSLASH : return "\\"; // Key: '\'
case KEY_RIGHT_BRACKET : return "]"; // Key: ]
case KEY_GRAVE : return "`"; // Key: `
case KEY_SPACE : return "SPACE"; // Key: Space
case KEY_ESCAPE : return "ESC"; // Key: Esc
case KEY_ENTER : return "ENTER"; // Key: Enter
case KEY_TAB : return "TAB"; // Key: Tab
case KEY_BACKSPACE : return "BACK"; // Key: Backspace
case KEY_INSERT : return "INS"; // Key: Ins
case KEY_DELETE : return "DEL"; // Key: Del
case KEY_RIGHT : return "RIGHT"; // Key: Cursor right
case KEY_LEFT : return "LEFT"; // Key: Cursor left
case KEY_DOWN : return "DOWN"; // Key: Cursor down
case KEY_UP : return "UP"; // Key: Cursor up
case KEY_PAGE_UP : return "PGUP"; // Key: Page up
case KEY_PAGE_DOWN : return "PGDOWN"; // Key: Page down
case KEY_HOME : return "HOME"; // Key: Home
case KEY_END : return "END"; // Key: End
case KEY_CAPS_LOCK : return "CAPS"; // Key: Caps lock
case KEY_SCROLL_LOCK : return "LOCK"; // Key: Scroll down
case KEY_NUM_LOCK : return "NUMLOCK"; // Key: Num lock
case KEY_PRINT_SCREEN : return "PRINTSCR"; // Key: Print screen
case KEY_PAUSE : return "PAUSE"; // Key: Pause
case KEY_F1 : return "F1"; // Key: F1
case KEY_F2 : return "F2"; // Key: F2
case KEY_F3 : return "F3"; // Key: F3
case KEY_F4 : return "F4"; // Key: F4
case KEY_F5 : return "F5"; // Key: F5
case KEY_F6 : return "F6"; // Key: F6
case KEY_F7 : return "F7"; // Key: F7
case KEY_F8 : return "F8"; // Key: F8
case KEY_F9 : return "F9"; // Key: F9
case KEY_F10 : return "F10"; // Key: F10
case KEY_F11 : return "F11"; // Key: F11
case KEY_F12 : return "F12"; // Key: F12
case KEY_LEFT_SHIFT : return "LSHIFT"; // Key: Shift left
case KEY_LEFT_CONTROL : return "LCTRL"; // Key: Control left
case KEY_LEFT_ALT : return "LALT"; // Key: Alt left
case KEY_LEFT_SUPER : return "WIN"; // Key: Super left
case KEY_RIGHT_SHIFT : return "RSHIFT"; // Key: Shift right
case KEY_RIGHT_CONTROL : return "RCTRL"; // Key: Control right
case KEY_RIGHT_ALT : return "ALTGR"; // Key: Alt right
case KEY_RIGHT_SUPER : return "RSUPER"; // Key: Super right
case KEY_KB_MENU : return "KBMENU"; // Key: KB menu
case KEY_KP_0 : return "KP0"; // Key: Keypad 0
case KEY_KP_1 : return "KP1"; // Key: Keypad 1
case KEY_KP_2 : return "KP2"; // Key: Keypad 2
case KEY_KP_3 : return "KP3"; // Key: Keypad 3
case KEY_KP_4 : return "KP4"; // Key: Keypad 4
case KEY_KP_5 : return "KP5"; // Key: Keypad 5
case KEY_KP_6 : return "KP6"; // Key: Keypad 6
case KEY_KP_7 : return "KP7"; // Key: Keypad 7
case KEY_KP_8 : return "KP8"; // Key: Keypad 8
case KEY_KP_9 : return "KP9"; // Key: Keypad 9
case KEY_KP_DECIMAL : return "KPDEC"; // Key: Keypad .
case KEY_KP_DIVIDE : return "KPDIV"; // Key: Keypad /
case KEY_KP_MULTIPLY : return "KPMUL"; // Key: Keypad *
case KEY_KP_SUBTRACT : return "KPSUB"; // Key: Keypad -
case KEY_KP_ADD : return "KPADD"; // Key: Keypad +
case KEY_KP_ENTER : return "KPENTER"; // Key: Keypad Enter
case KEY_KP_EQUAL : return "KPEQU"; // Key: Keypad =
default: return "";
}
}
// Draw keyboard key
static void GuiKeyboardKey(Rectangle bounds, int key)
{
if (key == KEY_NULL) DrawRectangleLinesEx(bounds, 2.0f, LIGHTGRAY);
else
{
if (IsKeyDown(key))
{
DrawRectangleLinesEx(bounds, 2.0f, MAROON);
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, MAROON);
}
else
{
DrawRectangleLinesEx(bounds, 2.0f, DARKGRAY);
DrawText(GetKeyText(key), bounds.x + 4, bounds.y + 4, 10, DARKGRAY);
}
}
if (CheckCollisionPointRec(GetMousePosition(), bounds))
{
DrawRectangleRec(bounds, Fade(RED, 0.2f));
DrawRectangleLinesEx(bounds, 3.0f, RED);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -40,10 +40,9 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
MonitorInfo monitors[MAX_MONITORS] = { 0 };
InitWindow(screenWidth, screenHeight, "raylib [core] example - monitor detector");
MonitorInfo monitors[MAX_MONITORS] = { 0 };
int currentMonitorIndex = GetCurrentMonitor();
int monitorCount = 0;
@ -55,7 +54,6 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
// Variables to find the max x and Y to calculate the scale
int maxWidth = 1;
int maxHeight = 1;
@ -76,7 +74,8 @@ int main(void)
GetMonitorPhysicalHeight(i),
GetMonitorRefreshRate(i)
};
if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = (int)monitors[i].position.x*-1;
if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = -(int)monitors[i].position.x;
const int width = (int)monitors[i].position.x + monitors[i].width;
const int height = (int)monitors[i].position.y + monitors[i].height;
@ -85,7 +84,7 @@ int main(void)
if (maxHeight < height) maxHeight = height;
}
if (IsKeyPressed(KEY_ENTER) && monitorCount > 1)
if (IsKeyPressed(KEY_ENTER) && (monitorCount > 1))
{
currentMonitorIndex += 1;
@ -94,16 +93,13 @@ int main(void)
SetWindowMonitor(currentMonitorIndex); // Move window to currentMonitorIndex
}
else
{
// Get currentMonitorIndex if manually moved
currentMonitorIndex = GetCurrentMonitor();
}
else currentMonitorIndex = GetCurrentMonitor(); // Get currentMonitorIndex if manually moved
float monitorScale = 0.6f;
if(maxHeight > maxWidth + monitorOffsetX) monitorScale *= ((float)screenHeight/(float)maxHeight);
if (maxHeight > (maxWidth + monitorOffsetX)) monitorScale *= ((float)screenHeight/(float)maxHeight);
else monitorScale *= ((float)screenWidth/(float)(maxWidth + monitorOffsetX));
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
@ -148,14 +144,9 @@ int main(void)
// Draw window position based on monitors
DrawRectangleV(windowPosition, (Vector2){screenWidth*monitorScale, screenHeight*monitorScale}, Fade(GREEN, 0.5));
}
else
{
DrawRectangleLinesEx(rec, 5, GRAY);
else DrawRectangleLinesEx(rec, 5, GRAY);
}
}
EndDrawing();
//----------------------------------------------------------------------------------
}

View File

@ -2,12 +2,10 @@
*
* raylib [core] example - screen recording
*
* Example complexity rating: [] 1/4
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
*
* Example contributed by Ramon Santamaria (@raysan5) 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
*
@ -17,6 +15,16 @@
#include "raylib.h"
// Using msf_gif library to record frames into GIF
#define MSF_GIF_IMPL
#include "msf_gif.h" // GIF recording functionality
#include <math.h> // Required for: sinf()
#define GIF_RECORD_FRAMERATE 5 // Record framerate, we get a frame every N frames
#define MAX_SINEWAVE_POINTS 256
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@ -29,7 +37,20 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [core] example - screen recording");
// TODO: Load resources / Initialize variables at this point
bool gifRecording = false; // GIF recording state
unsigned int gifFrameCounter = 0; // GIF frames counter
MsfGifState gifState = { 0 }; // MSGIF context state
Vector2 circlePosition = { 0.0f, screenHeight/2.0f };
float timeCounter = 0.0f;
// Get sine wave points for line drawing
Vector2 sinePoints[MAX_SINEWAVE_POINTS] = { 0 };
for (int i = 0; i < MAX_SINEWAVE_POINTS; i++)
{
sinePoints[i].x = i*GetScreenWidth()/180.0f;
sinePoints[i].y = screenHeight/2.0f + 150*sinf((2*PI/1.5f)*(1.0f/60.0f)*(float)i); // Calculate for 60 fps
}
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
@ -39,7 +60,59 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update variables / Implement example logic at this point
// Update circle sinusoidal movement
timeCounter += GetFrameTime();
circlePosition.x += GetScreenWidth()/180.0f;
circlePosition.y = screenHeight/2.0f + 150*sinf((2*PI/1.5f)*timeCounter);
if (circlePosition.x > screenWidth)
{
circlePosition.x = 0.0f;
circlePosition.y = screenHeight/2.0f;
timeCounter = 0.0f;
}
// Start-Stop GIF recording on CTRL+R
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_R))
{
if (gifRecording)
{
// Stop current recording and save file
gifRecording = false;
MsfGifResult result = msf_gif_end(&gifState);
SaveFileData(TextFormat("%s/screenrecording.gif", GetApplicationDirectory()), result.data, (unsigned int)result.dataSize);
msf_gif_free(result);
TraceLog(LOG_INFO, "Finish animated GIF recording");
}
else
{
// Start a new recording
gifRecording = true;
gifFrameCounter = 0;
msf_gif_begin(&gifState, GetRenderWidth(), GetRenderHeight());
TraceLog(LOG_INFO, "Start animated GIF recording");
}
}
if (gifRecording)
{
gifFrameCounter++;
// NOTE: We record one gif frame depending on the desired gif framerate
if (gifFrameCounter > GIF_RECORD_FRAMERATE)
{
// Get image data for the current frame (from backbuffer)
// WARNING: This process is quite slow, it can generate stuttering
Image imScreen = LoadImageFromScreen();
// Add the frame to the gif recording, providing and "estimated" time for display in centiseconds
msf_gif_frame(&gifState, imScreen.data, (int)((1.0f/60.0f)*GIF_RECORD_FRAMERATE)/10, 16, imScreen.width*4);
gifFrameCounter = 0;
UnloadImage(imScreen); // Free image data
}
}
//----------------------------------------------------------------------------------
// Draw
@ -48,20 +121,43 @@ int main(void)
ClearBackground(RAYWHITE);
// TODO: Draw everything that requires to be drawn at this point
for (int i = 0; i < (MAX_SINEWAVE_POINTS - 1); i++)
{
DrawLineV(sinePoints[i], sinePoints[i + 1], MAROON);
DrawCircleV(sinePoints[i], 3, MAROON);
}
DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
DrawCircleV(circlePosition, 30, RED);
DrawFPS(10, 10);
/*
// Draw record indicator
// WARNING: If drawn here, it will appear in the recorded image,
// use a render texture instead for the recording and LoadImageFromTexture(rt.texture)
if (gifRecording)
{
// Display the recording indicator every half-second
if ((int)(GetTime()/0.5)%2 == 1)
{
DrawCircle(30, GetScreenHeight() - 20, 10, MAROON);
DrawText("GIF RECORDING", 50, GetScreenHeight() - 25, 10, RED);
}
}
*/
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// TODO: Unload all loaded resources at this point
// If still recording a GIF on close window, just finish
if (gifRecording)
{
MsfGifResult result = msf_gif_end(&gifState);
msf_gif_free(result);
gifRecording = false;
}
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -19,6 +19,8 @@
#include "raymath.h" // Required for: Lerp()
#include <string.h>
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@ -59,10 +61,11 @@ int main(void)
int lastSpace = 0; // Keeping track of last valid space to insert '\n'
int lastWrapStart = 0; // Keeping track of the start of this wrapped line.
while (lines[i][j] != '\0')
while (j <= strlen(lines[i]))
{
if (lines[i][j] == ' ')
if (lines[i][j] == ' ' || lines[i][j] == '\0')
{
char before = lines[i][j];
// Making a C Style string by adding a '\0' at the required location so that we can use the MeasureText function
lines[i][j] = '\0';
@ -75,7 +78,7 @@ int main(void)
lastWrapStart = lastSpace + 1;
}
lines[i][j] = ' '; // Resetting the space back
if(before != '\0') lines[i][j] = ' '; // Resetting the space back
lastSpace = j; // Since we encountered a new space we update our last encountered space location
}
@ -92,7 +95,7 @@ int main(void)
textHeight += (int)size.y + 10;
}
// A simple scrollbar on the side to show how far we have red into the file
// A simple scrollbar on the side to show how far we have read into the file
Rectangle scrollBar = {
.x = (float)screenWidth - 5,
.y = 0,
@ -132,7 +135,13 @@ int main(void)
for (int i = 0, t = textTop; i < lineCount; i++)
{
// Each time we go through and calculate the height of the text to move the cursor appropriately
Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], (float)fontSize, 2);
Vector2 size;
if(strcmp(lines[i], "")){
// Fix for empty line in the text file
size = MeasureTextEx( GetFontDefault(), lines[i], (float)fontSize, 2);
}else{
size = MeasureTextEx( GetFontDefault(), " ", (float)fontSize, 2);
}
DrawText(lines[i], 10, t, fontSize, RED);

View File

@ -0,0 +1,321 @@
/*******************************************************************************************
*
* raylib [core] example - viewport scaling
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.5
*
* Example contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2025 Agnis Aldiņš (@nezvers)
*
********************************************************************************************/
#include "raylib.h"
#define RESOLUTION_COUNT 4 // For iteration purposes and teaching example
typedef enum {
// Only upscale, useful for pixel art
KEEP_ASPECT_INTEGER,
KEEP_HEIGHT_INTEGER,
KEEP_WIDTH_INTEGER,
// Can also downscale
KEEP_ASPECT,
KEEP_HEIGHT,
KEEP_WIDTH,
// For itteration purposes and as a teaching example
VIEWPORT_TYPE_COUNT,
} ViewportType;
// For displaying on GUI
const char *ViewportTypeNames[VIEWPORT_TYPE_COUNT] = {
"KEEP_ASPECT_INTEGER",
"KEEP_HEIGHT_INTEGER",
"KEEP_WIDTH_INTEGER",
"KEEP_ASPECT",
"KEEP_HEIGHT",
"KEEP_WIDTH",
};
//--------------------------------------------------------------------------------------
// Module Functions Declaration
//--------------------------------------------------------------------------------------
static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target);
// Example how to calculate position on RenderTexture
static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//---------------------------------------------------------
int screenWidth = 800;
int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
InitWindow(screenWidth, screenHeight, "raylib [core] example - viewport scaling");
// Preset resolutions that could be created by subdividing screen resolution
Vector2 resolutionList[RESOLUTION_COUNT] = {
(Vector2){ 64, 64 },
(Vector2){ 256, 240 },
(Vector2){ 320, 180 },
// 4K doesn't work with integer scaling but included for example purposes with non-integer scaling
(Vector2){ 3840, 2160 },
};
int resolutionIndex = 0;
int gameWidth = 64;
int gameHeight = 64;
RenderTexture2D target = (RenderTexture2D){ 0 };
Rectangle sourceRect = (Rectangle){ 0 };
Rectangle destRect = (Rectangle){ 0 };
ViewportType viewportType = KEEP_ASPECT_INTEGER;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
// Button rectangles
Rectangle decreaseResolutionButton = (Rectangle){ 200, 30, 10, 10 };
Rectangle increaseResolutionButton = (Rectangle){ 215, 30, 10, 10 };
Rectangle decreaseTypeButton = (Rectangle){ 200, 45, 10, 10 };
Rectangle increaseTypeButton = (Rectangle){ 215, 45, 10, 10 };
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
//----------------------------------------------------------------------------------
if (IsWindowResized()) ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
Vector2 mousePosition = GetMousePosition();
bool mousePressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
// Check buttons and rescale
if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed)
{
resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT;
gameWidth = (int)resolutionList[resolutionIndex].x;
gameHeight = (int)resolutionList[resolutionIndex].y;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
}
if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed)
{
resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT;
gameWidth = (int)resolutionList[resolutionIndex].x;
gameHeight = (int)resolutionList[resolutionIndex].y;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
}
if (CheckCollisionPointRec(mousePosition, decreaseTypeButton) && mousePressed)
{
viewportType = (viewportType + VIEWPORT_TYPE_COUNT - 1)%VIEWPORT_TYPE_COUNT;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
}
if (CheckCollisionPointRec(mousePosition, increaseTypeButton) && mousePressed)
{
viewportType = (viewportType + 1)%VIEWPORT_TYPE_COUNT;
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
}
Vector2 textureMousePosition = Screen2RenderTexturePosition(mousePosition, &sourceRect, &destRect);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
// Draw our scene to the render texture
BeginTextureMode(target);
ClearBackground(WHITE);
DrawCircleV(textureMousePosition, 20.0f, LIME);
EndTextureMode();
// Draw render texture to main framebuffer
BeginDrawing();
ClearBackground(BLACK);
// Draw our render texture with rotation applied
DrawTexturePro(target.texture, sourceRect, destRect, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
// Draw Native resolution (GUI or anything)
// Draw info box
Rectangle infoRect = (Rectangle){5, 5, 330, 105};
DrawRectangleRec(infoRect, Fade(LIGHTGRAY, 0.7f));
DrawRectangleLinesEx(infoRect, 1, BLUE);
DrawText(TextFormat("Window Resolution: %d x %d", screenWidth, screenHeight), 15, 15, 10, BLACK);
DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK);
DrawText(TextFormat("Type: %s", ViewportTypeNames[viewportType]), 15, 45, 10, BLACK);
Vector2 scaleRatio = (Vector2){destRect.width/sourceRect.width, -destRect.height/sourceRect.height};
if (scaleRatio.x < 0.001f || scaleRatio.y < 0.001f) DrawText(TextFormat("Scale ratio: INVALID"), 15, 60, 10, BLACK);
else DrawText(TextFormat("Scale ratio: %.2f x %.2f", scaleRatio.x, scaleRatio.y), 15, 60, 10, BLACK);
DrawText(TextFormat("Source size: %.2f x %.2f", sourceRect.width, -sourceRect.height), 15, 75, 10, BLACK);
DrawText(TextFormat("Destination size: %.2f x %.2f", destRect.width, destRect.height), 15, 90, 10, BLACK);
// Draw buttons
DrawRectangleRec(decreaseTypeButton, SKYBLUE);
DrawRectangleRec(increaseTypeButton, SKYBLUE);
DrawRectangleRec(decreaseResolutionButton, SKYBLUE);
DrawRectangleRec(increaseResolutionButton, SKYBLUE);
DrawText("<", decreaseTypeButton.x + 3, decreaseTypeButton.y + 1, 10, BLACK);
DrawText(">", increaseTypeButton.x + 3, increaseTypeButton.y + 1, 10, BLACK);
DrawText("<", decreaseResolutionButton.x + 3, decreaseResolutionButton.y + 1, 10, BLACK);
DrawText(">", increaseResolutionButton.x + 3, increaseResolutionButton.y + 1, 10, BLACK);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//----------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//----------------------------------------------------------------------------------
return 0;
}
//--------------------------------------------------------------------------------------
// Module Functions Definition
//--------------------------------------------------------------------------------------
static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
{
sourceRect->x = 0.0f;
sourceRect->y = (float)gameHeight;
sourceRect->width = (float)gameWidth;
sourceRect->height = (float)-gameHeight;
const int ratio_x = (screenWidth/gameWidth);
const int ratio_y = (screenHeight/gameHeight);
const float resizeRatio = (float)((ratio_x < ratio_y)? ratio_x : ratio_y);
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
destRect->width = (float)(int)(gameWidth*resizeRatio);
destRect->height = (float)(int)(gameHeight*resizeRatio);
}
static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
{
const float resizeRatio = (float)screenHeight/gameHeight;
sourceRect->x = 0.0f;
sourceRect->y = 0.0f;
sourceRect->width = (float)(int)(screenWidth/resizeRatio);
sourceRect->height = (float)-gameHeight;
destRect->x = (float)(int)((screenWidth - (sourceRect->width*resizeRatio))*0.5f);
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
destRect->width = (float)(int)(sourceRect->width*resizeRatio);
destRect->height = (float)(int)(gameHeight*resizeRatio);
}
static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
{
const float resizeRatio = (float)screenWidth/gameWidth;
sourceRect->x = 0.0f;
sourceRect->y = 0.0f;
sourceRect->width = (float)gameWidth;
sourceRect->height = (float)(int)(screenHeight/resizeRatio);
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
destRect->y = (float)(int)((screenHeight - (sourceRect->height*resizeRatio))*0.5f);
destRect->width = (float)(int)(gameWidth*resizeRatio);
destRect->height = (float)(int)(sourceRect->height*resizeRatio);
sourceRect->height *= -1.0f;
}
static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
{
sourceRect->x = 0.0f;
sourceRect->y = (float)gameHeight;
sourceRect->width = (float)gameWidth;
sourceRect->height = (float)-gameHeight;
const float ratio_x = ((float)screenWidth/(float)gameWidth);
const float ratio_y = ((float)screenHeight/(float)gameHeight);
const float resizeRatio = (ratio_x < ratio_y ? ratio_x : ratio_y);
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
destRect->width = (float)(int)(gameWidth*resizeRatio);
destRect->height = (float)(int)(gameHeight*resizeRatio);
}
static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
{
const float resizeRatio = ((float)screenHeight/(float)gameHeight);
sourceRect->x = 0.0f;
sourceRect->y = 0.0f;
sourceRect->width = (float)(int)((float)screenWidth/resizeRatio);
sourceRect->height = (float)-gameHeight;
destRect->x = (float)(int)((screenWidth - (sourceRect->width*resizeRatio))*0.5f);
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
destRect->width = (float)(int)(sourceRect->width*resizeRatio);
destRect->height = (float)(int)(gameHeight*resizeRatio);
}
static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
{
const float resizeRatio = ((float)screenWidth/(float)gameWidth);
sourceRect->x = 0.0f;
sourceRect->y = 0.0f;
sourceRect->width = (float)gameWidth;
sourceRect->height = (float)(int)((float)screenHeight/resizeRatio);
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
destRect->y = (float)(int)((screenHeight - (sourceRect->height*resizeRatio))*0.5f);
destRect->width = (float)(int)(gameWidth*resizeRatio);
destRect->height = (float)(int)(sourceRect->height*resizeRatio);
sourceRect->height *= -1.f;
}
static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target)
{
*screenWidth = GetScreenWidth();
*screenHeight = GetScreenHeight();
switch(viewportType)
{
case KEEP_ASPECT_INTEGER: KeepAspectCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
case KEEP_HEIGHT_INTEGER: KeepHeightCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
case KEEP_WIDTH_INTEGER: KeepWidthCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
case KEEP_ASPECT: KeepAspectCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
case KEEP_HEIGHT: KeepHeightCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
case KEEP_WIDTH: KeepWidthCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
default: break;
}
UnloadRenderTexture(*target);
*target = LoadRenderTexture(sourceRect->width, -sourceRect->height);
}
// Example how to calculate position on RenderTexture
static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect)
{
Vector2 relativePosition = {point.x - scaledRect->x, point.y - scaledRect->y};
Vector2 ratio = {textureRect->width/scaledRect->width, -textureRect->height/scaledRect->height};
return (Vector2){relativePosition.x*ratio.x, relativePosition.y*ratio.x};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@ -43,7 +43,7 @@ int main(void)
*/
// Set configuration flags for window creation
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);// | FLAG_WINDOW_TRANSPARENT);
InitWindow(screenWidth, screenHeight, "raylib [core] example - window flags");
Vector2 ballPosition = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
@ -97,7 +97,8 @@ int main(void)
if (IsWindowState(FLAG_WINDOW_MINIMIZED))
{
framesCounter++;
if (framesCounter >= 240) {
if (framesCounter >= 240)
{
RestoreWindow(); // Restore window after 3 seconds
framesCounter = 0;
}

View File

@ -18,7 +18,7 @@
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main()
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,13 @@
#
# raylib examples list used to generate/update collection
# examples must be provided as: <example_category>;<example_name>;<example_stars>;<raylib_created_version>;<raylib_last_update_version>;<year_created>;<year_reviewed>;"<example_author_name>";<author_github_user>
# raylib examples list with available .c example files
#
# WARNING: List is not ordered by example name but by the display order on web,
# so it can not be automatically generated scanning available .c code files, only updated
# new examples are added at the end of each category; it's up to the user to reorder them as desired
#
# examples data is listed as: <example_category>;<example_name>;<example_stars>;<raylib_created_version>;<raylib_last_update_version>;<year_created>;<year_reviewed>;"<example_author_name>";<author_github_user>
#
# This list is used as the main reference by [rexm] tool for examples collection validation and management
# New examples must be added to this list and any possible rename must be made on this list first
#
# WARNING: List is not ordered by example name but by the display order on web
#
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary
@ -25,7 +27,7 @@ core;core_3d_camera_mode;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@rays
core;core_3d_camera_free;★☆☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
core;core_3d_camera_first_person;★★☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
core;core_3d_camera_split_screen;★★★☆;3.7;4.0;2021;2025;"Jeffery Myers";@JeffM2501
core;core_3d_camera_fps;★★★☆;5.5;5.5;2025;2025;"Agnis Aldins";@nezvers
core;core_3d_camera_fps;★★★☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
core;core_3d_picking;★★☆☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5
core;core_world_screen;★★☆☆;1.3;1.4;2015;2025;"Ramon Santamaria";@raysan5
core;core_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
@ -43,15 +45,18 @@ core;core_custom_frame_control;★★★★;4.0;4.0;2021;2025;"Ramon Santamaria"
core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessandroni";@NotManyIdeasDev
core;core_random_sequence;★☆☆☆;5.0;5.0;2023;2025;"Dalton Overmyer";@REDl3east
core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
core;core_high_dpi;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
core;core_highdpi_demo;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
core;core_input_actions;★★☆☆;5.5;5.6;2025;2025;"Jett";@JettMonstersGoBoom
core;core_directory_files;★☆☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
core;core_highdpi_testbed;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_screen_recording;★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_clipboard_text;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
core;core_screen_recording;★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower
@ -84,6 +89,13 @@ shapes;shapes_math_sine_cosine;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe"
shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2025;2025;"Balamurugan R";@Bala050814
shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
shapes;shapes_lines_drawing;★☆☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
shapes;shapes_math_angle_rotation;★☆☆☆;5.6-dev;5.6;2025;2025;"Kris";@krispy-snacc
shapes;shapes_rlgl_color_wheel;★★★☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
@ -109,7 +121,11 @@ textures;textures_gif_player;★★★☆;4.2;4.2;2021;2025;"Ramon Santamaria";@
textures;textures_image_kernel;★★★★;1.3;1.3;2015;2025;"Karim Salem";@kimo-s
textures;textures_image_channel;★★☆☆;5.5;5.5;2024;2025;"Bruno Cabral";@brccabral
textures;textures_image_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501
textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary
textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
textures;textures_framebuffer_rendering;★★☆☆;5.6;5.6;2026;2026;"Jack Boakes";@jackboakes
text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5
text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
@ -125,6 +141,7 @@ text;text_3d_drawing;★★★★;3.5;4.0;2021;2025;"Vlad Adrian";@demizdor
text;text_codepoints_loading;★★★☆;4.2;4.2;2022;2025;"Ramon Santamaria";@raysan5
text;text_inline_styling;★★★☆;5.6-dev;5.6-dev;2025;2025;"Wagner Barongello";@SultansOfCode
text;text_words_alignment;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
text;text_strings_management;★★★☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
models;models_animation_playing;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant
models;models_billboard_rendering;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
models;models_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
@ -150,6 +167,8 @@ models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur
models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz
models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle
models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
@ -163,6 +182,7 @@ shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff";
shaders;shaders_texture_waves;★★☆☆;2.5;3.7;2019;2025;"Anata";@anatagawa
shaders;shaders_julia_set;★★★☆;2.5;4.0;2019;2025;"Josh Colclough";@joshcol9232
shaders;shaders_mandelbrot_set;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
shaders;shaders_color_correction;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
shaders;shaders_eratosthenes_sieve;★★★☆;2.5;4.0;2019;2025;"ProfJski";@ProfJski
shaders;shaders_fog_rendering;★★★☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
shaders;shaders_simple_mask;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
@ -181,6 +201,7 @@ shaders;shaders_basic_pbr;★★★★;5.0;5.5;2023;2025;"Afan OLOVCIC";@_DevDad
shaders;shaders_lightmap_rendering;★★★☆;4.5;4.5;2019;2025;"Jussi Viitala";@nullstare
shaders;shaders_rounded_rectangle;★★★☆;5.5;5.5;2025;2025;"Anstro Pleuton";@anstropleuton
shaders;shaders_depth_rendering;★★★☆;5.6-dev;5.6-dev;2025;2025;"Luís Almeida";@luis605
shaders;shaders_game_of_life;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
audio;audio_module_playing;★☆☆☆;1.5;3.5;2016;2025;"Ramon Santamaria";@raysan5
audio;audio_music_stream;★☆☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
audio;audio_raw_stream;★★★☆;1.6;4.2;2015;2025;"Ramon Santamaria";@raysan5
@ -189,6 +210,7 @@ audio;audio_mixed_processor;★★★★;4.2;4.2;2023;2025;"hkc";@hatkidchan
audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@raysan5
audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501
audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71
audio;audio_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4
others;rlgl_standalone;★★★★;1.6;4.0;2014;2025;"Ramon Santamaria";@raysan5
others;rlgl_compute_shader;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
others;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flashback-fx

View File

@ -4,7 +4,7 @@
*
* Example complexity rating: [] 4/4
*
* Example originally created with raylib 5.6-dev
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
*
* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5)
* Based on previous work by @mrdoob
@ -43,8 +43,10 @@ typedef struct MeshBuilder {
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]);
static void FreeMeshBuilder(MeshBuilder *mb);
static Mesh BuildMesh(MeshBuilder *mb);
static Mesh GenMeshDecal(Mesh inputMesh, Ray ray);
static Mesh GenMeshDecal(Model inputModel, Matrix projection, float decalSize, float decalOffset);
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s);
static void FreeDecalMeshData(void) { GenMeshDecal((Model){ .meshCount = -1 }, (Matrix){ 0 }, 0.0f, 0.0f); }
static bool GuiButton(Rectangle rec, const char *label);
//------------------------------------------------------------------------------------
// Program main entry point
@ -105,10 +107,6 @@ int main(void)
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture;
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
// We're going to use these to build up our decal meshes
// They'll resize automatically as we go, we'll free them at the end
MeshBuilder meshBuilders[2] = { 0 };
bool showModel = true;
Model decalModels[MAX_DECALS] = { 0 };
int decalCount = 0;
@ -123,8 +121,6 @@ int main(void)
//----------------------------------------------------------------------------------
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) UpdateCamera(&camera, CAMERA_THIRD_PERSON);
if (IsKeyPressed(KEY_SPACE)) showModel = !showModel;
// Display information about closest hit
RayCollision collision = { 0 };
collision.distance = FLT_MAX;
@ -165,7 +161,221 @@ int main(void)
// Spin the placement around a bit
splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD*((float)GetRandomValue(-180, 180))));
Matrix splatInv = MatrixInvert(splat);
Mesh decalMesh = GenMeshDecal(model, splat, decalSize, decalOffset);
if (decalMesh.vertexCount > 0)
{
int decalIndex = decalCount++;
decalModels[decalIndex] = LoadModelFromMesh(decalMesh);
decalModels[decalIndex].materials[0].maps[0] = decalMaterial.maps[0];
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
// Draw the model at the origin and default scale
if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
// Draw the decal models
for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){ 0 }, 1.0f, WHITE);
// If we hit the mesh, draw the box for the decal
if (collision.hit)
{
Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f));
Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0});
placementCube.transform = MatrixInvert(splat);
DrawModel(placementCube, (Vector3){ 0 }, 1.0f, Fade(WHITE, 0.5f));
}
DrawGrid(10, 10.0f);
EndMode3D();
float yPos = 10;
float x0 = GetScreenWidth() - 300.0f;
float x1 = x0 + 100;
float x2 = x1 + 100;
DrawText("Vertices", (int)x1, (int)yPos, 10, LIME);
DrawText("Triangles", (int)x2, (int)yPos, 10, LIME);
yPos += 15;
int vertexCount = 0;
int triangleCount = 0;
for (int i = 0; i < model.meshCount; i++)
{
vertexCount += model.meshes[i].vertexCount;
triangleCount += model.meshes[i].triangleCount;
}
DrawText("Main model", (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15;
for (int i = 0; i < decalCount; i++)
{
if (i == 20)
{
DrawText("...", (int)x0, (int)yPos, 10, LIME);
yPos += 15;
}
if (i < 20)
{
DrawText(TextFormat("Decal #%d", i+1), (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15;
}
vertexCount += decalModels[i].meshes[0].vertexCount;
triangleCount += decalModels[i].meshes[0].triangleCount;
}
DrawText("TOTAL", (int)x0, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", vertexCount), (int)x1, (int)yPos, 10, LIME);
DrawText(TextFormat("%d", triangleCount), (int)x2, (int)yPos, 10, LIME);
yPos += 15;
DrawText("Hold RMB to move camera", 10, 430, 10, GRAY);
DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY);
// UI elements
if (GuiButton((Rectangle){ 10, screenHeight - 1000.f, 100, 60 }, showModel ? "Hide Model" : "Show Model")) showModel = !showModel;
if (GuiButton((Rectangle){ 10 + 110, screenHeight - 100.0f, 100, 60 }, "Clear Decals"))
{
// Clear decals, unload all decal models
for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
decalCount = 0;
}
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadModel(model);
UnloadTexture(modelTexture);
// Unload decal models
for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
UnloadTexture(decalTexture);
FreeDecalMeshData(); // Free the data for decal generation
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Add triangles to mesh builder (dynamic array manager)
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3])
{
// Reallocate and copy if we need to
if (mb->vertexCapacity <= (mb->vertexCount + 3))
{
int newVertexCapacity = (1 + (mb->vertexCapacity/256))*256;
Vector3 *newVertices = (Vector3 *)MemAlloc(newVertexCapacity*sizeof(Vector3));
if (mb->vertexCapacity > 0)
{
memcpy(newVertices, mb->vertices, mb->vertexCount*sizeof(Vector3));
MemFree(mb->vertices);
}
mb->vertices = newVertices;
mb->vertexCapacity = newVertexCapacity;
}
// Add 3 vertices
int index = mb->vertexCount;
mb->vertexCount += 3;
for (int i = 0; i < 3; i++) mb->vertices[index+i] = vertices[i];
}
// Free mesh builder
static void FreeMeshBuilder(MeshBuilder *mb)
{
MemFree(mb->vertices);
if (mb->uvs) MemFree(mb->uvs);
*mb = (MeshBuilder){ 0 };
}
// Build a Mesh from MeshBuilder data
static Mesh BuildMesh(MeshBuilder *mb)
{
Mesh outMesh = { 0 };
outMesh.vertexCount = mb->vertexCount;
outMesh.triangleCount = mb->vertexCount/3;
outMesh.vertices = MemAlloc(outMesh.vertexCount*3*sizeof(float));
if (mb->uvs) outMesh.texcoords = MemAlloc(outMesh.vertexCount*2*sizeof(float));
for (int i = 0; i < mb->vertexCount; i++)
{
outMesh.vertices[3*i+0] = mb->vertices[i].x;
outMesh.vertices[3*i+1] = mb->vertices[i].y;
outMesh.vertices[3*i+2] = mb->vertices[i].z;
if (mb->uvs)
{
outMesh.texcoords[2*i+0] = mb->uvs[i].x;
outMesh.texcoords[2*i+1] = mb->uvs[i].y;
}
}
UploadMesh(&outMesh, false);
return outMesh;
}
// Clip segment
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s)
{
float d0 = Vector3DotProduct(v0, p) - s;
float d1 = Vector3DotProduct(v1, p) - s;
float s0 = d0/(d0 - d1);
Vector3 position = Vector3Lerp(v0, v1, s0);
return position;
}
// Generate mesh decals for provided model
static Mesh GenMeshDecal(Model target, Matrix projection, float decalSize, float decalOffset)
{
// We're going to use these to build up our decal meshes
// They'll resize automatically as we go, we'll free them at the end
static MeshBuilder meshBuilders[2] = { 0 };
// Ugly way of telling us to free the static MeshBuilder data
if (target.meshCount == -1)
{
FreeMeshBuilder(&meshBuilders[0]);
FreeMeshBuilder(&meshBuilders[1]);
return (Mesh){ 0 };
}
// We're going to need the inverse matrix
Matrix invProj = MatrixInvert(projection);
// Reset the mesh builders
meshBuilders[0].vertexCount = 0;
@ -176,9 +386,9 @@ int main(void)
int mbIndex = 0;
// First pass, just get any triangle inside the bounding box (for each mesh of the model)
for (int meshIndex = 0; meshIndex < model.meshCount; meshIndex++)
for (int meshIndex = 0; meshIndex < target.meshCount; meshIndex++)
{
Mesh mesh = model.meshes[meshIndex];
Mesh mesh = target.meshes[meshIndex];
for (int tri = 0; tri < mesh.triangleCount; tri++)
{
Vector3 vertices[3] = { 0 };
@ -213,8 +423,8 @@ int main(void)
int insideCount = 0;
for (int i = 0; i < 3; i++)
{
// To splat space
Vector3 v = Vector3Transform(vertices[i], splat);
// To projection space
Vector3 v = Vector3Transform(vertices[i], projection);
if ((fabsf(v.x) < decalSize) || (fabsf(v.y) <= decalSize) || (fabsf(v.z) <= decalSize)) insideCount++;
@ -354,185 +564,42 @@ int main(void)
theMesh->uvs[i].x = (theMesh->vertices[i].x/decalSize + 0.5f);
theMesh->uvs[i].y = (theMesh->vertices[i].y/decalSize + 0.5f);
// From splat space to world space
theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], splatInv);
// Tiny nudge in the normal direction so it renders properly over the mesh
theMesh->vertices[i] = Vector3Add(theMesh->vertices[i], Vector3Scale(collision.normal, decalOffset));
theMesh->vertices[i].z -= decalOffset;
// From projection space to world space
theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], invProj);
}
// Decal model data ready, create it and add it
int decalIndex = decalCount++;
decalModels[decalIndex] = LoadModelFromMesh(BuildMesh(theMesh));
decalModels[decalIndex].materials[0] = decalMaterial;
// Decal model data ready, create the mesh and return it
return BuildMesh(theMesh);
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
// Draw the model at the origin and default scale
if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
// Draw the decal models
for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){0}, 1.0f, WHITE);
// If we hit the mesh, draw the box for the decal
if (collision.hit)
else
{
Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f));
Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0});
placementCube.transform = MatrixInvert(splat);
DrawModel(placementCube, (Vector3){0}, 1.0f, Fade(WHITE, 0.5f));
// Return a blank mesh as there's nothing to add
return (Mesh){ 0 };
}
}
DrawGrid(10, 10.0f);
EndMode3D();
float yPos = 10;
float x0 = GetScreenWidth() - 300;
float x1 = x0 + 100;
float x2 = x1 + 100;
DrawText("Vertices", x1, yPos, 10, LIME);
DrawText("Triangles", x2, yPos, 10, LIME);
yPos += 15;
int vertexCount = 0;
int triangleCount = 0;
for (int i = 0; i < model.meshCount; i++)
// Button UI element
static bool GuiButton(Rectangle rec, const char *label)
{
vertexCount += model.meshes[i].vertexCount;
triangleCount += model.meshes[i].triangleCount;
}
Color bgColor = GRAY;
bool pressed = false;
DrawText("Main model", x0, yPos, 10, LIME);
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME);
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME);
yPos += 15;
for (int i = 0; i < decalCount; i++)
if (CheckCollisionPointRec(GetMousePosition(), rec))
{
DrawText(TextFormat("Decal #%d", i+1), x0, yPos, 10, LIME);
DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), x1, yPos, 10, LIME);
DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), x2, yPos, 10, LIME);
vertexCount += decalModels[i].meshes[0].vertexCount;
triangleCount += decalModels[i].meshes[0].triangleCount;
yPos += 15;
bgColor = LIGHTGRAY;
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) pressed = true;
}
DrawText("TOTAL", x0, yPos, 10, LIME);
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME);
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME);
yPos += 15;
DrawRectangleRec(rec, bgColor);
DrawRectangleLinesEx(rec, 2.0f, DARKGRAY);
DrawText("Hold RMB to move camera", 10, 430, 10, GRAY);
DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY);
int fontSize = 10;
int textWidth = MeasureText(label, fontSize);
DrawFPS(10, 10);
DrawText(label, (int)(rec.x + rec.width*0.5f - textWidth*0.5f), (int)(rec.y + rec.height*0.5f - fontSize*0.5f), fontSize, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadModel(model);
UnloadTexture(modelTexture);
// TODO: WARNING: This line crashes program on closing
//for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
UnloadTexture(decalTexture);
FreeMeshBuilder(&meshBuilders[0]);
FreeMeshBuilder(&meshBuilders[1]);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
// Add triangles to mesh builder (dynamic array manager)
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3])
{
// Reallocate and copy if we need to
if (mb->vertexCapacity <= (mb->vertexCount + 3))
{
int newVertexCapacity = (1 + (mb->vertexCapacity/256))*256;
Vector3 *newVertices = (Vector3 *)MemAlloc(newVertexCapacity*sizeof(Vector3));
if (mb->vertexCapacity > 0)
{
memcpy(newVertices, mb->vertices, mb->vertexCount*sizeof(Vector3));
MemFree(mb->vertices);
}
mb->vertices = newVertices;
mb->vertexCapacity = newVertexCapacity;
}
// Add 3 vertices
int index = mb->vertexCount;
mb->vertexCount += 3;
for (int i = 0; i < 3; i++) mb->vertices[index+i] = vertices[i];
}
// Free mesh builder
static void FreeMeshBuilder(MeshBuilder *mb)
{
MemFree(mb->vertices);
if (mb->uvs) MemFree(mb->uvs);
*mb = (MeshBuilder){ 0 };
}
// Build a Mesh from MeshBuilder data
static Mesh BuildMesh(MeshBuilder *mb)
{
Mesh outMesh = { 0 };
outMesh.vertexCount = mb->vertexCount;
outMesh.triangleCount = mb->vertexCount/3;
outMesh.vertices = MemAlloc(outMesh.vertexCount*3*sizeof(float));
if (mb->uvs) outMesh.texcoords = MemAlloc(outMesh.vertexCount*2*sizeof(float));
for (int i = 0; i < mb->vertexCount; i++)
{
outMesh.vertices[3*i+0] = mb->vertices[i].x;
outMesh.vertices[3*i+1] = mb->vertices[i].y;
outMesh.vertices[3*i+2] = mb->vertices[i].z;
if (mb->uvs)
{
outMesh.texcoords[2*i+0] = mb->uvs[i].x;
outMesh.texcoords[2*i+1] = mb->uvs[i].y;
}
}
UploadMesh(&outMesh, false);
return outMesh;
}
// Clip segment
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s)
{
float d0 = Vector3DotProduct(v0, p) - s;
float d1 = Vector3DotProduct(v1, p) - s;
float s0 = d0/(d0 - d1);
Vector3 position = Vector3Lerp(v0, v1, s0);
return position;
return pressed;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,116 @@
/*******************************************************************************************
*
* raylib [models] example - directional billboard
*
* Example complexity rating: [] 2/4
*
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6
*
* Example contributed by Robin (@RobinsAviary) 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 Robin (@RobinsAviary)
* Killbot art by patvanmackelberg https://opengameart.org/content/killbot-8-directional under CC0
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#include <stdlib.h>
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - directional billboard");
// Set up the camera
Camera camera = { 0 };
camera.position = (Vector3){ 2.0f, 1.0f, 2.0f }; // Starting position
camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Target position
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Up vector
camera.fovy = 45.0f; // FOV
camera.projection = CAMERA_PERSPECTIVE; // Projection type (Standard 3D perspective)
// Load billboard texture
Texture skillbot = LoadTexture("resources/skillbot.png");
// Timer to update animation
float anim_timer = 0.0f;
// Animation frame
unsigned int anim = 0;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera, CAMERA_ORBITAL);
// Update timer with delta time
anim_timer += GetFrameTime();
// Update frame index after a certain amount of time (half a second)
if (anim_timer > 0.5f)
{
anim_timer = 0.0f;
anim += 1;
}
// Reset frame index to zero on overflow
if (anim >= 4) anim = 0;
// Find the current direction frame based on the camera position to the billboard object
float dir = (float)floor(((Vector2Angle((Vector2){ 2.0f, 0.0f }, (Vector2){ camera.position.x, camera.position.z })/PI)*4.0f) + 0.25f);
// Correct frame index if angle is negative
if (dir < 0.0f)
{
dir = 8.0f - (float)abs((int)dir);
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
DrawGrid(10, 1.0f);
// Draw billboard pointing straight up to the sky, rotated relative to the camera and offset from the bottom
DrawBillboardPro(camera, skillbot, (Rectangle){ 0.0f + (anim*24.0f), 0.0f + (dir*24.0f), 24.0f, 24.0f }, Vector3Zero(), (Vector3){ 0.0f, 1.0f, 0.0f }, Vector2One(), (Vector2){ 0.5f, 0.0f }, 0, WHITE);
EndMode3D();
// Render various variables for reference
DrawText(TextFormat("animation: %d", anim), 10, 10, 20, DARKGRAY);
DrawText(TextFormat("direction frame: %.0f", dir), 10, 40, 20, DARKGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload billboard texture
UnloadTexture(skillbot);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -80,13 +80,17 @@ int main(void)
if (playerCellY < 0) playerCellY = 0;
else if (playerCellY >= cubicmap.height) playerCellY = cubicmap.height - 1;
// Check map collisions using image data and player position
// TODO: Improvement: Just check player surrounding cells for collision
for (int y = 0; y < cubicmap.height; y++)
// Check map collisions using image data and player position against surrounding cells only
for (int y = playerCellY - 1; y <= playerCellY + 1; y++)
{
for (int x = 0; x < cubicmap.width; x++)
// Avoid map accessing out of bounds
if ((y >= 0) && (y < cubicmap.height))
{
if ((mapPixels[y*cubicmap.width + x].r == 255) && // Collision: white pixel, only check R channel
for (int x = playerCellX - 1; x <= playerCellX + 1; x++)
{
// NOTE: Collision: Only checking R channel for white pixel
if (((x >= 0) && (x < cubicmap.width)) &&
(mapPixels[y*cubicmap.width + x].r == 255) &&
(CheckCollisionCircleRec(playerPos, playerRadius,
(Rectangle){ mapPosition.x - 0.5f + x*1.0f, mapPosition.z - 0.5f + y*1.0f, 1.0f, 1.0f })))
{
@ -95,6 +99,7 @@ int main(void)
}
}
}
}
//----------------------------------------------------------------------------------
// Draw

View File

@ -67,7 +67,7 @@ int main(void)
models[i] = LoadModel(voxFileNames[i]);
double t1 = GetTime()*1000.0;
TraceLog(LOG_WARNING, TextFormat("[%s] File loaded in %.3f ms", voxFileNames[i], t1 - t0));
TraceLog(LOG_INFO, TextFormat("[%s] Model file loaded in %.3f ms", voxFileNames[i], t1 - t0));
// Compute model translation matrix to center model on draw position (0, 0 , 0)
BoundingBox bb = GetModelBoundingBox(models[i]);
@ -80,6 +80,8 @@ int main(void)
}
int currentModel = 0;
Vector3 modelpos = { 0 };
Vector3 camerarot = { 0 };
// Load voxel shader
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION),
@ -98,11 +100,7 @@ int main(void)
// Assign out lighting shader to model
for (int i = 0; i < MAX_VOX_FILES; i++)
{
Model m = models[i];
for (int j = 0; j < m.materialCount; j++)
{
m.materials[j].shader = shader;
}
for (int j = 0; j < models[i].materialCount; j++) models[i].materials[j].shader = shader;
}
// Create lights
@ -112,12 +110,8 @@ int main(void)
lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader);
lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
Vector3 modelpos = { 0 };
Vector3 camerarot = { 0 };
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
@ -137,14 +131,10 @@ int main(void)
}
UpdateCameraPro(&camera,
(Vector3) {
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
0.0f // Move up-down
},
camerarot,
(Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left
0.0f }, // Move up-down
camerarot, // Camera rotation
GetMouseWheelMove()*-2.0f); // Move to target (zoom)
// Cycle between models on mouse click
@ -156,8 +146,8 @@ int main(void)
// Update light values (actually, only enable/disable them)
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
@ -166,7 +156,6 @@ int main(void)
// Draw 3D model
BeginMode3D(camera);
DrawModel(models[currentModel], modelpos, 1.0f, WHITE);
DrawGrid(10, 1.0);
@ -176,16 +165,15 @@ int main(void)
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color);
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f));
}
EndMode3D();
// Display info
DrawRectangle(10, 400, 340, 60, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(10, 400, 340, 60, Fade(DARKBLUE, 0.5f));
DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);
DrawText("MOUSE MIDDLE BUTTON to ZOOM OR ROTATE CAMERA", 40, 420, 10, BLUE);
DrawText("UP-DOWN-LEFT-RIGHT KEYS to MOVE CAMERA", 40, 430, 10, BLUE);
DrawText(TextFormat("File: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
DrawRectangle(10, 40, 340, 70, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(10, 40, 340, 70, Fade(DARKBLUE, 0.5f));
DrawText("- MOUSE LEFT BUTTON: CYCLE VOX MODELS", 20, 50, 10, BLUE);
DrawText("- MOUSE MIDDLE BUTTON: ZOOM OR ROTATE CAMERA", 20, 70, 10, BLUE);
DrawText("- UP-DOWN-LEFT-RIGHT KEYS: MOVE CAMERA", 20, 90, 10, BLUE);
DrawText(TextFormat("Model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
@ -201,5 +189,3 @@ int main(void)
return 0;
}

View File

@ -32,7 +32,7 @@ static Mesh GenMeshPoints(int numPoints);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main()
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
@ -57,7 +57,7 @@ int main()
Mesh mesh = GenMeshPoints(numPoints);
Model model = LoadModelFromMesh(mesh);
//SetTargetFPS(60);
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
@ -92,15 +92,12 @@ int main()
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(BLACK);
BeginMode3D(camera);
// The new method only uploads the points once to the GPU
if (useDrawModelPoints)
{
DrawModelPoints(model, position, 1.0f, WHITE);
}
if (useDrawModelPoints) DrawModelPoints(model, position, 1.0f, WHITE);
else
{
// The old method must continually draw the "points" (lines)
@ -124,17 +121,16 @@ int main()
// Draw a unit sphere for reference
DrawSphereWires(position, 1.0f, 10, 10, YELLOW);
EndMode3D();
// Draw UI text
DrawText(TextFormat("Point Count: %d", numPoints), 20, screenHeight - 50, 40, WHITE);
DrawText("Up - increase points", 20, 70, 20, WHITE);
DrawText("Down - decrease points", 20, 100, 20, WHITE);
DrawText("Space - drawing function", 20, 130, 20, WHITE);
DrawText(TextFormat("Point Count: %d", numPoints), 10, screenHeight - 50, 40, WHITE);
DrawText("UP - Increase points", 10, 40, 20, WHITE);
DrawText("DOWN - Decrease points", 10, 70, 20, WHITE);
DrawText("SPACE - Drawing function", 10, 100, 20, WHITE);
if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 20, 160, 20, GREEN);
else DrawText("Using: DrawPoint3D()", 20, 160, 20, RED);
if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 10, 130, 20, GREEN);
else DrawText("Using: DrawPoint3D()", 10, 130, 20, RED);
DrawFPS(10, 10);

View File

@ -148,25 +148,25 @@ void DrawSphereBasic(Color color)
{
for (int j = 0; j < slices; j++)
{
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)),
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)),
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360.0f/slices)),
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*i)),
cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*(i))),
cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)),
sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)),
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)),
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i))),
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)),
sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))),
cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices)));
}
}
rlEnd();

View File

@ -54,7 +54,8 @@ int main(void)
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
Model skybox = LoadModelFromMesh(cube);
// Set this to true to use an HDR Texture, Note that raylib must be built with HDR Support for this to work SUPPORT_FILEFORMAT_HDR
// Set this to true to use an HDR Texture
// NOTE: raylib must be built with HDR Support for this to work: SUPPORT_FILEFORMAT_HDR
bool useHDR = false;
// Load skybox shader and set required locations
@ -91,9 +92,11 @@ int main(void)
}
else
{
Image img = LoadImage("resources/skybox.png");
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT); // CUBEMAP_LAYOUT_PANORAMA
UnloadImage(img);
// TODO: WARNING: On PLATFORM_WEB it requires a big amount of memory to process input image
// and generate the required cubemap image to be passed to rlLoadTextureCubemap()
Image image = LoadImage("resources/skybox.png");
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
UnloadImage(image);
}
DisableCursor(); // Limit cursor to relative movement inside the window
@ -132,9 +135,9 @@ int main(void)
}
else
{
Image img = LoadImage(droppedFiles.paths[0]);
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT);
UnloadImage(img);
Image image = LoadImage(droppedFiles.paths[0]);
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
UnloadImage(image);
}
TextCopy(skyboxFileName, droppedFiles.paths[0]);

View File

@ -22,7 +22,7 @@
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main()
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
@ -85,9 +85,9 @@ int main()
// Calculate the cube position
Vector3 cubePos = {
(float)(x - numBlocks/2)*(scale*3.0f) + scatter,
(float)(y - numBlocks/2)*(scale*2.0f) + scatter,
(float)(z - numBlocks/2)*(scale*3.0f) + scatter
(float)(x - (float)numBlocks/2)*(scale*3.0f) + scatter,
(float)(y - (float)numBlocks/2)*(scale*2.0f) + scatter,
(float)(z - (float)numBlocks/2)*(scale*3.0f) + scatter
};
// Pick a color with a hue depending on cube position for the rainbow color effect

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -30,6 +30,7 @@
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL)
#if defined(GRAPHICS_API_OPENGL_ES2)
#define GLAD_GLES2_IMPLEMENTATION
#include "glad_gles2.h" // Required for: OpenGL functionality
#define glGenVertexArrays glGenVertexArraysOES
#define glBindVertexArray glBindVertexArrayOES

View File

@ -36,7 +36,7 @@ void UpdateDrawFrame(void); // Update and Draw one frame
//----------------------------------------------------------------------------------
// Program main entry point
//----------------------------------------------------------------------------------
int main()
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------

5987
examples/shaders/raygui.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,3 +11,6 @@
| texel_checker.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [UV Checker Map Maker](http://uvchecker.byvalle.com/) |
| cubicmap.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| spark_flame.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [EffectTextureMaker](https://mebiusbox.github.io/contents/EffectTextureMaker/) |
| parrots.png | [Kodak set](http://r0k.us/graphics/kodak/) | ❔ | Original name: `kodim23.png` |
| cat.png | ❔ | ❔ | - |
| mandrill.png | ❔ | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Mandrill (a.k.a. Baboon) |

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

View File

@ -0,0 +1,34 @@
#version 100
precision mediump float;
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
uniform float contrast;
uniform float saturation;
uniform float brightness;
void main()
{
// Get texel color
vec4 texel = texture2D(texture0, fragTexCoord);
// Apply contrast
texel.rgb = (texel.rgb - 0.5)*(contrast/100.0 + 1.0) + 0.5;
// Apply brightness
texel.rgb = texel.rgb + brightness/100.0;
// Apply saturation
float intensity = dot(texel.rgb, vec3(0.299, 0.587, 0.114));
texel.rgb = (texel.rgb - intensity)*saturation/100.0 + texel.rgb;
// Output resulting color
gl_FragColor = texel;
}

View File

@ -36,7 +36,7 @@ void main()
vec3 ambient = albedo*vec3(0.1);
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;
vec3 lightDirection = lights[i].position - fragPosition;

View File

@ -0,0 +1,44 @@
#version 100
precision highp float;
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// Input size in pixels of the textures
uniform vec2 resolution;
void main()
{
// Size of one pixel in texture coordinates (from 0.0 to 1.0)
float x = 1.0/resolution.x;
float y = 1.0/resolution.y;
// Status of the current cell (1 = alive, 0 = dead)
int origValue = (texture2D(texture0, fragTexCoord).r < 0.1)? 1 : 0;
// Sum of alive neighbors
int sumValue = (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left
sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top
sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right
sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left
sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right
// Game of life rules:
// Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise
// Current cell goes from dead to alive when exactly 3 neighbors are alive
if ((origValue == 1 && sumValue == 2) || sumValue == 3)
gl_FragColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black
else
gl_FragColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE
}

View File

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

View File

@ -2,6 +2,9 @@
#extension GL_EXT_frag_depth : enable //Extension required for writing depth
#extension GL_OES_standard_derivatives : enable //Extension used for fwidth()
#define ZERO 0
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
// Input vertex attributes (from vertex shader)
@ -17,8 +20,6 @@ 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)
{
@ -257,7 +258,8 @@ vec4 render(in vec3 ro, in vec3 rd)
return vec4(vec3(clamp(col,0.0,1.0)),t);
}
vec3 CalcRayDir(vec2 nCoord){
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);
@ -287,6 +289,7 @@ void main()
color = res.xyz;
depth = CalcDepth(rd,res.w);
}
gl_FragColor = vec4(color , 1.0);
gl_FragDepthEXT = depth;
}

View File

@ -34,7 +34,7 @@ void main()
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
for (int iter = 0; iter < maxIterationsLimit; ++iter)
for (int iter = 0; iter < maxIterationsLimit; iter++)
{
float aa = a*a;
float bb = b*b;

View File

@ -1,9 +1,9 @@
#version 100
precision mediump float;
#extension GL_OES_standard_derivatives : enable
precision mediump float;
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;

View File

@ -19,7 +19,8 @@ uniform float ampY;
uniform float speedX;
uniform float speedY;
void main() {
void main()
{
float pixelWidth = 1.0/size.x;
float pixelHeight = 1.0/size.y;
float aspect = pixelHeight/pixelWidth;

View File

@ -0,0 +1,31 @@
#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 contrast;
uniform float saturation;
uniform float brightness;
void main()
{
vec4 texel = texture2D(texture0, fragTexCoord); // Get texel color
// Apply contrast
texel.rgb = (texel.rgb - 0.5)*(contrast/100.0 + 1.0) + 0.5;
// Apply brightness
texel.rgb = texel.rgb + brightness/100.0;
// Apply saturation
float intensity = dot(texel.rgb, vec3(0.299, 0.587, 0.114));
texel.rgb = (texel.rgb - intensity)*saturation/100.0 + texel.rgb;
// Output resulting color
gl_FragColor = texel;
}

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