Merge branch 'raysan5:master' into master
This commit is contained in:
commit
078656f85a
|
|
@ -9,7 +9,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||||
| [raylib](https://github.com/raysan5/raylib) | **5.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
| [raylib](https://github.com/raysan5/raylib) | **5.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
||||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.0** | [Beef](https://www.beeflang.org) | MIT |
|
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.0** | [Beef](https://www.beeflang.org) | MIT |
|
||||||
| [raylib-boo](https://github.com/Rabios/raylib-boo) | 3.7 | [Boo](http://boo-language.github.io) | MIT |
|
| [raylib-boo](https://github.com/Rabios/raylib-boo) | 3.7 | [Boo](http://boo-language.github.io) | MIT |
|
||||||
| [raybit](https://github.com/Alex-Velez/raybit) | 3.7 | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||||
| [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
| [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
|
||||||
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||||
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
|
||||||
|
|
@ -31,7 +31,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||||
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.0** | [Go](https://golang.org) | Zlib |
|
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.0** | [Go](https://golang.org) | Zlib |
|
||||||
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
|
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
|
||||||
| [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** |
|
| [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** |
|
||||||
| [h-raylib](https://github.com/Anut-py/h-raylib) | **5.1-dev** | [Haskell](https://haskell.org) | Apache-2.0 |
|
| [h-raylib](https://github.com/Anut-py/h-raylib) | **5.5-dev** | [Haskell](https://haskell.org) | Apache-2.0 |
|
||||||
| [raylib-hx](https://github.com/foreignsasquatch/raylib-hx) | 4.2 | [Haxe](https://haxe.org) | Zlib |
|
| [raylib-hx](https://github.com/foreignsasquatch/raylib-hx) | 4.2 | [Haxe](https://haxe.org) | Zlib |
|
||||||
| [hb-raylib](https://github.com/MarcosLeonardoMendezGerencir/hb-raylib) | 3.5 | [Harbour](https://harbour.github.io) | MIT |
|
| [hb-raylib](https://github.com/MarcosLeonardoMendezGerencir/hb-raylib) | 3.5 | [Harbour](https://harbour.github.io) | MIT |
|
||||||
| [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT |
|
| [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT |
|
||||||
|
|
@ -78,10 +78,10 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||||
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
|
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
|
||||||
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
|
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
|
||||||
| [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD |
|
| [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD |
|
||||||
| [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **auto** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
| [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 |
|
| [rayjs](https://github.com/mode777/rayjs) | 4.6-dev | [QuickJS](https://bellard.org/quickjs) | MIT |
|
||||||
| [raylib-raku](https://github.com/vushu/raylib-raku) | **auto** | [Raku](https://www.raku.org) | Artistic License 2.0 |
|
| [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) | 4.5 | [Lean4](https://lean-lang.org) | BSD-3-Clause |
|
| [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 |
|
| [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain |
|
||||||
| [raylib-apl](https://github.com/Brian-ED/raylib-apl) | **5.0** | [Dyalog APL](https://www.dyalog.com/) | MIT |
|
| [raylib-apl](https://github.com/Brian-ED/raylib-apl) | **5.0** | [Dyalog APL](https://www.dyalog.com/) | MIT |
|
||||||
|
|
||||||
|
|
@ -92,6 +92,7 @@ These are utility wrappers for specific languages, they are not required to use
|
||||||
| ---------------------------------------------------- | :------------: | :------------------------------------------: | :-----: |
|
| ---------------------------------------------------- | :------------: | :------------------------------------------: | :-----: |
|
||||||
| [raylib-cpp](https://github.com/robloach/raylib-cpp) | **5.0** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib |
|
| [raylib-cpp](https://github.com/robloach/raylib-cpp) | **5.0** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib |
|
||||||
| [claylib](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
|
| [claylib](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
|
||||||
|
| [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
|
||||||
|
|
||||||
### Older or Unmaintained Language Bindings
|
### Older or Unmaintained Language Bindings
|
||||||
|
|
||||||
|
|
|
||||||
11
CHANGELOG
11
CHANGELOG
|
|
@ -3,6 +3,17 @@ changelog
|
||||||
|
|
||||||
Current Release: raylib 5.0 (18 November 2023)
|
Current Release: raylib 5.0 (18 November 2023)
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
Release: raylib 5.5 - 11th Anniversary Edition? (18 November 2024?)
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
KEY CHANGES:
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
|
||||||
|
Detailed changes:
|
||||||
|
...
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
Release: raylib 5.0 - 10th Anniversary Edition (18 November 2023)
|
Release: raylib 5.0 - 10th Anniversary Edition (18 November 2023)
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
|
|
||||||
437
build.zig
437
build.zig
|
|
@ -1,11 +1,434 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const raylib = @import("src/build.zig");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
// This has been tested to work with zig 0.12.0
|
/// Minimum supported version of Zig
|
||||||
pub fn build(b: *std.Build) !void {
|
const min_ver = "0.12.0";
|
||||||
try raylib.build(b);
|
|
||||||
|
comptime {
|
||||||
|
const order = std.SemanticVersion.order;
|
||||||
|
const parse = std.SemanticVersion.parse;
|
||||||
|
if (order(builtin.zig_version, parse(min_ver) catch unreachable) == .lt)
|
||||||
|
@compileError("Raylib requires zig version " ++ min_ver);
|
||||||
}
|
}
|
||||||
|
|
||||||
// expose helper functions to user's build.zig
|
// NOTE(freakmangd): I don't like using a global here, but it prevents having to
|
||||||
pub const addRaylib = raylib.addRaylib;
|
// get the flags a second time when adding raygui
|
||||||
pub const addRaygui = raylib.addRaygui;
|
var raylib_flags_arr: std.ArrayListUnmanaged([]const u8) = .{};
|
||||||
|
|
||||||
|
// This has been tested with zig version 0.12.0
|
||||||
|
pub fn addRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||||
|
const raylib_dep = b.dependencyFromBuildZig(@This(), .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.raudio = options.raudio,
|
||||||
|
.rmodels = options.rmodels,
|
||||||
|
.rshapes = options.rshapes,
|
||||||
|
.rtext = options.rtext,
|
||||||
|
.rtextures = options.rtextures,
|
||||||
|
.platform = options.platform,
|
||||||
|
.shared = options.shared,
|
||||||
|
.linux_display_backend = options.linux_display_backend,
|
||||||
|
.opengl_version = options.opengl_version,
|
||||||
|
.config = options.config,
|
||||||
|
});
|
||||||
|
const raylib = raylib_dep.artifact("raylib");
|
||||||
|
|
||||||
|
if (options.raygui) {
|
||||||
|
const raygui_dep = b.dependency(options.raygui_dependency_name, .{});
|
||||||
|
addRaygui(b, raylib, raygui_dep);
|
||||||
|
}
|
||||||
|
|
||||||
|
return raylib;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend) void {
|
||||||
|
raylib.defineCMacro("PLATFORM_DESKTOP", null);
|
||||||
|
|
||||||
|
switch (platform) {
|
||||||
|
.glfw => raylib.defineCMacro("PLATFORM_DESKTOP_GLFW", null),
|
||||||
|
.rgfw => raylib.defineCMacro("PLATFORM_DESKTOP_RGFW", null),
|
||||||
|
.sdl => raylib.defineCMacro("PLATFORM_DESKTOP_SDL", null),
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A list of all flags from `src/config.h` that one may override
|
||||||
|
const config_h_flags = outer: {
|
||||||
|
// Set this value higher if compile errors happen as `src/config.h` gets larger
|
||||||
|
@setEvalBranchQuota(1 << 20);
|
||||||
|
|
||||||
|
const config_h = @embedFile("src/config.h");
|
||||||
|
var flags: [std.mem.count(u8, config_h, "\n") + 1][]const u8 = undefined;
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
var lines = std.mem.tokenizeScalar(u8, config_h, '\n');
|
||||||
|
while (lines.next()) |line| {
|
||||||
|
if (!std.mem.containsAtLeast(u8, line, 1, "SUPPORT")) continue;
|
||||||
|
if (std.mem.startsWith(u8, line, "//")) continue;
|
||||||
|
if (std.mem.startsWith(u8, line, "#if")) continue;
|
||||||
|
|
||||||
|
var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace
|
||||||
|
flag = flag["#define ".len - 1 ..]; // Remove #define
|
||||||
|
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace
|
||||||
|
flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
|
||||||
|
flag = "-D" ++ flag; // Prepend with -D
|
||||||
|
|
||||||
|
flags[i] = flag;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncomment this to check what flags normally get passed
|
||||||
|
//@compileLog(flags[0..i].*);
|
||||||
|
break :outer flags[0..i].*;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||||
|
raylib_flags_arr.clearRetainingCapacity();
|
||||||
|
|
||||||
|
const shared_flags = &[_][]const u8{
|
||||||
|
"-fPIC",
|
||||||
|
"-DBUILD_LIBTYPE_SHARED",
|
||||||
|
};
|
||||||
|
try raylib_flags_arr.appendSlice(b.allocator, &[_][]const u8{
|
||||||
|
"-std=gnu99",
|
||||||
|
"-D_GNU_SOURCE",
|
||||||
|
"-DGL_SILENCE_DEPRECATION=199309L",
|
||||||
|
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
|
||||||
|
});
|
||||||
|
if (options.config.len > 0) {
|
||||||
|
// Sets a flag indiciating 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.
|
||||||
|
// `-xc++` or similar should be used when possible
|
||||||
|
var config_iter = std.mem.tokenizeScalar(u8, options.config, ' ');
|
||||||
|
|
||||||
|
// Apply config flags supplied by the user
|
||||||
|
while (config_iter.next()) |config_flag|
|
||||||
|
try raylib_flags_arr.append(b.allocator, config_flag);
|
||||||
|
|
||||||
|
// Apply all relevant configs from `src/config.h` *except* the user-specified ones
|
||||||
|
//
|
||||||
|
// Note: Currently using a suboptimal `O(m*n)` time algorithm where:
|
||||||
|
// `m` corresponds roughly to the number of lines in `src/config.h`
|
||||||
|
// `n` corresponds to the number of user-specified flags
|
||||||
|
outer: for (config_h_flags) |flag| {
|
||||||
|
// If a user already specified the flag, skip it
|
||||||
|
while (config_iter.next()) |config_flag| {
|
||||||
|
// For a user-specified flag to match, it must share the same prefix and have the
|
||||||
|
// same length or be followed by an equals sign
|
||||||
|
if (!std.mem.startsWith(u8, config_flag, flag)) continue;
|
||||||
|
if (config_flag.len == flag.len or config_flag[flag.len] == '=') continue :outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, append default value from config.h to compile flags
|
||||||
|
try raylib_flags_arr.append(b.allocator, flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.shared) {
|
||||||
|
try raylib_flags_arr.appendSlice(b.allocator, shared_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
const raylib = if (options.shared)
|
||||||
|
b.addSharedLibrary(.{
|
||||||
|
.name = "raylib",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
})
|
||||||
|
else
|
||||||
|
b.addStaticLibrary(.{
|
||||||
|
.name = "raylib",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
raylib.linkLibC();
|
||||||
|
|
||||||
|
// No GLFW required on PLATFORM_DRM
|
||||||
|
if (options.platform != .drm) {
|
||||||
|
raylib.addIncludePath(b.path("src/external/glfw/include"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var c_source_files = try std.ArrayList([]const u8).initCapacity(b.allocator, 2);
|
||||||
|
c_source_files.appendSliceAssumeCapacity(&.{ "src/rcore.c", "src/utils.c" });
|
||||||
|
|
||||||
|
if (options.raudio) {
|
||||||
|
try c_source_files.append("src/raudio.c");
|
||||||
|
}
|
||||||
|
if (options.rmodels) {
|
||||||
|
try c_source_files.append("src/rmodels.c");
|
||||||
|
}
|
||||||
|
if (options.rshapes) {
|
||||||
|
try c_source_files.append("src/rshapes.c");
|
||||||
|
}
|
||||||
|
if (options.rtext) {
|
||||||
|
try c_source_files.append("src/rtext.c");
|
||||||
|
}
|
||||||
|
if (options.rtextures) {
|
||||||
|
try c_source_files.append("src/rtextures.c");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.opengl_version != .auto) {
|
||||||
|
raylib.defineCMacro(options.opengl_version.toCMacroStr(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (target.result.os.tag) {
|
||||||
|
.windows => {
|
||||||
|
try c_source_files.append("src/rglfw.c");
|
||||||
|
raylib.linkSystemLibrary("winmm");
|
||||||
|
raylib.linkSystemLibrary("gdi32");
|
||||||
|
raylib.linkSystemLibrary("opengl32");
|
||||||
|
|
||||||
|
setDesktopPlatform(raylib, options.platform);
|
||||||
|
},
|
||||||
|
.linux => {
|
||||||
|
if (options.platform != .drm) {
|
||||||
|
try c_source_files.append("src/rglfw.c");
|
||||||
|
raylib.linkSystemLibrary("GL");
|
||||||
|
raylib.linkSystemLibrary("rt");
|
||||||
|
raylib.linkSystemLibrary("dl");
|
||||||
|
raylib.linkSystemLibrary("m");
|
||||||
|
|
||||||
|
raylib.addLibraryPath(.{ .cwd_relative = "/usr/lib" });
|
||||||
|
raylib.addIncludePath(.{ .cwd_relative = "/usr/include" });
|
||||||
|
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
||||||
|
raylib.defineCMacro("_GLFW_X11", null);
|
||||||
|
raylib.linkSystemLibrary("X11");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
|
||||||
|
_ = b.findProgram(&.{"wayland-scanner"}, &.{}) catch {
|
||||||
|
std.log.err(
|
||||||
|
\\ `wayland-scanner` may not be installed on the system.
|
||||||
|
\\ You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend`
|
||||||
|
, .{});
|
||||||
|
@panic("`wayland-scanner` not found");
|
||||||
|
};
|
||||||
|
raylib.defineCMacro("_GLFW_WAYLAND", null);
|
||||||
|
raylib.linkSystemLibrary("wayland-client");
|
||||||
|
raylib.linkSystemLibrary("wayland-cursor");
|
||||||
|
raylib.linkSystemLibrary("wayland-egl");
|
||||||
|
raylib.linkSystemLibrary("xkbcommon");
|
||||||
|
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
|
||||||
|
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
|
||||||
|
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
|
||||||
|
waylandGenerate(b, raylib, "viewporter.xml", "viewporter-client-protocol");
|
||||||
|
waylandGenerate(b, raylib, "relative-pointer-unstable-v1.xml", "relative-pointer-unstable-v1-client-protocol");
|
||||||
|
waylandGenerate(b, raylib, "pointer-constraints-unstable-v1.xml", "pointer-constraints-unstable-v1-client-protocol");
|
||||||
|
waylandGenerate(b, raylib, "fractional-scale-v1.xml", "fractional-scale-v1-client-protocol");
|
||||||
|
waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol");
|
||||||
|
waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol");
|
||||||
|
}
|
||||||
|
setDesktopPlatform(raylib, options.platform);
|
||||||
|
} else {
|
||||||
|
if (options.opengl_version == .auto) {
|
||||||
|
raylib.linkSystemLibrary("GLESv2");
|
||||||
|
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
raylib.linkSystemLibrary("EGL");
|
||||||
|
raylib.linkSystemLibrary("drm");
|
||||||
|
raylib.linkSystemLibrary("gbm");
|
||||||
|
raylib.linkSystemLibrary("pthread");
|
||||||
|
raylib.linkSystemLibrary("rt");
|
||||||
|
raylib.linkSystemLibrary("m");
|
||||||
|
raylib.linkSystemLibrary("dl");
|
||||||
|
raylib.addIncludePath(.{ .cwd_relative = "/usr/include/libdrm" });
|
||||||
|
|
||||||
|
raylib.defineCMacro("PLATFORM_DRM", null);
|
||||||
|
raylib.defineCMacro("EGL_NO_X11", null);
|
||||||
|
raylib.defineCMacro("DEFAULT_BATCH_BUFFER_ELEMENT", "2048");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.freebsd, .openbsd, .netbsd, .dragonfly => {
|
||||||
|
try c_source_files.append("rglfw.c");
|
||||||
|
raylib.linkSystemLibrary("GL");
|
||||||
|
raylib.linkSystemLibrary("rt");
|
||||||
|
raylib.linkSystemLibrary("dl");
|
||||||
|
raylib.linkSystemLibrary("m");
|
||||||
|
raylib.linkSystemLibrary("X11");
|
||||||
|
raylib.linkSystemLibrary("Xrandr");
|
||||||
|
raylib.linkSystemLibrary("Xinerama");
|
||||||
|
raylib.linkSystemLibrary("Xi");
|
||||||
|
raylib.linkSystemLibrary("Xxf86vm");
|
||||||
|
raylib.linkSystemLibrary("Xcursor");
|
||||||
|
|
||||||
|
setDesktopPlatform(raylib, options.platform);
|
||||||
|
},
|
||||||
|
.macos => {
|
||||||
|
// On macos rglfw.c include Objective-C files.
|
||||||
|
try raylib_flags_arr.append(b.allocator, "-ObjC");
|
||||||
|
raylib.root_module.addCSourceFile(.{
|
||||||
|
.file = b.path("src/rglfw.c"),
|
||||||
|
.flags = raylib_flags_arr.items,
|
||||||
|
});
|
||||||
|
_ = raylib_flags_arr.pop();
|
||||||
|
raylib.linkFramework("Foundation");
|
||||||
|
raylib.linkFramework("CoreServices");
|
||||||
|
raylib.linkFramework("CoreGraphics");
|
||||||
|
raylib.linkFramework("AppKit");
|
||||||
|
raylib.linkFramework("IOKit");
|
||||||
|
|
||||||
|
setDesktopPlatform(raylib, options.platform);
|
||||||
|
},
|
||||||
|
.emscripten => {
|
||||||
|
raylib.defineCMacro("PLATFORM_WEB", null);
|
||||||
|
if (options.opengl_version == .auto) {
|
||||||
|
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.sysroot == null) {
|
||||||
|
@panic("Pass '--sysroot \"$EMSDK/upstream/emscripten\"'");
|
||||||
|
}
|
||||||
|
|
||||||
|
const cache_include = b.pathJoin(&.{ b.sysroot.?, "cache", "sysroot", "include" });
|
||||||
|
|
||||||
|
var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!");
|
||||||
|
dir.close();
|
||||||
|
raylib.addIncludePath(.{ .cwd_relative = cache_include });
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
@panic("Unsupported OS");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
raylib.root_module.addCSourceFiles(.{
|
||||||
|
.files = c_source_files.items,
|
||||||
|
.flags = raylib_flags_arr.items,
|
||||||
|
});
|
||||||
|
|
||||||
|
return raylib;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function does not need to be called if you passed .raygui = true to addRaylib
|
||||||
|
pub fn addRaygui(b: *std.Build, raylib: *std.Build.Step.Compile, raygui_dep: *std.Build.Dependency) void {
|
||||||
|
if (raylib_flags_arr.items.len == 0) {
|
||||||
|
@panic(
|
||||||
|
\\argument 2 `raylib` in `addRaygui` must come from b.dependency("raylib", ...).artifact("raylib")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var gen_step = b.addWriteFiles();
|
||||||
|
raylib.step.dependOn(&gen_step.step);
|
||||||
|
|
||||||
|
const raygui_c_path = gen_step.add("raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n");
|
||||||
|
raylib.addCSourceFile(.{ .file = raygui_c_path, .flags = raylib_flags_arr.items });
|
||||||
|
raylib.addIncludePath(raygui_dep.path("src"));
|
||||||
|
|
||||||
|
raylib.installHeader(raygui_dep.path("src/raygui.h"), "raygui.h");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Options = struct {
|
||||||
|
raudio: bool = true,
|
||||||
|
rmodels: bool = true,
|
||||||
|
rshapes: bool = true,
|
||||||
|
rtext: bool = true,
|
||||||
|
rtextures: bool = true,
|
||||||
|
raygui: bool = false,
|
||||||
|
platform: PlatformBackend = .glfw,
|
||||||
|
shared: bool = false,
|
||||||
|
linux_display_backend: LinuxDisplayBackend = .Both,
|
||||||
|
opengl_version: OpenglVersion = .auto,
|
||||||
|
/// config should be a list of space-separated cflags, eg, "-DSUPPORT_CUSTOM_FRAME_CONTROL"
|
||||||
|
config: []const u8 = &.{},
|
||||||
|
|
||||||
|
raygui_dependency_name: []const u8 = "raygui",
|
||||||
|
|
||||||
|
const defaults = Options{};
|
||||||
|
|
||||||
|
fn getOptions(b: *std.Build) Options {
|
||||||
|
return .{
|
||||||
|
.platform = b.option(PlatformBackend, "platform", "Choose the platform backedn for desktop target") orelse defaults.platform,
|
||||||
|
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
|
||||||
|
.raygui = b.option(bool, "raygui", "Compile with raygui support") orelse defaults.raygui,
|
||||||
|
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
|
||||||
|
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
|
||||||
|
.rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures,
|
||||||
|
.rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes,
|
||||||
|
.shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared,
|
||||||
|
.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 &.{},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const OpenglVersion = enum {
|
||||||
|
auto,
|
||||||
|
gl_1_1,
|
||||||
|
gl_2_1,
|
||||||
|
gl_3_3,
|
||||||
|
gl_4_3,
|
||||||
|
gles_2,
|
||||||
|
gles_3,
|
||||||
|
|
||||||
|
pub fn toCMacroStr(self: @This()) []const u8 {
|
||||||
|
switch (self) {
|
||||||
|
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
|
||||||
|
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
|
||||||
|
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
|
||||||
|
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
|
||||||
|
.gl_4_3 => return "GRAPHICS_API_OPENGL_43",
|
||||||
|
.gles_2 => return "GRAPHICS_API_OPENGL_ES2",
|
||||||
|
.gles_3 => return "GRAPHICS_API_OPENGL_ES3",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const LinuxDisplayBackend = enum {
|
||||||
|
X11,
|
||||||
|
Wayland,
|
||||||
|
Both,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PlatformBackend = enum {
|
||||||
|
glfw,
|
||||||
|
rgfw,
|
||||||
|
sdl,
|
||||||
|
drm,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) !void {
|
||||||
|
// Standard target options allows the person running `zig build` to choose
|
||||||
|
// what target to build for. Here we do not override the defaults, which
|
||||||
|
// means any target is allowed, and the default is native. Other options
|
||||||
|
// for restricting supported target set are available.
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
// Standard optimization options allow the person running `zig build` to select
|
||||||
|
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
||||||
|
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const lib = try compileRaylib(b, target, optimize, Options.getOptions(b));
|
||||||
|
|
||||||
|
lib.installHeader(b.path("src/raylib.h"), "raylib.h");
|
||||||
|
lib.installHeader(b.path("src/raymath.h"), "raymath.h");
|
||||||
|
lib.installHeader(b.path("src/rlgl.h"), "rlgl.h");
|
||||||
|
|
||||||
|
b.installArtifact(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn waylandGenerate(
|
||||||
|
b: *std.Build,
|
||||||
|
raylib: *std.Build.Step.Compile,
|
||||||
|
comptime protocol: []const u8,
|
||||||
|
comptime basename: []const u8,
|
||||||
|
) void {
|
||||||
|
const waylandDir = "src/external/glfw/deps/wayland";
|
||||||
|
const protocolDir = b.pathJoin(&.{ waylandDir, protocol });
|
||||||
|
const clientHeader = basename ++ ".h";
|
||||||
|
const privateCode = basename ++ "-code.h";
|
||||||
|
|
||||||
|
const client_step = b.addSystemCommand(&.{ "wayland-scanner", "client-header" });
|
||||||
|
client_step.addFileArg(b.path(protocolDir));
|
||||||
|
raylib.addIncludePath(client_step.addOutputFileArg(clientHeader).dirname());
|
||||||
|
|
||||||
|
const private_step = b.addSystemCommand(&.{ "wayland-scanner", "private-code" });
|
||||||
|
private_step.addFileArg(b.path(protocolDir));
|
||||||
|
raylib.addIncludePath(private_step.addOutputFileArg(privateCode).dirname());
|
||||||
|
|
||||||
|
raylib.step.dependOn(&client_step.step);
|
||||||
|
raylib.step.dependOn(&private_step.step);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,9 +100,10 @@ elseif ("${PLATFORM}" MATCHES "SDL")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||||
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
|
set(SUGGESTED_GRAPHICS "${GRAPHICS}")
|
||||||
|
|
||||||
if (${OPENGL_VERSION} MATCHES "4.3")
|
if (${OPENGL_VERSION} MATCHES "4.3")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_43")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_43")
|
||||||
elseif (${OPENGL_VERSION} MATCHES "3.3")
|
elseif (${OPENGL_VERSION} MATCHES "3.3")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
||||||
elseif (${OPENGL_VERSION} MATCHES "2.1")
|
elseif (${OPENGL_VERSION} MATCHES "2.1")
|
||||||
|
|
@ -114,8 +115,8 @@ if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||||
elseif (${OPENGL_VERSION} MATCHES "ES 3.0")
|
elseif (${OPENGL_VERSION} MATCHES "ES 3.0")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES3")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES3")
|
||||||
endif ()
|
endif ()
|
||||||
if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
if (NOT "${SUGGESTED_GRAPHICS}" STREQUAL "" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
||||||
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail")
|
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail.")
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,9 @@ RAYLIB_SRC_PATH ?= ../src
|
||||||
|
|
||||||
# Locations of raylib.h and libraylib.a/libraylib.so
|
# Locations of raylib.h and libraylib.a/libraylib.so
|
||||||
# NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD
|
# NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD
|
||||||
RAYLIB_INCLUDE_PATH ?= /usr/local/include
|
DESTDIR ?= /usr/local
|
||||||
RAYLIB_LIB_PATH ?= /usr/local/lib
|
RAYLIB_INCLUDE_PATH ?= $(DESTDIR)/include
|
||||||
|
RAYLIB_LIB_PATH ?= $(DESTDIR)/lib
|
||||||
|
|
||||||
# Library type compilation: STATIC (.a) or SHARED (.so/.dll)
|
# Library type compilation: STATIC (.a) or SHARED (.so/.dll)
|
||||||
RAYLIB_LIBTYPE ?= STATIC
|
RAYLIB_LIBTYPE ?= STATIC
|
||||||
|
|
@ -491,6 +492,7 @@ CORE = \
|
||||||
core/core_input_mouse \
|
core/core_input_mouse \
|
||||||
core/core_input_mouse_wheel \
|
core/core_input_mouse_wheel \
|
||||||
core/core_input_multitouch \
|
core/core_input_multitouch \
|
||||||
|
core/core_input_virtual_controls \
|
||||||
core/core_loading_thread \
|
core/core_loading_thread \
|
||||||
core/core_random_sequence \
|
core/core_random_sequence \
|
||||||
core/core_random_values \
|
core/core_random_values \
|
||||||
|
|
@ -547,7 +549,6 @@ TEXTURES = \
|
||||||
textures/textures_sprite_button \
|
textures/textures_sprite_button \
|
||||||
textures/textures_sprite_explosion \
|
textures/textures_sprite_explosion \
|
||||||
textures/textures_srcrec_dstrec \
|
textures/textures_srcrec_dstrec \
|
||||||
textures/textures_svg_loading \
|
|
||||||
textures/textures_textured_curve \
|
textures/textures_textured_curve \
|
||||||
textures/textures_to_image
|
textures/textures_to_image
|
||||||
|
|
||||||
|
|
@ -582,10 +583,12 @@ MODELS = \
|
||||||
models/models_mesh_generation \
|
models/models_mesh_generation \
|
||||||
models/models_mesh_picking \
|
models/models_mesh_picking \
|
||||||
models/models_orthographic_projection \
|
models/models_orthographic_projection \
|
||||||
|
models/models_point_rendering \
|
||||||
models/models_rlgl_solar_system \
|
models/models_rlgl_solar_system \
|
||||||
models/models_skybox \
|
models/models_skybox \
|
||||||
models/models_waving_cubes \
|
models/models_waving_cubes \
|
||||||
models/models_yaw_pitch_roll
|
models/models_yaw_pitch_roll \
|
||||||
|
models/models_gpu_skinning
|
||||||
|
|
||||||
SHADERS = \
|
SHADERS = \
|
||||||
shaders/shaders_basic_lighting \
|
shaders/shaders_basic_lighting \
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,9 @@ RAYLIB_PATH ?= ..
|
||||||
|
|
||||||
# Locations of raylib.h and libraylib.a/libraylib.so
|
# Locations of raylib.h and libraylib.a/libraylib.so
|
||||||
# NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD
|
# NOTE: Those variables are only used for PLATFORM_OS: LINUX, BSD
|
||||||
RAYLIB_INCLUDE_PATH ?= /usr/local/include
|
DESTDIR ?= /usr/local
|
||||||
RAYLIB_LIB_PATH ?= /usr/local/lib
|
RAYLIB_INCLUDE_PATH ?= $(DESTDIR)/include
|
||||||
|
RAYLIB_LIB_PATH ?= $(DESTDIR)/lib
|
||||||
|
|
||||||
# Library type compilation: STATIC (.a) or SHARED (.so/.dll)
|
# Library type compilation: STATIC (.a) or SHARED (.so/.dll)
|
||||||
RAYLIB_LIBTYPE ?= STATIC
|
RAYLIB_LIBTYPE ?= STATIC
|
||||||
|
|
@ -358,6 +359,7 @@ CORE = \
|
||||||
core/core_input_mouse \
|
core/core_input_mouse \
|
||||||
core/core_input_mouse_wheel \
|
core/core_input_mouse_wheel \
|
||||||
core/core_input_multitouch \
|
core/core_input_multitouch \
|
||||||
|
core/core_input_virtual_controls \
|
||||||
core/core_loading_thread \
|
core/core_loading_thread \
|
||||||
core/core_random_sequence \
|
core/core_random_sequence \
|
||||||
core/core_random_values \
|
core/core_random_values \
|
||||||
|
|
@ -413,7 +415,6 @@ TEXTURES = \
|
||||||
textures/textures_sprite_button \
|
textures/textures_sprite_button \
|
||||||
textures/textures_sprite_explosion \
|
textures/textures_sprite_explosion \
|
||||||
textures/textures_srcrec_dstrec \
|
textures/textures_srcrec_dstrec \
|
||||||
textures/textures_svg_loading \
|
|
||||||
textures/textures_textured_curve \
|
textures/textures_textured_curve \
|
||||||
textures/textures_to_image
|
textures/textures_to_image
|
||||||
|
|
||||||
|
|
@ -447,6 +448,7 @@ MODELS = \
|
||||||
models/models_mesh_generation \
|
models/models_mesh_generation \
|
||||||
models/models_mesh_picking \
|
models/models_mesh_picking \
|
||||||
models/models_orthographic_projection \
|
models/models_orthographic_projection \
|
||||||
|
models/models_point_rendering \
|
||||||
models/models_rlgl_solar_system \
|
models/models_rlgl_solar_system \
|
||||||
models/models_skybox \
|
models/models_skybox \
|
||||||
models/models_waving_cubes \
|
models/models_waving_cubes \
|
||||||
|
|
@ -773,10 +775,6 @@ textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file textures/resources/scarfy.png@resources/scarfy.png
|
--preload-file textures/resources/scarfy.png@resources/scarfy.png
|
||||||
|
|
||||||
textures/textures_svg_loading: textures/textures_svg_loading.c
|
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
|
||||||
--preload-file textures/resources/test.svg
|
|
||||||
|
|
||||||
textures/textures_textured_curve: textures/textures_textured_curve.c
|
textures/textures_textured_curve: textures/textures_textured_curve.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file textures/resources/road.png@resources/road.png
|
--preload-file textures/resources/road.png@resources/road.png
|
||||||
|
|
|
||||||
|
|
@ -31,31 +31,32 @@ Examples using raylib core platform functionality like window creation, inputs,
|
||||||
| 05 | [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐️☆☆☆ | 1.1 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 05 | [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐️☆☆☆ | 1.1 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 06 | [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐️☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) |
|
| 06 | [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐️☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) |
|
||||||
| 07 | [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 07 | [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 08 | [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐️⭐️☆☆ | 1.5 | 3.0 | [Ray](https://github.com/raysan5) |
|
| 08 | [core_input_virtual_controls](core/core_input_virtual_controls.c) | <img src="core/core_input_virtual_controls.png" alt="core_input_virtual_controls" width="80"> | ⭐️⭐️☆☆ | **5.0** | **5.0** | [oblerion](https://github.com/oblerion) |
|
||||||
| 09 | [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) |
|
| 09 | [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐️⭐️☆☆ | 1.5 | 3.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 10 | [core_2d_camera_platformer](core/core_2d_camera_platformer.c) | <img src="core/core_2d_camera_platformer.png" alt="core_2d_camera_platformer" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [avyy](https://github.com/avyy) |
|
| 10 | [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||||
| 11 | [core_2d_camera_split_screen](core/core_2d_camera_split_screen.c) | <img src="core/core_2d_camera_split_screen.png" alt="core_2d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Gabriel dos Santos Sanches](https://github.com/gabrielssanches) |
|
| 11 | [core_2d_camera_platformer](core/core_2d_camera_platformer.c) | <img src="core/core_2d_camera_platformer.png" alt="core_2d_camera_platformer" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [avyy](https://github.com/avyy) |
|
||||||
| 12 | [core_3d_camera_mode](core/core_3d_camera_mode.c) | <img src="core/core_3d_camera_mode.png" alt="core_3d_camera_mode" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
| 12 | [core_2d_camera_split_screen](core/core_2d_camera_split_screen.c) | <img src="core/core_2d_camera_split_screen.png" alt="core_2d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Gabriel dos Santos Sanches](https://github.com/gabrielssanches) |
|
||||||
| 13 | [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 | [Ray](https://github.com/raysan5) |
|
| 13 | [core_3d_camera_mode](core/core_3d_camera_mode.c) | <img src="core/core_3d_camera_mode.png" alt="core_3d_camera_mode" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 14 | [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 | [Ray](https://github.com/raysan5) |
|
| 14 | [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 | [Ray](https://github.com/raysan5) |
|
||||||
| 15 | [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) |
|
| 15 | [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 | [Ray](https://github.com/raysan5) |
|
||||||
| 16 | [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** | [Ray](https://github.com/raysan5) |
|
| 16 | [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) |
|
||||||
| 17 | [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 | [Ray](https://github.com/raysan5) |
|
| 17 | [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** | [Ray](https://github.com/raysan5) |
|
||||||
| 18 | [core_custom_logging](core/core_custom_logging.c) | <img src="core/core_custom_logging.png" alt="core_custom_logging" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) |
|
| 18 | [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 | [Ray](https://github.com/raysan5) |
|
||||||
| 19 | [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 | [Ray](https://github.com/raysan5) |
|
| 19 | [core_custom_logging](core/core_custom_logging.c) | <img src="core/core_custom_logging.png" alt="core_custom_logging" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) |
|
||||||
| 20 | [core_window_letterbox](core/core_window_letterbox.c) | <img src="core/core_window_letterbox.png" alt="core_window_letterbox" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Anata](https://github.com/anatagawa) |
|
| 20 | [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 | [Ray](https://github.com/raysan5) |
|
||||||
| 21 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
| 21 | [core_window_letterbox](core/core_window_letterbox.c) | <img src="core/core_window_letterbox.png" alt="core_window_letterbox" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Anata](https://github.com/anatagawa) |
|
||||||
| 22 | [core_drop_files](core/core_drop_files.c) | <img src="core/core_drop_files.png" alt="core_drop_files" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 22 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 23 | [core_random_values](core/core_random_values.c) | <img src="core/core_random_values.png" alt="core_random_values" width="80"> | ⭐️☆☆☆ | 1.1 | 1.1 | [Ray](https://github.com/raysan5) |
|
| 23 | [core_drop_files](core/core_drop_files.c) | <img src="core/core_drop_files.png" alt="core_drop_files" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 24 | [core_storage_values](core/core_storage_values.c) | <img src="core/core_storage_values.png" alt="core_storage_values" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 24 | [core_random_values](core/core_random_values.c) | <img src="core/core_random_values.png" alt="core_random_values" width="80"> | ⭐️☆☆☆ | 1.1 | 1.1 | [Ray](https://github.com/raysan5) |
|
||||||
| 25 | [core_vr_simulator](core/core_vr_simulator.c) | <img src="core/core_vr_simulator.png" alt="core_vr_simulator" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 25 | [core_storage_values](core/core_storage_values.c) | <img src="core/core_storage_values.png" alt="core_storage_values" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 26 | [core_loading_thread](core/core_loading_thread.c) | <img src="core/core_loading_thread.png" alt="core_loading_thread" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Ray](https://github.com/raysan5) |
|
| 26 | [core_vr_simulator](core/core_vr_simulator.c) | <img src="core/core_vr_simulator.png" alt="core_vr_simulator" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 27 | [core_scissor_test](core/core_scissor_test.c) | <img src="core/core_scissor_test.png" alt="core_scissor_test" width="80"> | ⭐️☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
|
| 27 | [core_loading_thread](core/core_loading_thread.c) | <img src="core/core_loading_thread.png" alt="core_loading_thread" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 28 | [core_basic_screen_manager](core/core_basic_screen_manager.c) | <img src="core/core_basic_screen_manager.png" alt="core_basic_screen_manager" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
|
| 28 | [core_scissor_test](core/core_scissor_test.c) | <img src="core/core_scissor_test.png" alt="core_scissor_test" width="80"> | ⭐️☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
|
||||||
| 29 | [core_custom_frame_control](core/core_custom_frame_control.c) | <img src="core/core_custom_frame_control.png" alt="core_custom_frame_control" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
|
| 29 | [core_basic_screen_manager](core/core_basic_screen_manager.c) | <img src="core/core_basic_screen_manager.png" alt="core_basic_screen_manager" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 30 | [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) |
|
| 30 | [core_custom_frame_control](core/core_custom_frame_control.c) | <img src="core/core_custom_frame_control.png" alt="core_custom_frame_control" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 31 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
| 31 | [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) |
|
||||||
| 32 | [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** | [REDl3east](https://github.com/REDl3east) |
|
| 32 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
|
| 33 | [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** | [REDl3east](https://github.com/REDl3east) |
|
||||||
|
|
||||||
### category: shapes
|
### category: shapes
|
||||||
|
|
||||||
|
|
@ -63,22 +64,22 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||||
|
|
||||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||||
| 31 | [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 34 | [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 32 | [shapes_bouncing_ball](shapes/shapes_bouncing_ball.c) | <img src="shapes/shapes_bouncing_ball.png" alt="shapes_bouncing_ball" width="80"> | ⭐️☆☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 35 | [shapes_bouncing_ball](shapes/shapes_bouncing_ball.c) | <img src="shapes/shapes_bouncing_ball.png" alt="shapes_bouncing_ball" width="80"> | ⭐️☆☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 33 | [shapes_colors_palette](shapes/shapes_colors_palette.c) | <img src="shapes/shapes_colors_palette.png" alt="shapes_colors_palette" width="80"> | ⭐️⭐️☆☆ | 1.0 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 36 | [shapes_colors_palette](shapes/shapes_colors_palette.c) | <img src="shapes/shapes_colors_palette.png" alt="shapes_colors_palette" width="80"> | ⭐️⭐️☆☆ | 1.0 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 34 | [shapes_logo_raylib](shapes/shapes_logo_raylib.c) | <img src="shapes/shapes_logo_raylib.png" alt="shapes_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
| 37 | [shapes_logo_raylib](shapes/shapes_logo_raylib.c) | <img src="shapes/shapes_logo_raylib.png" alt="shapes_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 35 | [shapes_logo_raylib_anim](shapes/shapes_logo_raylib_anim.c) | <img src="shapes/shapes_logo_raylib_anim.png" alt="shapes_logo_raylib_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 38 | [shapes_logo_raylib_anim](shapes/shapes_logo_raylib_anim.c) | <img src="shapes/shapes_logo_raylib_anim.png" alt="shapes_logo_raylib_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 36 | [shapes_rectangle_scaling](shapes/shapes_rectangle_scaling.c) | <img src="shapes/shapes_rectangle_scaling.png" alt="shapes_rectangle_scaling" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| 39 | [shapes_rectangle_scaling](shapes/shapes_rectangle_scaling.c) | <img src="shapes/shapes_rectangle_scaling.png" alt="shapes_rectangle_scaling" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| 37 | [shapes_lines_bezier](shapes/shapes_lines_bezier.c) | <img src="shapes/shapes_lines_bezier.png" alt="shapes_lines_bezier" width="80"> | ⭐️☆☆☆ | 1.7 | 1.7 | [Ray](https://github.com/raysan5) |
|
| 40 | [shapes_lines_bezier](shapes/shapes_lines_bezier.c) | <img src="shapes/shapes_lines_bezier.png" alt="shapes_lines_bezier" width="80"> | ⭐️☆☆☆ | 1.7 | 1.7 | [Ray](https://github.com/raysan5) |
|
||||||
| 38 | [shapes_collision_area](shapes/shapes_collision_area.c) | <img src="shapes/shapes_collision_area.png" alt="shapes_collision_area" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 41 | [shapes_collision_area](shapes/shapes_collision_area.c) | <img src="shapes/shapes_collision_area.png" alt="shapes_collision_area" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 39 | [shapes_following_eyes](shapes/shapes_following_eyes.c) | <img src="shapes/shapes_following_eyes.png" alt="shapes_following_eyes" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 42 | [shapes_following_eyes](shapes/shapes_following_eyes.c) | <img src="shapes/shapes_following_eyes.png" alt="shapes_following_eyes" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 40 | [shapes_easings_ball_anim](shapes/shapes_easings_ball_anim.c) | <img src="shapes/shapes_easings_ball_anim.png" alt="shapes_easings_ball_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 43 | [shapes_easings_ball_anim](shapes/shapes_easings_ball_anim.c) | <img src="shapes/shapes_easings_ball_anim.png" alt="shapes_easings_ball_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 41 | [shapes_easings_box_anim](shapes/shapes_easings_box_anim.c) | <img src="shapes/shapes_easings_box_anim.png" alt="shapes_easings_box_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 44 | [shapes_easings_box_anim](shapes/shapes_easings_box_anim.c) | <img src="shapes/shapes_easings_box_anim.png" alt="shapes_easings_box_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 42 | [shapes_easings_rectangle_array](shapes/shapes_easings_rectangle_array.c) | <img src="shapes/shapes_easings_rectangle_array.png" alt="shapes_easings_rectangle_array" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 45 | [shapes_easings_rectangle_array](shapes/shapes_easings_rectangle_array.c) | <img src="shapes/shapes_easings_rectangle_array.png" alt="shapes_easings_rectangle_array" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 43 | [shapes_draw_ring](shapes/shapes_draw_ring.c) | <img src="shapes/shapes_draw_ring.png" alt="shapes_draw_ring" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| 46 | [shapes_draw_ring](shapes/shapes_draw_ring.c) | <img src="shapes/shapes_draw_ring.png" alt="shapes_draw_ring" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| 44 | [shapes_draw_circle_sector](shapes/shapes_draw_circle_sector.c) | <img src="shapes/shapes_draw_circle_sector.png" alt="shapes_draw_circle_sector" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| 47 | [shapes_draw_circle_sector](shapes/shapes_draw_circle_sector.c) | <img src="shapes/shapes_draw_circle_sector.png" alt="shapes_draw_circle_sector" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| 45 | [shapes_draw_rectangle_rounded](shapes/shapes_draw_rectangle_rounded.c) | <img src="shapes/shapes_draw_rectangle_rounded.png" alt="shapes_draw_rectangle_rounded" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| 48 | [shapes_draw_rectangle_rounded](shapes/shapes_draw_rectangle_rounded.c) | <img src="shapes/shapes_draw_rectangle_rounded.png" alt="shapes_draw_rectangle_rounded" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| 46 | [shapes_top_down_lights](shapes/shapes_top_down_lights.c) | <img src="shapes/shapes_top_down_lights.png" alt="shapes_top_down_lights" width="80"> | ⭐️⭐️⭐️⭐️ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) |
|
| 49 | [shapes_top_down_lights](shapes/shapes_top_down_lights.c) | <img src="shapes/shapes_top_down_lights.png" alt="shapes_top_down_lights" width="80"> | ⭐️⭐️⭐️⭐️ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||||
|
|
||||||
### category: textures
|
### category: textures
|
||||||
|
|
||||||
|
|
@ -86,28 +87,28 @@ Examples using raylib textures functionality, including image/textures loading/g
|
||||||
|
|
||||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||||
| 47 | [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
| 50 | [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 48 | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
| 51 | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||||
| 49 | [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
|
| 52 | [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
|
||||||
| 50 | [textures_image_generation](textures/textures_image_generation.c) | <img src="textures/textures_image_generation.png" alt="textures_image_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | 1.8 | [Ray](https://github.com/raysan5) |
|
| 53 | [textures_image_generation](textures/textures_image_generation.c) | <img src="textures/textures_image_generation.png" alt="textures_image_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | 1.8 | [Ray](https://github.com/raysan5) |
|
||||||
| 51 | [textures_image_loading](textures/textures_image_loading.c) | <img src="textures/textures_image_loading.png" alt="textures_image_loading" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
| 54 | [textures_image_loading](textures/textures_image_loading.c) | <img src="textures/textures_image_loading.png" alt="textures_image_loading" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||||
| 52 | [textures_image_processing](textures/textures_image_processing.c) | <img src="textures/textures_image_processing.png" alt="textures_image_processing" width="80"> | ⭐️⭐️⭐️☆ | 1.4 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 55 | [textures_image_processing](textures/textures_image_processing.c) | <img src="textures/textures_image_processing.png" alt="textures_image_processing" width="80"> | ⭐️⭐️⭐️☆ | 1.4 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 53 | [textures_image_text](textures/textures_image_text.c) | <img src="textures/textures_image_text.png" alt="textures_image_text" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 56 | [textures_image_text](textures/textures_image_text.c) | <img src="textures/textures_image_text.png" alt="textures_image_text" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 54 | [textures_to_image](textures/textures_to_image.c) | <img src="textures/textures_to_image.png" alt="textures_to_image" width="80"> | ⭐️☆☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 57 | [textures_to_image](textures/textures_to_image.c) | <img src="textures/textures_to_image.png" alt="textures_to_image" width="80"> | ⭐️☆☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 55 | [textures_raw_data](textures/textures_raw_data.c) | <img src="textures/textures_raw_data.png" alt="textures_raw_data" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 58 | [textures_raw_data](textures/textures_raw_data.c) | <img src="textures/textures_raw_data.png" alt="textures_raw_data" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 56 | [textures_particles_blending](textures/textures_particles_blending.c) | <img src="textures/textures_particles_blending.png" alt="textures_particles_blending" width="80"> | ⭐️☆☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 59 | [textures_particles_blending](textures/textures_particles_blending.c) | <img src="textures/textures_particles_blending.png" alt="textures_particles_blending" width="80"> | ⭐️☆☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 57 | [textures_npatch_drawing](textures/textures_npatch_drawing.c) | <img src="textures/textures_npatch_drawing.png" alt="textures_npatch_drawing" width="80"> | ⭐️⭐️⭐️☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) |
|
| 60 | [textures_npatch_drawing](textures/textures_npatch_drawing.c) | <img src="textures/textures_npatch_drawing.png" alt="textures_npatch_drawing" width="80"> | ⭐️⭐️⭐️☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) |
|
||||||
| 58 | [textures_background_scrolling](textures/textures_background_scrolling.c) | <img src="textures/textures_background_scrolling.png" alt="textures_background_scrolling" width="80"> | ⭐️☆☆☆ | 2.0 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 61 | [textures_background_scrolling](textures/textures_background_scrolling.c) | <img src="textures/textures_background_scrolling.png" alt="textures_background_scrolling" width="80"> | ⭐️☆☆☆ | 2.0 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 59 | [textures_sprite_anim](textures/textures_sprite_anim.c) | <img src="textures/textures_sprite_anim.png" alt="textures_sprite_anim" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
| 62 | [textures_sprite_anim](textures/textures_sprite_anim.c) | <img src="textures/textures_sprite_anim.png" alt="textures_sprite_anim" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
|
||||||
| 60 | [textures_sprite_button](textures/textures_sprite_button.c) | <img src="textures/textures_sprite_button.png" alt="textures_sprite_button" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 63 | [textures_sprite_button](textures/textures_sprite_button.c) | <img src="textures/textures_sprite_button.png" alt="textures_sprite_button" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 61 | [textures_sprite_explosion](textures/textures_sprite_explosion.c) | <img src="textures/textures_sprite_explosion.png" alt="textures_sprite_explosion" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 64 | [textures_sprite_explosion](textures/textures_sprite_explosion.c) | <img src="textures/textures_sprite_explosion.png" alt="textures_sprite_explosion" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 62 | [textures_bunnymark](textures/textures_bunnymark.c) | <img src="textures/textures_bunnymark.png" alt="textures_bunnymark" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | 2.5 | [Ray](https://github.com/raysan5) |
|
| 65 | [textures_bunnymark](textures/textures_bunnymark.c) | <img src="textures/textures_bunnymark.png" alt="textures_bunnymark" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | 2.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 63 | [textures_mouse_painting](textures/textures_mouse_painting.c) | <img src="textures/textures_mouse_painting.png" alt="textures_mouse_painting" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
|
| 66 | [textures_mouse_painting](textures/textures_mouse_painting.c) | <img src="textures/textures_mouse_painting.png" alt="textures_mouse_painting" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
|
||||||
| 64 | [textures_blend_modes](textures/textures_blend_modes.c) | <img src="textures/textures_blend_modes.png" alt="textures_blend_modes" width="80"> | ⭐️☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) |
|
| 67 | [textures_blend_modes](textures/textures_blend_modes.c) | <img src="textures/textures_blend_modes.png" alt="textures_blend_modes" width="80"> | ⭐️☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) |
|
||||||
| 65 | [textures_draw_tiled](textures/textures_draw_tiled.c) | <img src="textures/textures_draw_tiled.png" alt="textures_draw_tiled" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | **4.2** | [Vlad Adrian](https://github.com/demizdor) |
|
| 68 | [textures_draw_tiled](textures/textures_draw_tiled.c) | <img src="textures/textures_draw_tiled.png" alt="textures_draw_tiled" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | **4.2** | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| 66 | [textures_polygon](textures/textures_polygon.c) | <img src="textures/textures_polygon.png" alt="textures_polygon" width="80"> | ⭐️☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
| 69 | [textures_polygon](textures/textures_polygon.c) | <img src="textures/textures_polygon.png" alt="textures_polygon" width="80"> | ⭐️☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
||||||
| 67 | [textures_fog_of_war](textures/textures_fog_of_war.c) | <img src="textures/textures_fog_of_war.png" alt="textures_fog_of_war" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
| 70 | [textures_fog_of_war](textures/textures_fog_of_war.c) | <img src="textures/textures_fog_of_war.png" alt="textures_fog_of_war" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 68 | [textures_gif_player](textures/textures_gif_player.c) | <img src="textures/textures_gif_player.png" alt="textures_gif_player" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
| 71 | [textures_gif_player](textures/textures_gif_player.c) | <img src="textures/textures_gif_player.png" alt="textures_gif_player" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
|
|
||||||
### category: text
|
### category: text
|
||||||
|
|
||||||
|
|
@ -115,18 +116,18 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
||||||
|
|
||||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||||
| 69 | [text_raylib_fonts](text/text_raylib_fonts.c) | <img src="text/text_raylib_fonts.png" alt="text_raylib_fonts" width="80"> | ⭐️☆☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
|
| 72 | [text_raylib_fonts](text/text_raylib_fonts.c) | <img src="text/text_raylib_fonts.png" alt="text_raylib_fonts" width="80"> | ⭐️☆☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
|
||||||
| 70 | [text_font_spritefont](text/text_font_spritefont.c) | <img src="text/text_font_spritefont.png" alt="text_font_spritefont" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
| 73 | [text_font_spritefont](text/text_font_spritefont.c) | <img src="text/text_font_spritefont.png" alt="text_font_spritefont" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 71 | [text_font_filters](text/text_font_filters.c) | <img src="text/text_font_filters.png" alt="text_font_filters" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 74 | [text_font_filters](text/text_font_filters.c) | <img src="text/text_font_filters.png" alt="text_font_filters" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 72 | [text_font_loading](text/text_font_loading.c) | <img src="text/text_font_loading.png" alt="text_font_loading" width="80"> | ⭐️☆☆☆ | 1.4 | 3.0 | [Ray](https://github.com/raysan5) |
|
| 75 | [text_font_loading](text/text_font_loading.c) | <img src="text/text_font_loading.png" alt="text_font_loading" width="80"> | ⭐️☆☆☆ | 1.4 | 3.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 73 | [text_font_sdf](text/text_font_sdf.c) | <img src="text/text_font_sdf.png" alt="text_font_sdf" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 76 | [text_font_sdf](text/text_font_sdf.c) | <img src="text/text_font_sdf.png" alt="text_font_sdf" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 74 | [text_format_text](text/text_format_text.c) | <img src="text/text_format_text.png" alt="text_format_text" width="80"> | ⭐️☆☆☆ | 1.1 | 3.0 | [Ray](https://github.com/raysan5) |
|
| 77 | [text_format_text](text/text_format_text.c) | <img src="text/text_format_text.png" alt="text_format_text" width="80"> | ⭐️☆☆☆ | 1.1 | 3.0 | [Ray](https://github.com/raysan5) |
|
||||||
| 75 | [text_input_box](text/text_input_box.c) | <img src="text/text_input_box.png" alt="text_input_box" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 78 | [text_input_box](text/text_input_box.c) | <img src="text/text_input_box.png" alt="text_input_box" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 76 | [text_writing_anim](text/text_writing_anim.c) | <img src="text/text_writing_anim.png" alt="text_writing_anim" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
|
| 79 | [text_writing_anim](text/text_writing_anim.c) | <img src="text/text_writing_anim.png" alt="text_writing_anim" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
|
||||||
| 77 | [text_rectangle_bounds](text/text_rectangle_bounds.c) | <img src="text/text_rectangle_bounds.png" alt="text_rectangle_bounds" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
| 80 | [text_rectangle_bounds](text/text_rectangle_bounds.c) | <img src="text/text_rectangle_bounds.png" alt="text_rectangle_bounds" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| 78 | [text_unicode](text/text_unicode.c) | <img src="text/text_unicode.png" alt="text_unicode" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
| 81 | [text_unicode](text/text_unicode.c) | <img src="text/text_unicode.png" alt="text_unicode" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| 79 | [text_draw_3d](text/text_draw_3d.c) | <img src="text/text_draw_3d.png" alt="text_draw_3d" width="80"> | ⭐️⭐️⭐️⭐️ | 3.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
| 82 | [text_draw_3d](text/text_draw_3d.c) | <img src="text/text_draw_3d.png" alt="text_draw_3d" width="80"> | ⭐️⭐️⭐️⭐️ | 3.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| 80 | [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** | [Ray](https://github.com/raysan5) |
|
| 83 | [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** | [Ray](https://github.com/raysan5) |
|
||||||
|
|
||||||
### category: models
|
### category: models
|
||||||
|
|
||||||
|
|
@ -134,24 +135,25 @@ Examples using raylib models functionality, including models loading/generation
|
||||||
|
|
||||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||||
| 81 | [models_animation](models/models_animation.c) | <img src="models/models_animation.png" alt="models_animation" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [culacant](https://github.com/culacant) |
|
| 84 | [models_animation](models/models_animation.c) | <img src="models/models_animation.png" alt="models_animation" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [culacant](https://github.com/culacant) |
|
||||||
| 82 | [models_billboard](models/models_billboard.c) | <img src="models/models_billboard.png" alt="models_billboard" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 85 | [models_billboard](models/models_billboard.c) | <img src="models/models_billboard.png" alt="models_billboard" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 83 | [models_box_collisions](models/models_box_collisions.c) | <img src="models/models_box_collisions.png" alt="models_box_collisions" width="80"> | ⭐️☆☆☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 86 | [models_box_collisions](models/models_box_collisions.c) | <img src="models/models_box_collisions.png" alt="models_box_collisions" width="80"> | ⭐️☆☆☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 84 | [models_cubicmap](models/models_cubicmap.c) | <img src="models/models_cubicmap.png" alt="models_cubicmap" width="80"> | ⭐️⭐️☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 87 | [models_cubicmap](models/models_cubicmap.c) | <img src="models/models_cubicmap.png" alt="models_cubicmap" width="80"> | ⭐️⭐️☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 85 | [models_first_person_maze](models/models_first_person_maze.c) | <img src="models/models_first_person_maze.png" alt="models_first_person_maze" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 88 | [models_first_person_maze](models/models_first_person_maze.c) | <img src="models/models_first_person_maze.png" alt="models_first_person_maze" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 86 | [models_geometric_shapes](models/models_geometric_shapes.c) | <img src="models/models_geometric_shapes.png" alt="models_geometric_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 89 | [models_geometric_shapes](models/models_geometric_shapes.c) | <img src="models/models_geometric_shapes.png" alt="models_geometric_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 87 | [models_mesh_generation](models/models_mesh_generation.c) | <img src="models/models_mesh_generation.png" alt="models_mesh_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 90 | [models_mesh_generation](models/models_mesh_generation.c) | <img src="models/models_mesh_generation.png" alt="models_mesh_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 88 | [models_mesh_picking](models/models_mesh_picking.c) | <img src="models/models_mesh_picking.png" alt="models_mesh_picking" width="80"> | ⭐️⭐️⭐️☆ | 1.7 | **4.0** | [Joel Davis](https://github.com/joeld42) |
|
| 91 | [models_mesh_picking](models/models_mesh_picking.c) | <img src="models/models_mesh_picking.png" alt="models_mesh_picking" width="80"> | ⭐️⭐️⭐️☆ | 1.7 | **4.0** | [Joel Davis](https://github.com/joeld42) |
|
||||||
| 89 | [models_loading](models/models_loading.c) | <img src="models/models_loading.png" alt="models_loading" width="80"> | ⭐️☆☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 92 | [models_loading](models/models_loading.c) | <img src="models/models_loading.png" alt="models_loading" width="80"> | ⭐️☆☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 90 | [models_loading_gltf](models/models_loading_gltf.c) | <img src="models/models_loading_gltf.png" alt="models_loading_gltf" width="80"> | ⭐️☆☆☆ | 3.7 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 93 | [models_loading_gltf](models/models_loading_gltf.c) | <img src="models/models_loading_gltf.png" alt="models_loading_gltf" width="80"> | ⭐️☆☆☆ | 3.7 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 91 | [models_loading_vox](models/models_loading_vox.c) | <img src="models/models_loading_vox.png" alt="models_loading_vox" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Johann Nadalutti](https://github.com/procfxgen) |
|
| 94 | [models_loading_vox](models/models_loading_vox.c) | <img src="models/models_loading_vox.png" alt="models_loading_vox" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Johann Nadalutti](https://github.com/procfxgen) |
|
||||||
| 92 | [models_loading_m3d](models/models_loading_m3d.c) | <img src="models/models_loading_m3d.png" alt="models_loading_m3d" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [bzt](https://bztsrc.gitlab.io/model3d) |
|
| 95 | [models_loading_m3d](models/models_loading_m3d.c) | <img src="models/models_loading_m3d.png" alt="models_loading_m3d" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [bzt](https://bztsrc.gitlab.io/model3d) |
|
||||||
| 93 | [models_orthographic_projection](models/models_orthographic_projection.c) | <img src="models/models_orthographic_projection.png" alt="models_orthographic_projection" width="80"> | ⭐️☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) |
|
| 96 | [models_orthographic_projection](models/models_orthographic_projection.c) | <img src="models/models_orthographic_projection.png" alt="models_orthographic_projection" width="80"> | ⭐️☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) |
|
||||||
| 94 | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) | <img src="models/models_rlgl_solar_system.png" alt="models_rlgl_solar_system" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 97 | [models_point_rendering](models/models_point_rendering.c) | <img src="models/models_point_rendering.png" alt="models_point_rendering" width="80"> | ⭐️⭐️☆☆ | 5.0 | 5.0 | [Reese Gallagher](https://github.com/satchelfrost) |
|
||||||
| 95 | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) | <img src="models/models_yaw_pitch_roll.png" alt="models_yaw_pitch_roll" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Berni](https://github.com/Berni8k) |
|
| 98 | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) | <img src="models/models_rlgl_solar_system.png" alt="models_rlgl_solar_system" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 96 | [models_waving_cubes](models/models_waving_cubes.c) | <img src="models/models_waving_cubes.png" alt="models_waving_cubes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [codecat](https://github.com/codecat) |
|
| 99 | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) | <img src="models/models_yaw_pitch_roll.png" alt="models_yaw_pitch_roll" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Berni](https://github.com/Berni8k) |
|
||||||
| 97 | [models_heightmap](models/models_heightmap.c) | <img src="models/models_heightmap.png" alt="models_heightmap" width="80"> | ⭐️☆☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 100 | [models_waving_cubes](models/models_waving_cubes.c) | <img src="models/models_waving_cubes.png" alt="models_waving_cubes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [codecat](https://github.com/codecat) |
|
||||||
| 98 | [models_skybox](models/models_skybox.c) | <img src="models/models_skybox.png" alt="models_skybox" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 101 | [models_heightmap](models/models_heightmap.c) | <img src="models/models_heightmap.png" alt="models_heightmap" width="80"> | ⭐️☆☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
|
| 102 | [models_skybox](models/models_skybox.c) | <img src="models/models_skybox.png" alt="models_skybox" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
|
|
||||||
### category: shaders
|
### category: shaders
|
||||||
|
|
||||||
|
|
@ -159,26 +161,25 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
||||||
|
|
||||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||||
| 99 | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐️⭐️⭐️⭐️ | 3.0 | **4.2** | [Chris Camacho](https://github.com/codifies) |
|
| 103 | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐️⭐️⭐️⭐️ | 3.0 | **4.2** | [Chris Camacho](https://github.com/codifies) |
|
||||||
| 100 | [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐️⭐️☆☆ | 1.3 | 3.7 | [Ray](https://github.com/raysan5) |
|
| 104 | [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐️⭐️☆☆ | 1.3 | 3.7 | [Ray](https://github.com/raysan5) |
|
||||||
| 101 | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
|
| 105 | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
|
||||||
| 102 | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) | <img src="shaders/shaders_custom_uniform.png" alt="shaders_custom_uniform" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 106 | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) | <img src="shaders/shaders_custom_uniform.png" alt="shaders_custom_uniform" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 103 | [shaders_postprocessing](shaders/shaders_postprocessing.c) | <img src="shaders/shaders_postprocessing.png" alt="shaders_postprocessing" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 107 | [shaders_postprocessing](shaders/shaders_postprocessing.c) | <img src="shaders/shaders_postprocessing.png" alt="shaders_postprocessing" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 104 | [shaders_palette_switch](shaders/shaders_palette_switch.c) | <img src="shaders/shaders_palette_switch.png" alt="shaders_palette_switch" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) |
|
| 108 | [shaders_palette_switch](shaders/shaders_palette_switch.c) | <img src="shaders/shaders_palette_switch.png" alt="shaders_palette_switch" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) |
|
||||||
| 105 | [shaders_raymarching](shaders/shaders_raymarching.c) | <img src="shaders/shaders_raymarching.png" alt="shaders_raymarching" width="80"> | ⭐️⭐️⭐️⭐️ | 2.0 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 109 | [shaders_raymarching](shaders/shaders_raymarching.c) | <img src="shaders/shaders_raymarching.png" alt="shaders_raymarching" width="80"> | ⭐️⭐️⭐️⭐️ | 2.0 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 106 | [shaders_texture_drawing](shaders/shaders_texture_drawing.c) | <img src="shaders/shaders_texture_drawing.png" alt="shaders_texture_drawing" width="80"> | ⭐️⭐️☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/) |
|
| 110 | [shaders_texture_drawing](shaders/shaders_texture_drawing.c) | <img src="shaders/shaders_texture_drawing.png" alt="shaders_texture_drawing" width="80"> | ⭐️⭐️☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/) |
|
||||||
| 107 | [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** | [Samuel Skiff](https://github.com/GoldenThumbs) |
|
| 111 | [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** | [Samuel Skiff](https://github.com/GoldenThumbs) |
|
||||||
| 108 | [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) |
|
| 112 | [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) |
|
||||||
| 109 | [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** | [eggmund](https://github.com/eggmund) |
|
| 113 | [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** | [eggmund](https://github.com/eggmund) |
|
||||||
| 110 | [shaders_eratosthenes](shaders/shaders_eratosthenes.c) | <img src="shaders/shaders_eratosthenes.png" alt="shaders_eratosthenes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [ProfJski](https://github.com/ProfJski) |
|
| 114 | [shaders_eratosthenes](shaders/shaders_eratosthenes.c) | <img src="shaders/shaders_eratosthenes.png" alt="shaders_eratosthenes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [ProfJski](https://github.com/ProfJski) |
|
||||||
| 111 | [shaders_fog](shaders/shaders_fog.c) | <img src="shaders/shaders_fog.png" alt="shaders_fog" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
| 115 | [shaders_fog](shaders/shaders_fog.c) | <img src="shaders/shaders_fog.png" alt="shaders_fog" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
||||||
| 112 | [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/codifies) |
|
| 116 | [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/codifies) |
|
||||||
| 113 | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 117 | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 114 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.2** | [seanpringle](https://github.com/seanpringle) |
|
| 118 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.2** | [seanpringle](https://github.com/seanpringle) |
|
||||||
| 115 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 119 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 116 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
| 120 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
|
||||||
| 117 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
|
| 121 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
|
||||||
| 118 | [shaders_vertex_displacement](shaders/shaders_vertex_displacement.c) | <img src="shaders/shaders_vertex_displacement.png" alt="shaders_deferred_render" width="80"> | ⭐️☆☆☆ | 1.5 | 1.5 | [Alex ZH](https://github.com/ZzzhHe) |
|
|
||||||
|
|
||||||
### category: audio
|
### category: audio
|
||||||
|
|
||||||
|
|
@ -186,10 +187,10 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
||||||
|
|
||||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||||
| 119 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 122 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
| 120 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 123 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 121 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) |
|
| 124 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) |
|
||||||
| 122 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
|
| 125 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
|
||||||
|
|
||||||
### category: others
|
### category: others
|
||||||
|
|
||||||
|
|
@ -197,11 +198,11 @@ Examples showing raylib misc functionality that does not fit in other categories
|
||||||
|
|
||||||
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||||
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
|
||||||
| 123 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) |
|
| 126 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) |
|
||||||
| 124 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) |
|
| 127 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) |
|
||||||
| 125 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
|
| 128 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||||
| 126 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
|
| 129 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
|
||||||
| 127 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
|
| 130 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
|
||||||
|
|
||||||
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
|
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
|
||||||
|
|
||||||
|
|
|
||||||
123
examples/core/core_input_virtual_controls.c
Normal file
123
examples/core/core_input_virtual_controls.c
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - input virtual controls
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||||
|
*
|
||||||
|
* Example create by GreenSnakeLinux (@GreenSnakeLinux),
|
||||||
|
* lighter by oblerion (@oblerion) 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) 2024 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include <math.h>
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls");
|
||||||
|
|
||||||
|
const int dpadX = 90;
|
||||||
|
const int dpadY = 300;
|
||||||
|
const int dpadRad = 25;//radius of each pad
|
||||||
|
Color dpadColor = BLUE;
|
||||||
|
int dpadKeydown = -1;//-1 if not down, else 0,1,2,3
|
||||||
|
|
||||||
|
|
||||||
|
const float dpadCollider[4][2]= // collider array with x,y position
|
||||||
|
{
|
||||||
|
{dpadX,dpadY-dpadRad*1.5},//up
|
||||||
|
{dpadX-dpadRad*1.5,dpadY},//left
|
||||||
|
{dpadX+dpadRad*1.5,dpadY},//right
|
||||||
|
{dpadX,dpadY+dpadRad*1.5}//down
|
||||||
|
};
|
||||||
|
const char dpadLabel[4]="XYBA";//label of Dpad
|
||||||
|
|
||||||
|
float playerX=100;
|
||||||
|
float playerY=100;
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
dpadKeydown = -1; //reset
|
||||||
|
float inputX=0;
|
||||||
|
float inputY=0;
|
||||||
|
if(GetTouchPointCount()>0)
|
||||||
|
{//use touch pos
|
||||||
|
inputX = GetTouchX();
|
||||||
|
inputY = GetTouchY();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{//use mouse pos
|
||||||
|
inputX = GetMouseX();
|
||||||
|
inputY = GetMouseY();
|
||||||
|
}
|
||||||
|
for(int i=0;i<4;i++)
|
||||||
|
{
|
||||||
|
//test distance each collider and input < radius
|
||||||
|
if( fabsf(dpadCollider[i][1]-inputY) + fabsf(dpadCollider[i][0]-inputX) < dpadRad)
|
||||||
|
{
|
||||||
|
dpadKeydown = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// move player
|
||||||
|
switch(dpadKeydown){
|
||||||
|
case 0: playerY -= 50*GetFrameTime();
|
||||||
|
break;
|
||||||
|
case 1: playerX -= 50*GetFrameTime();
|
||||||
|
break;
|
||||||
|
case 2: playerX += 50*GetFrameTime();
|
||||||
|
break;
|
||||||
|
case 3: playerY += 50*GetFrameTime();
|
||||||
|
default:;
|
||||||
|
};
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
for(int i=0;i<4;i++)
|
||||||
|
{
|
||||||
|
//draw all pad
|
||||||
|
DrawCircle(dpadCollider[i][0],dpadCollider[i][1],dpadRad,dpadColor);
|
||||||
|
if(i!=dpadKeydown)
|
||||||
|
{
|
||||||
|
//draw label
|
||||||
|
DrawText(TextSubtext(dpadLabel,i,1),
|
||||||
|
dpadCollider[i][0]-5,
|
||||||
|
dpadCollider[i][1]-5,16,BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
DrawText("Player",playerX,playerY,16,BLACK);
|
||||||
|
EndDrawing();
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BIN
examples/core/core_input_virtual_controls.png
Normal file
BIN
examples/core/core_input_virtual_controls.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
118
examples/models/models_gpu_skinning.c
Normal file
118
examples/models/models_gpu_skinning.c
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - Doing skinning on the gpu using a vertex shader
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 4.5, last time updated with raylib 4.5
|
||||||
|
*
|
||||||
|
* Example contributed by Daniel Holden (@orangeduck) 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) 2024 Daniel Holden (@orangeduck)
|
||||||
|
*
|
||||||
|
* Note: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
#define GLSL_VERSION 330
|
||||||
|
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||||
|
#define GLSL_VERSION 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - GPU skinning");
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world
|
||||||
|
Camera camera = { 0 };
|
||||||
|
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
|
||||||
|
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
||||||
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||||
|
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||||
|
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||||
|
|
||||||
|
// Load gltf model
|
||||||
|
Model characterModel = LoadModel("resources/models/gltf/greenman.glb"); // Load character model
|
||||||
|
|
||||||
|
// Load skinning shader
|
||||||
|
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||||
|
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||||
|
|
||||||
|
characterModel.materials[1].shader = skinningShader;
|
||||||
|
|
||||||
|
// Load gltf model animations
|
||||||
|
int animsCount = 0;
|
||||||
|
unsigned int animIndex = 0;
|
||||||
|
unsigned int animCurrentFrame = 0;
|
||||||
|
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/greenman.glb", &animsCount);
|
||||||
|
|
||||||
|
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||||
|
|
||||||
|
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||||
|
|
||||||
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||||
|
|
||||||
|
// Select current animation
|
||||||
|
if (IsKeyPressed(KEY_T)) animIndex = (animIndex + 1)%animsCount;
|
||||||
|
else if (IsKeyPressed(KEY_G)) animIndex = (animIndex + animsCount - 1)%animsCount;
|
||||||
|
|
||||||
|
// Update model animation
|
||||||
|
ModelAnimation anim = modelAnimations[animIndex];
|
||||||
|
animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode3D(camera);
|
||||||
|
|
||||||
|
// Draw character
|
||||||
|
characterModel.transform = MatrixTranslate(position.x, position.y, position.z);
|
||||||
|
UpdateModelAnimationBoneMatrices(characterModel, anim, animCurrentFrame);
|
||||||
|
DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);
|
||||||
|
|
||||||
|
DrawGrid(10, 1.0f);
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
DrawText("Use the T/G to switch animation", 10, 10, 20, GRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadModelAnimations(modelAnimations, animsCount);
|
||||||
|
UnloadModel(characterModel); // Unload character model and meshes/material
|
||||||
|
UnloadShader(skinningShader);
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
182
examples/models/models_point_rendering.c
Normal file
182
examples/models/models_point_rendering.c
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib example - point rendering
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||||
|
*
|
||||||
|
* Example contributed by Reese Gallagher (@satchelfrost) 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) 2024 Reese Gallagher (@satchelfrost)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <stdlib.h> // Required for: rand()
|
||||||
|
#include <math.h> // Required for: cos(), sin()
|
||||||
|
|
||||||
|
#define MAX_POINTS 10000000 // 10 million
|
||||||
|
#define MIN_POINTS 1000 // 1 thousand
|
||||||
|
|
||||||
|
// Generate mesh using points
|
||||||
|
Mesh GenMeshPoints(int numPoints);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - point rendering");
|
||||||
|
|
||||||
|
Camera camera = {
|
||||||
|
.position = { 3.0f, 3.0f, 3.0f },
|
||||||
|
.target = { 0.0f, 0.0f, 0.0f },
|
||||||
|
.up = { 0.0f, 1.0f, 0.0f },
|
||||||
|
.fovy = 45.0f,
|
||||||
|
.projection = CAMERA_PERSPECTIVE
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector3 position = { 0.0f, 0.0f, 0.0f };
|
||||||
|
bool useDrawModelPoints = true;
|
||||||
|
bool numPointsChanged = false;
|
||||||
|
int numPoints = 1000;
|
||||||
|
|
||||||
|
Mesh mesh = GenMeshPoints(numPoints);
|
||||||
|
Model model = LoadModelFromMesh(mesh);
|
||||||
|
|
||||||
|
//SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while(!WindowShouldClose())
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) useDrawModelPoints = !useDrawModelPoints;
|
||||||
|
if (IsKeyPressed(KEY_UP))
|
||||||
|
{
|
||||||
|
numPoints = (numPoints*10 > MAX_POINTS)? MAX_POINTS : numPoints*10;
|
||||||
|
numPointsChanged = true;
|
||||||
|
}
|
||||||
|
if (IsKeyPressed(KEY_DOWN))
|
||||||
|
{
|
||||||
|
numPoints = (numPoints/10 < MIN_POINTS)? MIN_POINTS : numPoints/10;
|
||||||
|
numPointsChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload a different point cloud size
|
||||||
|
if (numPointsChanged)
|
||||||
|
{
|
||||||
|
UnloadModel(model);
|
||||||
|
mesh = GenMeshPoints(numPoints);
|
||||||
|
model = LoadModelFromMesh(mesh);
|
||||||
|
numPointsChanged = false;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The old method must continually draw the "points" (lines)
|
||||||
|
for (int i = 0; i < numPoints; i++)
|
||||||
|
{
|
||||||
|
Vector3 pos = {
|
||||||
|
.x = mesh.vertices[i*3 + 0],
|
||||||
|
.y = mesh.vertices[i*3 + 1],
|
||||||
|
.z = mesh.vertices[i*3 + 2],
|
||||||
|
};
|
||||||
|
Color color = {
|
||||||
|
.r = mesh.colors[i*4 + 0],
|
||||||
|
.g = mesh.colors[i*4 + 1],
|
||||||
|
.b = mesh.colors[i*4 + 2],
|
||||||
|
.a = mesh.colors[i*4 + 3],
|
||||||
|
};
|
||||||
|
|
||||||
|
DrawPoint3D(pos, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 20, 160, 20, GREEN);
|
||||||
|
else DrawText("Using: DrawPoint3D()", 20, 160, 20, RED);
|
||||||
|
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadModel(model);
|
||||||
|
|
||||||
|
CloseWindow();
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a spherical point cloud
|
||||||
|
Mesh GenMeshPoints(int numPoints)
|
||||||
|
{
|
||||||
|
Mesh mesh = {
|
||||||
|
.triangleCount = 1,
|
||||||
|
.vertexCount = numPoints,
|
||||||
|
.vertices = (float *)MemAlloc(numPoints*3*sizeof(float)),
|
||||||
|
.colors = (unsigned char*)MemAlloc(numPoints*4*sizeof(unsigned char)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/Spherical_coordinate_system
|
||||||
|
for (int i = 0; i < numPoints; i++)
|
||||||
|
{
|
||||||
|
float theta = PI*rand()/RAND_MAX;
|
||||||
|
float phi = 2.0f*PI*rand()/RAND_MAX;
|
||||||
|
float r = 10.0f*rand()/RAND_MAX;
|
||||||
|
|
||||||
|
mesh.vertices[i*3 + 0] = r*sin(theta)*cos(phi);
|
||||||
|
mesh.vertices[i*3 + 1] = r*sin(theta)*sin(phi);
|
||||||
|
mesh.vertices[i*3 + 2] = r*cos(theta);
|
||||||
|
|
||||||
|
Color color = ColorFromHSV(r*360.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
mesh.colors[i*4 + 0] = color.r;
|
||||||
|
mesh.colors[i*4 + 1] = color.g;
|
||||||
|
mesh.colors[i*4 + 2] = color.b;
|
||||||
|
mesh.colors[i*4 + 3] = color.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload mesh data from CPU (RAM) to GPU (VRAM) memory
|
||||||
|
UploadMesh(&mesh, false);
|
||||||
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
BIN
examples/models/models_point_rendering.png
Normal file
BIN
examples/models/models_point_rendering.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
17
examples/models/resources/shaders/glsl100/skinning.fs
Normal file
17
examples/models/resources/shaders/glsl100/skinning.fs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#version 100
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
|
||||||
|
// Output fragment color
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||||
|
finalColor = texelColor*colDiffuse*fragColor;
|
||||||
|
}
|
||||||
34
examples/models/resources/shaders/glsl100/skinning.vs
Normal file
34
examples/models/resources/shaders/glsl100/skinning.vs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#version 100
|
||||||
|
|
||||||
|
in vec3 vertexPosition;
|
||||||
|
in vec2 vertexTexCoord;
|
||||||
|
in vec4 vertexColor;
|
||||||
|
in vec4 vertexBoneIds;
|
||||||
|
in vec4 vertexBoneWeights;
|
||||||
|
|
||||||
|
#define MAX_BONE_NUM 128
|
||||||
|
uniform mat4 boneMatrices[MAX_BONE_NUM];
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
out vec2 fragTexCoord;
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int boneIndex0 = int(vertexBoneIds.x);
|
||||||
|
int boneIndex1 = int(vertexBoneIds.y);
|
||||||
|
int boneIndex2 = int(vertexBoneIds.z);
|
||||||
|
int boneIndex3 = int(vertexBoneIds.w);
|
||||||
|
|
||||||
|
vec4 skinnedPosition =
|
||||||
|
vertexBoneWeights.x * (boneMatrices[boneIndex0] * vec4(vertexPosition, 1.0f)) +
|
||||||
|
vertexBoneWeights.y * (boneMatrices[boneIndex1] * vec4(vertexPosition, 1.0f)) +
|
||||||
|
vertexBoneWeights.z * (boneMatrices[boneIndex2] * vec4(vertexPosition, 1.0f)) +
|
||||||
|
vertexBoneWeights.w * (boneMatrices[boneIndex3] * vec4(vertexPosition, 1.0f));
|
||||||
|
|
||||||
|
fragTexCoord = vertexTexCoord;
|
||||||
|
fragColor = vertexColor;
|
||||||
|
|
||||||
|
gl_Position = mvp * skinnedPosition;
|
||||||
|
}
|
||||||
17
examples/models/resources/shaders/glsl330/skinning.fs
Normal file
17
examples/models/resources/shaders/glsl330/skinning.fs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
|
||||||
|
// Output fragment color
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 colDiffuse;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||||
|
finalColor = texelColor*colDiffuse*fragColor;
|
||||||
|
}
|
||||||
34
examples/models/resources/shaders/glsl330/skinning.vs
Normal file
34
examples/models/resources/shaders/glsl330/skinning.vs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec3 vertexPosition;
|
||||||
|
in vec2 vertexTexCoord;
|
||||||
|
in vec4 vertexColor;
|
||||||
|
in vec4 vertexBoneIds;
|
||||||
|
in vec4 vertexBoneWeights;
|
||||||
|
|
||||||
|
#define MAX_BONE_NUM 128
|
||||||
|
uniform mat4 boneMatrices[MAX_BONE_NUM];
|
||||||
|
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
out vec2 fragTexCoord;
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int boneIndex0 = int(vertexBoneIds.x);
|
||||||
|
int boneIndex1 = int(vertexBoneIds.y);
|
||||||
|
int boneIndex2 = int(vertexBoneIds.z);
|
||||||
|
int boneIndex3 = int(vertexBoneIds.w);
|
||||||
|
|
||||||
|
vec4 skinnedPosition =
|
||||||
|
vertexBoneWeights.x * (boneMatrices[boneIndex0] * vec4(vertexPosition, 1.0f)) +
|
||||||
|
vertexBoneWeights.y * (boneMatrices[boneIndex1] * vec4(vertexPosition, 1.0f)) +
|
||||||
|
vertexBoneWeights.z * (boneMatrices[boneIndex2] * vec4(vertexPosition, 1.0f)) +
|
||||||
|
vertexBoneWeights.w * (boneMatrices[boneIndex3] * vec4(vertexPosition, 1.0f));
|
||||||
|
|
||||||
|
fragTexCoord = vertexTexCoord;
|
||||||
|
fragColor = vertexColor;
|
||||||
|
|
||||||
|
gl_Position = mvp * skinnedPosition;
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 5.6 KiB |
|
|
@ -47,7 +47,7 @@ int main(void)
|
||||||
|
|
||||||
UnloadImage(cat); // Unload image from RAM
|
UnloadImage(cat); // Unload image from RAM
|
||||||
|
|
||||||
// Load custom font for frawing on image
|
// Load custom font for drawing on image
|
||||||
Font font = LoadFont("resources/custom_jupiter_crash.png");
|
Font font = LoadFont("resources/custom_jupiter_crash.png");
|
||||||
|
|
||||||
// Draw over image using custom font
|
// Draw over image using custom font
|
||||||
|
|
@ -93,4 +93,4 @@ int main(void)
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
/*******************************************************************************************
|
|
||||||
*
|
|
||||||
* raylib [textures] example - SVG loading and texture creation
|
|
||||||
*
|
|
||||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
|
||||||
*
|
|
||||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
|
||||||
*
|
|
||||||
* 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) 2022 Dennis Meinen (@bixxy#4258 on Discord)
|
|
||||||
*
|
|
||||||
********************************************************************************************/
|
|
||||||
|
|
||||||
#include "raylib.h"
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
// Program main entry point
|
|
||||||
//------------------------------------------------------------------------------------
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
// Initialization
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
const int screenWidth = 800;
|
|
||||||
const int screenHeight = 450;
|
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - svg loading");
|
|
||||||
|
|
||||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
|
||||||
|
|
||||||
Image image = LoadImageSvg("resources/test.svg", 400, 350); // Loaded in CPU memory (RAM)
|
|
||||||
Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
|
|
||||||
UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
|
||||||
|
|
||||||
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
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
// TODO: Update your variables here
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Draw
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
BeginDrawing();
|
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
|
||||||
|
|
||||||
DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE);
|
|
||||||
|
|
||||||
//Red border to illustrate how the SVG is centered within the specified dimensions
|
|
||||||
DrawRectangleLines((screenWidth / 2 - texture.width / 2) - 1, (screenHeight / 2 - texture.height / 2) - 1, texture.width + 2, texture.height + 2, RED);
|
|
||||||
|
|
||||||
DrawText("this IS a texture loaded from an SVG file!", 300, 410, 10, GRAY);
|
|
||||||
|
|
||||||
EndDrawing();
|
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
}
|
|
||||||
|
|
||||||
// De-Initialization
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
UnloadTexture(texture); // Texture unloading
|
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
|
||||||
//--------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
|
|
@ -41,7 +41,7 @@ OPTIONS:
|
||||||
-f, --format <type> : Define output format for parser data.
|
-f, --format <type> : Define output format for parser data.
|
||||||
Supported types: DEFAULT, JSON, XML, LUA
|
Supported types: DEFAULT, JSON, XML, LUA
|
||||||
|
|
||||||
-d, --define <DEF> : Define functions specifiers (i.e. RLAPI for raylib.h, RMDEF for raymath.h, etc.)
|
-d, --define <DEF> : Define functions specifiers (i.e. RLAPI for raylib.h, RMAPI for raymath.h, etc.)
|
||||||
NOTE: If no specifier defined, defaults to: RLAPI
|
NOTE: If no specifier defined, defaults to: RLAPI
|
||||||
|
|
||||||
-t, --truncate <after> : Define string to truncate input after (i.e. "RLGL IMPLEMENTATION" for rlgl.h)
|
-t, --truncate <after> : Define string to truncate input after (i.e. "RLGL IMPLEMENTATION" for rlgl.h)
|
||||||
|
|
@ -56,7 +56,7 @@ EXAMPLES:
|
||||||
> raylib_parser --output raylib_data.info --format XML
|
> raylib_parser --output raylib_data.info --format XML
|
||||||
Process <raylib.h> to generate <raylib_data.info> as XML text data
|
Process <raylib.h> to generate <raylib_data.info> as XML text data
|
||||||
|
|
||||||
> raylib_parser --input raymath.h --output raymath_data.info --format XML
|
> raylib_parser --input raymath.h --output raymath_data.info --format XML --define RMAPI
|
||||||
Process <raymath.h> to generate <raymath_data.info> as XML text data
|
Process <raymath.h> to generate <raymath_data.info> as XML text data
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -850,12 +850,22 @@
|
||||||
{
|
{
|
||||||
"type": "unsigned char *",
|
"type": "unsigned char *",
|
||||||
"name": "boneIds",
|
"name": "boneIds",
|
||||||
"description": "Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning)"
|
"description": "Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) (shader-location = 6)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "float *",
|
"type": "float *",
|
||||||
"name": "boneWeights",
|
"name": "boneWeights",
|
||||||
"description": "Vertex bone weight, up to 4 bones influence by vertex (skinning)"
|
"description": "Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Matrix *",
|
||||||
|
"name": "boneMatrices",
|
||||||
|
"description": "Bones animated transformation matrices"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "int",
|
||||||
|
"name": "boneCount",
|
||||||
|
"description": "Number of bones"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "unsigned int",
|
"type": "unsigned int",
|
||||||
|
|
@ -2518,6 +2528,21 @@
|
||||||
"name": "SHADER_LOC_MAP_BRDF",
|
"name": "SHADER_LOC_MAP_BRDF",
|
||||||
"value": 25,
|
"value": 25,
|
||||||
"description": "Shader location: sampler2d texture: brdf"
|
"description": "Shader location: sampler2d texture: brdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SHADER_LOC_VERTEX_BONEIDS",
|
||||||
|
"value": 26,
|
||||||
|
"description": "Shader location: vertex attribute: boneIds"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SHADER_LOC_VERTEX_BONEWEIGHTS",
|
||||||
|
"value": 27,
|
||||||
|
"description": "Shader location: vertex attribute: boneWeights"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SHADER_LOC_BONE_MATRICES",
|
||||||
|
"value": 28,
|
||||||
|
"description": "Shader location: array of matrices uniform: boneMatrices"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -3215,12 +3240,12 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ToggleFullscreen",
|
"name": "ToggleFullscreen",
|
||||||
"description": "Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP)",
|
"description": "Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)",
|
||||||
"returnType": "void"
|
"returnType": "void"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ToggleBorderlessWindowed",
|
"name": "ToggleBorderlessWindowed",
|
||||||
"description": "Toggle window state: borderless windowed (only PLATFORM_DESKTOP)",
|
"description": "Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)",
|
||||||
"returnType": "void"
|
"returnType": "void"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -3738,8 +3763,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsShaderReady",
|
"name": "IsShaderValid",
|
||||||
"description": "Check if a shader is ready",
|
"description": "Check if a shader is valid (loaded on GPU)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -4477,6 +4502,17 @@
|
||||||
"description": "Get the directory of the running application (uses static string)",
|
"description": "Get the directory of the running application (uses static string)",
|
||||||
"returnType": "const char *"
|
"returnType": "const char *"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "MakeDirectory",
|
||||||
|
"description": "Create directories (including full path requested), returns 0 on success",
|
||||||
|
"returnType": "int",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "const char *",
|
||||||
|
"name": "dirPath"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ChangeDirectory",
|
"name": "ChangeDirectory",
|
||||||
"description": "Change working directory, return true on success",
|
"description": "Change working directory, return true on success",
|
||||||
|
|
@ -4523,7 +4559,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "LoadDirectoryFilesEx",
|
"name": "LoadDirectoryFilesEx",
|
||||||
"description": "Load directory filepaths with extension filtering and recursive directory scan",
|
"description": "Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result",
|
||||||
"returnType": "FilePathList",
|
"returnType": "FilePathList",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -4655,6 +4691,51 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "ComputeCRC32",
|
||||||
|
"description": "Compute CRC32 hash code",
|
||||||
|
"returnType": "unsigned int",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "unsigned char *",
|
||||||
|
"name": "data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "int",
|
||||||
|
"name": "dataSize"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ComputeMD5",
|
||||||
|
"description": "Compute MD5 hash code, returns static int[4] (16 bytes)",
|
||||||
|
"returnType": "unsigned int *",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "unsigned char *",
|
||||||
|
"name": "data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "int",
|
||||||
|
"name": "dataSize"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ComputeSHA1",
|
||||||
|
"description": "Compute SHA1 hash code, returns static int[5] (20 bytes)",
|
||||||
|
"returnType": "unsigned int *",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "unsigned char *",
|
||||||
|
"name": "data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "int",
|
||||||
|
"name": "dataSize"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "LoadAutomationEventList",
|
"name": "LoadAutomationEventList",
|
||||||
"description": "Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS",
|
"description": "Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS",
|
||||||
|
|
@ -5150,7 +5231,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "GetGestureHoldDuration",
|
"name": "GetGestureHoldDuration",
|
||||||
"description": "Get gesture hold time in milliseconds",
|
"description": "Get gesture hold time in seconds",
|
||||||
"returnType": "float"
|
"returnType": "float"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -5238,7 +5319,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DrawPixel",
|
"name": "DrawPixel",
|
||||||
"description": "Draw a pixel",
|
"description": "Draw a pixel using geometry [Can be slow, use with care]",
|
||||||
"returnType": "void",
|
"returnType": "void",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -5257,7 +5338,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DrawPixelV",
|
"name": "DrawPixelV",
|
||||||
"description": "Draw a pixel (Vector version)",
|
"description": "Draw a pixel using geometry (Vector version) [Can be slow, use with care]",
|
||||||
"returnType": "void",
|
"returnType": "void",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -6779,25 +6860,6 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "LoadImageSvg",
|
|
||||||
"description": "Load image from SVG file data or string with specified size",
|
|
||||||
"returnType": "Image",
|
|
||||||
"params": [
|
|
||||||
{
|
|
||||||
"type": "const char *",
|
|
||||||
"name": "fileNameOrString"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "int",
|
|
||||||
"name": "width"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "int",
|
|
||||||
"name": "height"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "LoadImageAnim",
|
"name": "LoadImageAnim",
|
||||||
"description": "Load image sequence from file (frames appended to image.data)",
|
"description": "Load image sequence from file (frames appended to image.data)",
|
||||||
|
|
@ -6872,8 +6934,8 @@
|
||||||
"returnType": "Image"
|
"returnType": "Image"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsImageReady",
|
"name": "IsImageValid",
|
||||||
"description": "Check if an image is ready",
|
"description": "Check if an image is valid (data and parameters)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -8336,8 +8398,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsTextureReady",
|
"name": "IsTextureValid",
|
||||||
"description": "Check if a texture is ready",
|
"description": "Check if a texture is valid (loaded in GPU)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -8358,8 +8420,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsRenderTextureReady",
|
"name": "IsRenderTextureValid",
|
||||||
"description": "Check if a render texture is ready",
|
"description": "Check if a render texture is valid (loaded in GPU)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -8780,6 +8842,25 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "ColorLerp",
|
||||||
|
"description": "Get color lerp interpolation between two colors, factor [0.0f..1.0f]",
|
||||||
|
"returnType": "Color",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "Color",
|
||||||
|
"name": "color1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Color",
|
||||||
|
"name": "color2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "float",
|
||||||
|
"name": "factor"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "GetColor",
|
"name": "GetColor",
|
||||||
"description": "Get Color structure from hexadecimal value",
|
"description": "Get Color structure from hexadecimal value",
|
||||||
|
|
@ -8862,7 +8943,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "LoadFontEx",
|
"name": "LoadFontEx",
|
||||||
"description": "Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character setFont",
|
"description": "Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height",
|
||||||
"returnType": "Font",
|
"returnType": "Font",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -8934,8 +9015,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsFontReady",
|
"name": "IsFontValid",
|
||||||
"description": "Check if a font is ready",
|
"description": "Check if a font is valid (font data loaded, WARNING: GPU texture not checked)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -10226,8 +10307,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsModelReady",
|
"name": "IsModelValid",
|
||||||
"description": "Check if a model is ready",
|
"description": "Check if a model is valid (loaded in GPU, VAO/VBOs)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -10366,6 +10447,60 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawModelPoints",
|
||||||
|
"description": "Draw a model as points",
|
||||||
|
"returnType": "void",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "Model",
|
||||||
|
"name": "model"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Vector3",
|
||||||
|
"name": "position"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "float",
|
||||||
|
"name": "scale"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Color",
|
||||||
|
"name": "tint"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DrawModelPointsEx",
|
||||||
|
"description": "Draw a model as points with extended parameters",
|
||||||
|
"returnType": "void",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "Model",
|
||||||
|
"name": "model"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Vector3",
|
||||||
|
"name": "position"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Vector3",
|
||||||
|
"name": "rotationAxis"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "float",
|
||||||
|
"name": "rotationAngle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Vector3",
|
||||||
|
"name": "scale"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Color",
|
||||||
|
"name": "tint"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "DrawBoundingBox",
|
"name": "DrawBoundingBox",
|
||||||
"description": "Draw bounding box (wires)",
|
"description": "Draw bounding box (wires)",
|
||||||
|
|
@ -10859,8 +10994,8 @@
|
||||||
"returnType": "Material"
|
"returnType": "Material"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsMaterialReady",
|
"name": "IsMaterialValid",
|
||||||
"description": "Check if a material is ready",
|
"description": "Check if a material is valid (shader assigned, map textures loaded in GPU)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -10993,6 +11128,25 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "UpdateModelAnimationBoneMatrices",
|
||||||
|
"description": "Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)",
|
||||||
|
"returnType": "void",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "Model",
|
||||||
|
"name": "model"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModelAnimation",
|
||||||
|
"name": "anim"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "int",
|
||||||
|
"name": "frame"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "CheckCollisionSpheres",
|
"name": "CheckCollisionSpheres",
|
||||||
"description": "Check collision between two spheres",
|
"description": "Check collision between two spheres",
|
||||||
|
|
@ -11215,8 +11369,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsWaveReady",
|
"name": "IsWaveValid",
|
||||||
"description": "Checks if wave data is ready",
|
"description": "Checks if wave data is valid (data loaded and parameters)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -11259,8 +11413,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsSoundReady",
|
"name": "IsSoundValid",
|
||||||
"description": "Checks if a sound is ready",
|
"description": "Checks if a sound is valid (data loaded and buffers initialized)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -11557,8 +11711,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsMusicReady",
|
"name": "IsMusicValid",
|
||||||
"description": "Checks if a music stream is ready",
|
"description": "Checks if a music stream is valid (context and buffers initialized)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
@ -11746,8 +11900,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IsAudioStreamReady",
|
"name": "IsAudioStreamValid",
|
||||||
"description": "Checks if an audio stream is ready",
|
"description": "Checks if an audio stream is valid (buffers initialized)",
|
||||||
"returnType": "bool",
|
"returnType": "bool",
|
||||||
"params": [
|
"params": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -850,12 +850,22 @@ return {
|
||||||
{
|
{
|
||||||
type = "unsigned char *",
|
type = "unsigned char *",
|
||||||
name = "boneIds",
|
name = "boneIds",
|
||||||
description = "Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning)"
|
description = "Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) (shader-location = 6)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "float *",
|
type = "float *",
|
||||||
name = "boneWeights",
|
name = "boneWeights",
|
||||||
description = "Vertex bone weight, up to 4 bones influence by vertex (skinning)"
|
description = "Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "Matrix *",
|
||||||
|
name = "boneMatrices",
|
||||||
|
description = "Bones animated transformation matrices"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type = "int",
|
||||||
|
name = "boneCount",
|
||||||
|
description = "Number of bones"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "unsigned int",
|
type = "unsigned int",
|
||||||
|
|
@ -2518,6 +2528,21 @@ return {
|
||||||
name = "SHADER_LOC_MAP_BRDF",
|
name = "SHADER_LOC_MAP_BRDF",
|
||||||
value = 25,
|
value = 25,
|
||||||
description = "Shader location: sampler2d texture: brdf"
|
description = "Shader location: sampler2d texture: brdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "SHADER_LOC_VERTEX_BONEIDS",
|
||||||
|
value = 26,
|
||||||
|
description = "Shader location: vertex attribute: boneIds"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "SHADER_LOC_VERTEX_BONEWEIGHTS",
|
||||||
|
value = 27,
|
||||||
|
description = "Shader location: vertex attribute: boneWeights"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "SHADER_LOC_BONE_MATRICES",
|
||||||
|
value = 28,
|
||||||
|
description = "Shader location: array of matrices uniform: boneMatrices"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -3158,12 +3183,12 @@ return {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "ToggleFullscreen",
|
name = "ToggleFullscreen",
|
||||||
description = "Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP)",
|
description = "Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)",
|
||||||
returnType = "void"
|
returnType = "void"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "ToggleBorderlessWindowed",
|
name = "ToggleBorderlessWindowed",
|
||||||
description = "Toggle window state: borderless windowed (only PLATFORM_DESKTOP)",
|
description = "Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)",
|
||||||
returnType = "void"
|
returnType = "void"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -3564,8 +3589,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsShaderReady",
|
name = "IsShaderValid",
|
||||||
description = "Check if a shader is ready",
|
description = "Check if a shader is valid (loaded on GPU)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Shader", name = "shader"}
|
{type = "Shader", name = "shader"}
|
||||||
|
|
@ -4042,6 +4067,14 @@ return {
|
||||||
description = "Get the directory of the running application (uses static string)",
|
description = "Get the directory of the running application (uses static string)",
|
||||||
returnType = "const char *"
|
returnType = "const char *"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name = "MakeDirectory",
|
||||||
|
description = "Create directories (including full path requested), returns 0 on success",
|
||||||
|
returnType = "int",
|
||||||
|
params = {
|
||||||
|
{type = "const char *", name = "dirPath"}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name = "ChangeDirectory",
|
name = "ChangeDirectory",
|
||||||
description = "Change working directory, return true on success",
|
description = "Change working directory, return true on success",
|
||||||
|
|
@ -4076,7 +4109,7 @@ return {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "LoadDirectoryFilesEx",
|
name = "LoadDirectoryFilesEx",
|
||||||
description = "Load directory filepaths with extension filtering and recursive directory scan",
|
description = "Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result",
|
||||||
returnType = "FilePathList",
|
returnType = "FilePathList",
|
||||||
params = {
|
params = {
|
||||||
{type = "const char *", name = "basePath"},
|
{type = "const char *", name = "basePath"},
|
||||||
|
|
@ -4157,6 +4190,33 @@ return {
|
||||||
{type = "int *", name = "outputSize"}
|
{type = "int *", name = "outputSize"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name = "ComputeCRC32",
|
||||||
|
description = "Compute CRC32 hash code",
|
||||||
|
returnType = "unsigned int",
|
||||||
|
params = {
|
||||||
|
{type = "unsigned char *", name = "data"},
|
||||||
|
{type = "int", name = "dataSize"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "ComputeMD5",
|
||||||
|
description = "Compute MD5 hash code, returns static int[4] (16 bytes)",
|
||||||
|
returnType = "unsigned int *",
|
||||||
|
params = {
|
||||||
|
{type = "unsigned char *", name = "data"},
|
||||||
|
{type = "int", name = "dataSize"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "ComputeSHA1",
|
||||||
|
description = "Compute SHA1 hash code, returns static int[5] (20 bytes)",
|
||||||
|
returnType = "unsigned int *",
|
||||||
|
params = {
|
||||||
|
{type = "unsigned char *", name = "data"},
|
||||||
|
{type = "int", name = "dataSize"}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name = "LoadAutomationEventList",
|
name = "LoadAutomationEventList",
|
||||||
description = "Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS",
|
description = "Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS",
|
||||||
|
|
@ -4517,7 +4577,7 @@ return {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "GetGestureHoldDuration",
|
name = "GetGestureHoldDuration",
|
||||||
description = "Get gesture hold time in milliseconds",
|
description = "Get gesture hold time in seconds",
|
||||||
returnType = "float"
|
returnType = "float"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -4581,7 +4641,7 @@ return {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "DrawPixel",
|
name = "DrawPixel",
|
||||||
description = "Draw a pixel",
|
description = "Draw a pixel using geometry [Can be slow, use with care]",
|
||||||
returnType = "void",
|
returnType = "void",
|
||||||
params = {
|
params = {
|
||||||
{type = "int", name = "posX"},
|
{type = "int", name = "posX"},
|
||||||
|
|
@ -4591,7 +4651,7 @@ return {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "DrawPixelV",
|
name = "DrawPixelV",
|
||||||
description = "Draw a pixel (Vector version)",
|
description = "Draw a pixel using geometry (Vector version) [Can be slow, use with care]",
|
||||||
returnType = "void",
|
returnType = "void",
|
||||||
params = {
|
params = {
|
||||||
{type = "Vector2", name = "position"},
|
{type = "Vector2", name = "position"},
|
||||||
|
|
@ -5306,16 +5366,6 @@ return {
|
||||||
{type = "int", name = "headerSize"}
|
{type = "int", name = "headerSize"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name = "LoadImageSvg",
|
|
||||||
description = "Load image from SVG file data or string with specified size",
|
|
||||||
returnType = "Image",
|
|
||||||
params = {
|
|
||||||
{type = "const char *", name = "fileNameOrString"},
|
|
||||||
{type = "int", name = "width"},
|
|
||||||
{type = "int", name = "height"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name = "LoadImageAnim",
|
name = "LoadImageAnim",
|
||||||
description = "Load image sequence from file (frames appended to image.data)",
|
description = "Load image sequence from file (frames appended to image.data)",
|
||||||
|
|
@ -5360,8 +5410,8 @@ return {
|
||||||
returnType = "Image"
|
returnType = "Image"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsImageReady",
|
name = "IsImageValid",
|
||||||
description = "Check if an image is ready",
|
description = "Check if an image is valid (data and parameters)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Image", name = "image"}
|
{type = "Image", name = "image"}
|
||||||
|
|
@ -6125,8 +6175,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsTextureReady",
|
name = "IsTextureValid",
|
||||||
description = "Check if a texture is ready",
|
description = "Check if a texture is valid (loaded in GPU)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Texture2D", name = "texture"}
|
{type = "Texture2D", name = "texture"}
|
||||||
|
|
@ -6141,8 +6191,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsRenderTextureReady",
|
name = "IsRenderTextureValid",
|
||||||
description = "Check if a render texture is ready",
|
description = "Check if a render texture is valid (loaded in GPU)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "RenderTexture2D", name = "target"}
|
{type = "RenderTexture2D", name = "target"}
|
||||||
|
|
@ -6377,6 +6427,16 @@ return {
|
||||||
{type = "Color", name = "tint"}
|
{type = "Color", name = "tint"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name = "ColorLerp",
|
||||||
|
description = "Get color lerp interpolation between two colors, factor [0.0f..1.0f]",
|
||||||
|
returnType = "Color",
|
||||||
|
params = {
|
||||||
|
{type = "Color", name = "color1"},
|
||||||
|
{type = "Color", name = "color2"},
|
||||||
|
{type = "float", name = "factor"}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name = "GetColor",
|
name = "GetColor",
|
||||||
description = "Get Color structure from hexadecimal value",
|
description = "Get Color structure from hexadecimal value",
|
||||||
|
|
@ -6429,7 +6489,7 @@ return {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "LoadFontEx",
|
name = "LoadFontEx",
|
||||||
description = "Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character setFont",
|
description = "Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height",
|
||||||
returnType = "Font",
|
returnType = "Font",
|
||||||
params = {
|
params = {
|
||||||
{type = "const char *", name = "fileName"},
|
{type = "const char *", name = "fileName"},
|
||||||
|
|
@ -6462,8 +6522,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsFontReady",
|
name = "IsFontValid",
|
||||||
description = "Check if a font is ready",
|
description = "Check if a font is valid (font data loaded, WARNING: GPU texture not checked)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Font", name = "font"}
|
{type = "Font", name = "font"}
|
||||||
|
|
@ -7142,8 +7202,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsModelReady",
|
name = "IsModelValid",
|
||||||
description = "Check if a model is ready",
|
description = "Check if a model is valid (loaded in GPU, VAO/VBOs)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Model", name = "model"}
|
{type = "Model", name = "model"}
|
||||||
|
|
@ -7213,6 +7273,30 @@ return {
|
||||||
{type = "Color", name = "tint"}
|
{type = "Color", name = "tint"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name = "DrawModelPoints",
|
||||||
|
description = "Draw a model as points",
|
||||||
|
returnType = "void",
|
||||||
|
params = {
|
||||||
|
{type = "Model", name = "model"},
|
||||||
|
{type = "Vector3", name = "position"},
|
||||||
|
{type = "float", name = "scale"},
|
||||||
|
{type = "Color", name = "tint"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "DrawModelPointsEx",
|
||||||
|
description = "Draw a model as points with extended parameters",
|
||||||
|
returnType = "void",
|
||||||
|
params = {
|
||||||
|
{type = "Model", name = "model"},
|
||||||
|
{type = "Vector3", name = "position"},
|
||||||
|
{type = "Vector3", name = "rotationAxis"},
|
||||||
|
{type = "float", name = "rotationAngle"},
|
||||||
|
{type = "Vector3", name = "scale"},
|
||||||
|
{type = "Color", name = "tint"}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name = "DrawBoundingBox",
|
name = "DrawBoundingBox",
|
||||||
description = "Draw bounding box (wires)",
|
description = "Draw bounding box (wires)",
|
||||||
|
|
@ -7472,8 +7556,8 @@ return {
|
||||||
returnType = "Material"
|
returnType = "Material"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsMaterialReady",
|
name = "IsMaterialValid",
|
||||||
description = "Check if a material is ready",
|
description = "Check if a material is valid (shader assigned, map textures loaded in GPU)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Material", name = "material"}
|
{type = "Material", name = "material"}
|
||||||
|
|
@ -7552,6 +7636,16 @@ return {
|
||||||
{type = "ModelAnimation", name = "anim"}
|
{type = "ModelAnimation", name = "anim"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name = "UpdateModelAnimationBoneMatrices",
|
||||||
|
description = "Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)",
|
||||||
|
returnType = "void",
|
||||||
|
params = {
|
||||||
|
{type = "Model", name = "model"},
|
||||||
|
{type = "ModelAnimation", name = "anim"},
|
||||||
|
{type = "int", name = "frame"}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name = "CheckCollisionSpheres",
|
name = "CheckCollisionSpheres",
|
||||||
description = "Check collision between two spheres",
|
description = "Check collision between two spheres",
|
||||||
|
|
@ -7681,8 +7775,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsWaveReady",
|
name = "IsWaveValid",
|
||||||
description = "Checks if wave data is ready",
|
description = "Checks if wave data is valid (data loaded and parameters)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Wave", name = "wave"}
|
{type = "Wave", name = "wave"}
|
||||||
|
|
@ -7713,8 +7807,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsSoundReady",
|
name = "IsSoundValid",
|
||||||
description = "Checks if a sound is ready",
|
description = "Checks if a sound is valid (data loaded and buffers initialized)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Sound", name = "sound"}
|
{type = "Sound", name = "sound"}
|
||||||
|
|
@ -7903,8 +7997,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsMusicReady",
|
name = "IsMusicValid",
|
||||||
description = "Checks if a music stream is ready",
|
description = "Checks if a music stream is valid (context and buffers initialized)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "Music", name = "music"}
|
{type = "Music", name = "music"}
|
||||||
|
|
@ -8029,8 +8123,8 @@ return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "IsAudioStreamReady",
|
name = "IsAudioStreamValid",
|
||||||
description = "Checks if an audio stream is ready",
|
description = "Checks if an audio stream is valid (buffers initialized)",
|
||||||
returnType = "bool",
|
returnType = "bool",
|
||||||
params = {
|
params = {
|
||||||
{type = "AudioStream", name = "stream"}
|
{type = "AudioStream", name = "stream"}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -160,7 +160,7 @@
|
||||||
<Field type="float" name="rotation" desc="Camera rotation in degrees" />
|
<Field type="float" name="rotation" desc="Camera rotation in degrees" />
|
||||||
<Field type="float" name="zoom" desc="Camera zoom (scaling), should be 1.0f by default" />
|
<Field type="float" name="zoom" desc="Camera zoom (scaling), should be 1.0f by default" />
|
||||||
</Struct>
|
</Struct>
|
||||||
<Struct name="Mesh" fieldCount="15" desc="Mesh, vertex data and vao/vbo">
|
<Struct name="Mesh" fieldCount="17" desc="Mesh, vertex data and vao/vbo">
|
||||||
<Field type="int" name="vertexCount" desc="Number of vertices stored in arrays" />
|
<Field type="int" name="vertexCount" desc="Number of vertices stored in arrays" />
|
||||||
<Field type="int" name="triangleCount" desc="Number of triangles stored (indexed or not)" />
|
<Field type="int" name="triangleCount" desc="Number of triangles stored (indexed or not)" />
|
||||||
<Field type="float *" name="vertices" desc="Vertex position (XYZ - 3 components per vertex) (shader-location = 0)" />
|
<Field type="float *" name="vertices" desc="Vertex position (XYZ - 3 components per vertex) (shader-location = 0)" />
|
||||||
|
|
@ -172,8 +172,10 @@
|
||||||
<Field type="unsigned short *" name="indices" desc="Vertex indices (in case vertex data comes indexed)" />
|
<Field type="unsigned short *" name="indices" desc="Vertex indices (in case vertex data comes indexed)" />
|
||||||
<Field type="float *" name="animVertices" desc="Animated vertex positions (after bones transformations)" />
|
<Field type="float *" name="animVertices" desc="Animated vertex positions (after bones transformations)" />
|
||||||
<Field type="float *" name="animNormals" desc="Animated normals (after bones transformations)" />
|
<Field type="float *" name="animNormals" desc="Animated normals (after bones transformations)" />
|
||||||
<Field type="unsigned char *" name="boneIds" desc="Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning)" />
|
<Field type="unsigned char *" name="boneIds" desc="Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) (shader-location = 6)" />
|
||||||
<Field type="float *" name="boneWeights" desc="Vertex bone weight, up to 4 bones influence by vertex (skinning)" />
|
<Field type="float *" name="boneWeights" desc="Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7)" />
|
||||||
|
<Field type="Matrix *" name="boneMatrices" desc="Bones animated transformation matrices" />
|
||||||
|
<Field type="int" name="boneCount" desc="Number of bones" />
|
||||||
<Field type="unsigned int" name="vaoId" desc="OpenGL Vertex Array Object id" />
|
<Field type="unsigned int" name="vaoId" desc="OpenGL Vertex Array Object id" />
|
||||||
<Field type="unsigned int *" name="vboId" desc="OpenGL Vertex Buffer Objects id (default vertex data)" />
|
<Field type="unsigned int *" name="vboId" desc="OpenGL Vertex Buffer Objects id (default vertex data)" />
|
||||||
</Struct>
|
</Struct>
|
||||||
|
|
@ -505,7 +507,7 @@
|
||||||
<Value name="MATERIAL_MAP_PREFILTER" integer="9" desc="Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP)" />
|
<Value name="MATERIAL_MAP_PREFILTER" integer="9" desc="Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP)" />
|
||||||
<Value name="MATERIAL_MAP_BRDF" integer="10" desc="Brdf material" />
|
<Value name="MATERIAL_MAP_BRDF" integer="10" desc="Brdf material" />
|
||||||
</Enum>
|
</Enum>
|
||||||
<Enum name="ShaderLocationIndex" valueCount="26" desc="Shader location index">
|
<Enum name="ShaderLocationIndex" valueCount="29" desc="Shader location index">
|
||||||
<Value name="SHADER_LOC_VERTEX_POSITION" integer="0" desc="Shader location: vertex attribute: position" />
|
<Value name="SHADER_LOC_VERTEX_POSITION" integer="0" desc="Shader location: vertex attribute: position" />
|
||||||
<Value name="SHADER_LOC_VERTEX_TEXCOORD01" integer="1" desc="Shader location: vertex attribute: texcoord01" />
|
<Value name="SHADER_LOC_VERTEX_TEXCOORD01" integer="1" desc="Shader location: vertex attribute: texcoord01" />
|
||||||
<Value name="SHADER_LOC_VERTEX_TEXCOORD02" integer="2" desc="Shader location: vertex attribute: texcoord02" />
|
<Value name="SHADER_LOC_VERTEX_TEXCOORD02" integer="2" desc="Shader location: vertex attribute: texcoord02" />
|
||||||
|
|
@ -532,6 +534,9 @@
|
||||||
<Value name="SHADER_LOC_MAP_IRRADIANCE" integer="23" desc="Shader location: samplerCube texture: irradiance" />
|
<Value name="SHADER_LOC_MAP_IRRADIANCE" integer="23" desc="Shader location: samplerCube texture: irradiance" />
|
||||||
<Value name="SHADER_LOC_MAP_PREFILTER" integer="24" desc="Shader location: samplerCube texture: prefilter" />
|
<Value name="SHADER_LOC_MAP_PREFILTER" integer="24" desc="Shader location: samplerCube texture: prefilter" />
|
||||||
<Value name="SHADER_LOC_MAP_BRDF" integer="25" desc="Shader location: sampler2d texture: brdf" />
|
<Value name="SHADER_LOC_MAP_BRDF" integer="25" desc="Shader location: sampler2d texture: brdf" />
|
||||||
|
<Value name="SHADER_LOC_VERTEX_BONEIDS" integer="26" desc="Shader location: vertex attribute: boneIds" />
|
||||||
|
<Value name="SHADER_LOC_VERTEX_BONEWEIGHTS" integer="27" desc="Shader location: vertex attribute: boneWeights" />
|
||||||
|
<Value name="SHADER_LOC_BONE_MATRICES" integer="28" desc="Shader location: array of matrices uniform: boneMatrices" />
|
||||||
</Enum>
|
</Enum>
|
||||||
<Enum name="ShaderUniformDataType" valueCount="9" desc="Shader uniform data type">
|
<Enum name="ShaderUniformDataType" valueCount="9" desc="Shader uniform data type">
|
||||||
<Value name="SHADER_UNIFORM_FLOAT" integer="0" desc="Shader uniform type: float" />
|
<Value name="SHADER_UNIFORM_FLOAT" integer="0" desc="Shader uniform type: float" />
|
||||||
|
|
@ -670,7 +675,7 @@
|
||||||
<Param type="unsigned int" name="frames" desc="" />
|
<Param type="unsigned int" name="frames" desc="" />
|
||||||
</Callback>
|
</Callback>
|
||||||
</Callbacks>
|
</Callbacks>
|
||||||
<Functions count="573">
|
<Functions count="580">
|
||||||
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
||||||
<Param type="int" name="width" desc="" />
|
<Param type="int" name="width" desc="" />
|
||||||
<Param type="int" name="height" desc="" />
|
<Param type="int" name="height" desc="" />
|
||||||
|
|
@ -703,9 +708,9 @@
|
||||||
<Function name="ClearWindowState" retType="void" paramCount="1" desc="Clear window configuration state flags">
|
<Function name="ClearWindowState" retType="void" paramCount="1" desc="Clear window configuration state flags">
|
||||||
<Param type="unsigned int" name="flags" desc="" />
|
<Param type="unsigned int" name="flags" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="ToggleFullscreen" retType="void" paramCount="0" desc="Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP)">
|
<Function name="ToggleFullscreen" retType="void" paramCount="0" desc="Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="ToggleBorderlessWindowed" retType="void" paramCount="0" desc="Toggle window state: borderless windowed (only PLATFORM_DESKTOP)">
|
<Function name="ToggleBorderlessWindowed" retType="void" paramCount="0" desc="Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="MaximizeWindow" retType="void" paramCount="0" desc="Set window state: maximized, if resizable (only PLATFORM_DESKTOP)">
|
<Function name="MaximizeWindow" retType="void" paramCount="0" desc="Set window state: maximized, if resizable (only PLATFORM_DESKTOP)">
|
||||||
</Function>
|
</Function>
|
||||||
|
|
@ -866,7 +871,7 @@
|
||||||
<Param type="const char *" name="vsCode" desc="" />
|
<Param type="const char *" name="vsCode" desc="" />
|
||||||
<Param type="const char *" name="fsCode" desc="" />
|
<Param type="const char *" name="fsCode" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsShaderReady" retType="bool" paramCount="1" desc="Check if a shader is ready">
|
<Function name="IsShaderValid" retType="bool" paramCount="1" desc="Check if a shader is valid (loaded on GPU)">
|
||||||
<Param type="Shader" name="shader" desc="" />
|
<Param type="Shader" name="shader" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetShaderLocation" retType="int" paramCount="2" desc="Get shader uniform location">
|
<Function name="GetShaderLocation" retType="int" paramCount="2" desc="Get shader uniform location">
|
||||||
|
|
@ -1069,6 +1074,9 @@
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetApplicationDirectory" retType="const char *" paramCount="0" desc="Get the directory of the running application (uses static string)">
|
<Function name="GetApplicationDirectory" retType="const char *" paramCount="0" desc="Get the directory of the running application (uses static string)">
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name="MakeDirectory" retType="int" paramCount="1" desc="Create directories (including full path requested), returns 0 on success">
|
||||||
|
<Param type="const char *" name="dirPath" desc="" />
|
||||||
|
</Function>
|
||||||
<Function name="ChangeDirectory" retType="bool" paramCount="1" desc="Change working directory, return true on success">
|
<Function name="ChangeDirectory" retType="bool" paramCount="1" desc="Change working directory, return true on success">
|
||||||
<Param type="const char *" name="dir" desc="" />
|
<Param type="const char *" name="dir" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
|
@ -1081,7 +1089,7 @@
|
||||||
<Function name="LoadDirectoryFiles" retType="FilePathList" paramCount="1" desc="Load directory filepaths">
|
<Function name="LoadDirectoryFiles" retType="FilePathList" paramCount="1" desc="Load directory filepaths">
|
||||||
<Param type="const char *" name="dirPath" desc="" />
|
<Param type="const char *" name="dirPath" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="LoadDirectoryFilesEx" retType="FilePathList" paramCount="3" desc="Load directory filepaths with extension filtering and recursive directory scan">
|
<Function name="LoadDirectoryFilesEx" retType="FilePathList" paramCount="3" desc="Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result">
|
||||||
<Param type="const char *" name="basePath" desc="" />
|
<Param type="const char *" name="basePath" desc="" />
|
||||||
<Param type="const char *" name="filter" desc="" />
|
<Param type="const char *" name="filter" desc="" />
|
||||||
<Param type="bool" name="scanSubdirs" desc="" />
|
<Param type="bool" name="scanSubdirs" desc="" />
|
||||||
|
|
@ -1118,6 +1126,18 @@
|
||||||
<Param type="const unsigned char *" name="data" desc="" />
|
<Param type="const unsigned char *" name="data" desc="" />
|
||||||
<Param type="int *" name="outputSize" desc="" />
|
<Param type="int *" name="outputSize" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name="ComputeCRC32" retType="unsigned int" paramCount="2" desc="Compute CRC32 hash code">
|
||||||
|
<Param type="unsigned char *" name="data" desc="" />
|
||||||
|
<Param type="int" name="dataSize" desc="" />
|
||||||
|
</Function>
|
||||||
|
<Function name="ComputeMD5" retType="unsigned int *" paramCount="2" desc="Compute MD5 hash code, returns static int[4] (16 bytes)">
|
||||||
|
<Param type="unsigned char *" name="data" desc="" />
|
||||||
|
<Param type="int" name="dataSize" desc="" />
|
||||||
|
</Function>
|
||||||
|
<Function name="ComputeSHA1" retType="unsigned int *" paramCount="2" desc="Compute SHA1 hash code, returns static int[5] (20 bytes)">
|
||||||
|
<Param type="unsigned char *" name="data" desc="" />
|
||||||
|
<Param type="int" name="dataSize" desc="" />
|
||||||
|
</Function>
|
||||||
<Function name="LoadAutomationEventList" retType="AutomationEventList" paramCount="1" desc="Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS">
|
<Function name="LoadAutomationEventList" retType="AutomationEventList" paramCount="1" desc="Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS">
|
||||||
<Param type="const char *" name="fileName" desc="" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
|
@ -1261,7 +1281,7 @@
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetGestureDetected" retType="int" paramCount="0" desc="Get latest detected gesture">
|
<Function name="GetGestureDetected" retType="int" paramCount="0" desc="Get latest detected gesture">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetGestureHoldDuration" retType="float" paramCount="0" desc="Get gesture hold time in milliseconds">
|
<Function name="GetGestureHoldDuration" retType="float" paramCount="0" desc="Get gesture hold time in seconds">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetGestureDragVector" retType="Vector2" paramCount="0" desc="Get gesture drag vector">
|
<Function name="GetGestureDragVector" retType="Vector2" paramCount="0" desc="Get gesture drag vector">
|
||||||
</Function>
|
</Function>
|
||||||
|
|
@ -1289,12 +1309,12 @@
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetShapesTextureRectangle" retType="Rectangle" paramCount="0" desc="Get texture source rectangle that is used for shapes drawing">
|
<Function name="GetShapesTextureRectangle" retType="Rectangle" paramCount="0" desc="Get texture source rectangle that is used for shapes drawing">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="DrawPixel" retType="void" paramCount="3" desc="Draw a pixel">
|
<Function name="DrawPixel" retType="void" paramCount="3" desc="Draw a pixel using geometry [Can be slow, use with care]">
|
||||||
<Param type="int" name="posX" desc="" />
|
<Param type="int" name="posX" desc="" />
|
||||||
<Param type="int" name="posY" desc="" />
|
<Param type="int" name="posY" desc="" />
|
||||||
<Param type="Color" name="color" desc="" />
|
<Param type="Color" name="color" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="DrawPixelV" retType="void" paramCount="2" desc="Draw a pixel (Vector version)">
|
<Function name="DrawPixelV" retType="void" paramCount="2" desc="Draw a pixel using geometry (Vector version) [Can be slow, use with care]">
|
||||||
<Param type="Vector2" name="position" desc="" />
|
<Param type="Vector2" name="position" desc="" />
|
||||||
<Param type="Color" name="color" desc="" />
|
<Param type="Color" name="color" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
|
@ -1691,11 +1711,6 @@
|
||||||
<Param type="int" name="format" desc="" />
|
<Param type="int" name="format" desc="" />
|
||||||
<Param type="int" name="headerSize" desc="" />
|
<Param type="int" name="headerSize" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="LoadImageSvg" retType="Image" paramCount="3" desc="Load image from SVG file data or string with specified size">
|
|
||||||
<Param type="const char *" name="fileNameOrString" desc="" />
|
|
||||||
<Param type="int" name="width" desc="" />
|
|
||||||
<Param type="int" name="height" desc="" />
|
|
||||||
</Function>
|
|
||||||
<Function name="LoadImageAnim" retType="Image" paramCount="2" desc="Load image sequence from file (frames appended to image.data)">
|
<Function name="LoadImageAnim" retType="Image" paramCount="2" desc="Load image sequence from file (frames appended to image.data)">
|
||||||
<Param type="const char *" name="fileName" desc="" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
<Param type="int *" name="frames" desc="" />
|
<Param type="int *" name="frames" desc="" />
|
||||||
|
|
@ -1716,7 +1731,7 @@
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="LoadImageFromScreen" retType="Image" paramCount="0" desc="Load image from screen buffer and (screenshot)">
|
<Function name="LoadImageFromScreen" retType="Image" paramCount="0" desc="Load image from screen buffer and (screenshot)">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsImageReady" retType="bool" paramCount="1" desc="Check if an image is ready">
|
<Function name="IsImageValid" retType="bool" paramCount="1" desc="Check if an image is valid (data and parameters)">
|
||||||
<Param type="Image" name="image" desc="" />
|
<Param type="Image" name="image" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="UnloadImage" retType="void" paramCount="1" desc="Unload image from CPU memory (RAM)">
|
<Function name="UnloadImage" retType="void" paramCount="1" desc="Unload image from CPU memory (RAM)">
|
||||||
|
|
@ -2101,13 +2116,13 @@
|
||||||
<Param type="int" name="width" desc="" />
|
<Param type="int" name="width" desc="" />
|
||||||
<Param type="int" name="height" desc="" />
|
<Param type="int" name="height" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsTextureReady" retType="bool" paramCount="1" desc="Check if a texture is ready">
|
<Function name="IsTextureValid" retType="bool" paramCount="1" desc="Check if a texture is valid (loaded in GPU)">
|
||||||
<Param type="Texture2D" name="texture" desc="" />
|
<Param type="Texture2D" name="texture" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="UnloadTexture" retType="void" paramCount="1" desc="Unload texture from GPU memory (VRAM)">
|
<Function name="UnloadTexture" retType="void" paramCount="1" desc="Unload texture from GPU memory (VRAM)">
|
||||||
<Param type="Texture2D" name="texture" desc="" />
|
<Param type="Texture2D" name="texture" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsRenderTextureReady" retType="bool" paramCount="1" desc="Check if a render texture is ready">
|
<Function name="IsRenderTextureValid" retType="bool" paramCount="1" desc="Check if a render texture is valid (loaded in GPU)">
|
||||||
<Param type="RenderTexture2D" name="target" desc="" />
|
<Param type="RenderTexture2D" name="target" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="UnloadRenderTexture" retType="void" paramCount="1" desc="Unload render texture from GPU memory (VRAM)">
|
<Function name="UnloadRenderTexture" retType="void" paramCount="1" desc="Unload render texture from GPU memory (VRAM)">
|
||||||
|
|
@ -2219,6 +2234,11 @@
|
||||||
<Param type="Color" name="src" desc="" />
|
<Param type="Color" name="src" desc="" />
|
||||||
<Param type="Color" name="tint" desc="" />
|
<Param type="Color" name="tint" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name="ColorLerp" retType="Color" paramCount="3" desc="Get color lerp interpolation between two colors, factor [0.0f..1.0f]">
|
||||||
|
<Param type="Color" name="color1" desc="" />
|
||||||
|
<Param type="Color" name="color2" desc="" />
|
||||||
|
<Param type="float" name="factor" desc="" />
|
||||||
|
</Function>
|
||||||
<Function name="GetColor" retType="Color" paramCount="1" desc="Get Color structure from hexadecimal value">
|
<Function name="GetColor" retType="Color" paramCount="1" desc="Get Color structure from hexadecimal value">
|
||||||
<Param type="unsigned int" name="hexValue" desc="" />
|
<Param type="unsigned int" name="hexValue" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
|
@ -2241,7 +2261,7 @@
|
||||||
<Function name="LoadFont" retType="Font" paramCount="1" desc="Load font from file into GPU memory (VRAM)">
|
<Function name="LoadFont" retType="Font" paramCount="1" desc="Load font from file into GPU memory (VRAM)">
|
||||||
<Param type="const char *" name="fileName" desc="" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="LoadFontEx" retType="Font" paramCount="4" desc="Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character setFont">
|
<Function name="LoadFontEx" retType="Font" paramCount="4" desc="Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height">
|
||||||
<Param type="const char *" name="fileName" desc="" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
<Param type="int" name="fontSize" desc="" />
|
<Param type="int" name="fontSize" desc="" />
|
||||||
<Param type="int *" name="codepoints" desc="" />
|
<Param type="int *" name="codepoints" desc="" />
|
||||||
|
|
@ -2260,7 +2280,7 @@
|
||||||
<Param type="int *" name="codepoints" desc="" />
|
<Param type="int *" name="codepoints" desc="" />
|
||||||
<Param type="int" name="codepointCount" desc="" />
|
<Param type="int" name="codepointCount" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsFontReady" retType="bool" paramCount="1" desc="Check if a font is ready">
|
<Function name="IsFontValid" retType="bool" paramCount="1" desc="Check if a font is valid (font data loaded, WARNING: GPU texture not checked)">
|
||||||
<Param type="Font" name="font" desc="" />
|
<Param type="Font" name="font" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="LoadFontData" retType="GlyphInfo *" paramCount="6" desc="Load font data for further use">
|
<Function name="LoadFontData" retType="GlyphInfo *" paramCount="6" desc="Load font data for further use">
|
||||||
|
|
@ -2600,7 +2620,7 @@
|
||||||
<Function name="LoadModelFromMesh" retType="Model" paramCount="1" desc="Load model from generated mesh (default material)">
|
<Function name="LoadModelFromMesh" retType="Model" paramCount="1" desc="Load model from generated mesh (default material)">
|
||||||
<Param type="Mesh" name="mesh" desc="" />
|
<Param type="Mesh" name="mesh" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsModelReady" retType="bool" paramCount="1" desc="Check if a model is ready">
|
<Function name="IsModelValid" retType="bool" paramCount="1" desc="Check if a model is valid (loaded in GPU, VAO/VBOs)">
|
||||||
<Param type="Model" name="model" desc="" />
|
<Param type="Model" name="model" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="UnloadModel" retType="void" paramCount="1" desc="Unload model (including meshes) from memory (RAM and/or VRAM)">
|
<Function name="UnloadModel" retType="void" paramCount="1" desc="Unload model (including meshes) from memory (RAM and/or VRAM)">
|
||||||
|
|
@ -2637,6 +2657,20 @@
|
||||||
<Param type="Vector3" name="scale" desc="" />
|
<Param type="Vector3" name="scale" desc="" />
|
||||||
<Param type="Color" name="tint" desc="" />
|
<Param type="Color" name="tint" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name="DrawModelPoints" retType="void" paramCount="4" desc="Draw a model as points">
|
||||||
|
<Param type="Model" name="model" desc="" />
|
||||||
|
<Param type="Vector3" name="position" desc="" />
|
||||||
|
<Param type="float" name="scale" desc="" />
|
||||||
|
<Param type="Color" name="tint" desc="" />
|
||||||
|
</Function>
|
||||||
|
<Function name="DrawModelPointsEx" retType="void" paramCount="6" desc="Draw a model as points with extended parameters">
|
||||||
|
<Param type="Model" name="model" desc="" />
|
||||||
|
<Param type="Vector3" name="position" desc="" />
|
||||||
|
<Param type="Vector3" name="rotationAxis" desc="" />
|
||||||
|
<Param type="float" name="rotationAngle" desc="" />
|
||||||
|
<Param type="Vector3" name="scale" desc="" />
|
||||||
|
<Param type="Color" name="tint" desc="" />
|
||||||
|
</Function>
|
||||||
<Function name="DrawBoundingBox" retType="void" paramCount="2" desc="Draw bounding box (wires)">
|
<Function name="DrawBoundingBox" retType="void" paramCount="2" desc="Draw bounding box (wires)">
|
||||||
<Param type="BoundingBox" name="box" desc="" />
|
<Param type="BoundingBox" name="box" desc="" />
|
||||||
<Param type="Color" name="color" desc="" />
|
<Param type="Color" name="color" desc="" />
|
||||||
|
|
@ -2767,7 +2801,7 @@
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="LoadMaterialDefault" retType="Material" paramCount="0" desc="Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)">
|
<Function name="LoadMaterialDefault" retType="Material" paramCount="0" desc="Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsMaterialReady" retType="bool" paramCount="1" desc="Check if a material is ready">
|
<Function name="IsMaterialValid" retType="bool" paramCount="1" desc="Check if a material is valid (shader assigned, map textures loaded in GPU)">
|
||||||
<Param type="Material" name="material" desc="" />
|
<Param type="Material" name="material" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="UnloadMaterial" retType="void" paramCount="1" desc="Unload material from GPU memory (VRAM)">
|
<Function name="UnloadMaterial" retType="void" paramCount="1" desc="Unload material from GPU memory (VRAM)">
|
||||||
|
|
@ -2803,6 +2837,11 @@
|
||||||
<Param type="Model" name="model" desc="" />
|
<Param type="Model" name="model" desc="" />
|
||||||
<Param type="ModelAnimation" name="anim" desc="" />
|
<Param type="ModelAnimation" name="anim" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name="UpdateModelAnimationBoneMatrices" retType="void" paramCount="3" desc="Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)">
|
||||||
|
<Param type="Model" name="model" desc="" />
|
||||||
|
<Param type="ModelAnimation" name="anim" desc="" />
|
||||||
|
<Param type="int" name="frame" desc="" />
|
||||||
|
</Function>
|
||||||
<Function name="CheckCollisionSpheres" retType="bool" paramCount="4" desc="Check collision between two spheres">
|
<Function name="CheckCollisionSpheres" retType="bool" paramCount="4" desc="Check collision between two spheres">
|
||||||
<Param type="Vector3" name="center1" desc="" />
|
<Param type="Vector3" name="center1" desc="" />
|
||||||
<Param type="float" name="radius1" desc="" />
|
<Param type="float" name="radius1" desc="" />
|
||||||
|
|
@ -2864,7 +2903,7 @@
|
||||||
<Param type="const unsigned char *" name="fileData" desc="" />
|
<Param type="const unsigned char *" name="fileData" desc="" />
|
||||||
<Param type="int" name="dataSize" desc="" />
|
<Param type="int" name="dataSize" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsWaveReady" retType="bool" paramCount="1" desc="Checks if wave data is ready">
|
<Function name="IsWaveValid" retType="bool" paramCount="1" desc="Checks if wave data is valid (data loaded and parameters)">
|
||||||
<Param type="Wave" name="wave" desc="" />
|
<Param type="Wave" name="wave" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="LoadSound" retType="Sound" paramCount="1" desc="Load sound from file">
|
<Function name="LoadSound" retType="Sound" paramCount="1" desc="Load sound from file">
|
||||||
|
|
@ -2876,7 +2915,7 @@
|
||||||
<Function name="LoadSoundAlias" retType="Sound" paramCount="1" desc="Create a new sound that shares the same sample data as the source sound, does not own the sound data">
|
<Function name="LoadSoundAlias" retType="Sound" paramCount="1" desc="Create a new sound that shares the same sample data as the source sound, does not own the sound data">
|
||||||
<Param type="Sound" name="source" desc="" />
|
<Param type="Sound" name="source" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsSoundReady" retType="bool" paramCount="1" desc="Checks if a sound is ready">
|
<Function name="IsSoundValid" retType="bool" paramCount="1" desc="Checks if a sound is valid (data loaded and buffers initialized)">
|
||||||
<Param type="Sound" name="sound" desc="" />
|
<Param type="Sound" name="sound" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="UpdateSound" retType="void" paramCount="3" desc="Update sound buffer with new data">
|
<Function name="UpdateSound" retType="void" paramCount="3" desc="Update sound buffer with new data">
|
||||||
|
|
@ -2956,7 +2995,7 @@
|
||||||
<Param type="const unsigned char *" name="data" desc="" />
|
<Param type="const unsigned char *" name="data" desc="" />
|
||||||
<Param type="int" name="dataSize" desc="" />
|
<Param type="int" name="dataSize" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsMusicReady" retType="bool" paramCount="1" desc="Checks if a music stream is ready">
|
<Function name="IsMusicValid" retType="bool" paramCount="1" desc="Checks if a music stream is valid (context and buffers initialized)">
|
||||||
<Param type="Music" name="music" desc="" />
|
<Param type="Music" name="music" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="UnloadMusicStream" retType="void" paramCount="1" desc="Unload music stream">
|
<Function name="UnloadMusicStream" retType="void" paramCount="1" desc="Unload music stream">
|
||||||
|
|
@ -3007,7 +3046,7 @@
|
||||||
<Param type="unsigned int" name="sampleSize" desc="" />
|
<Param type="unsigned int" name="sampleSize" desc="" />
|
||||||
<Param type="unsigned int" name="channels" desc="" />
|
<Param type="unsigned int" name="channels" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsAudioStreamReady" retType="bool" paramCount="1" desc="Checks if an audio stream is ready">
|
<Function name="IsAudioStreamValid" retType="bool" paramCount="1" desc="Checks if an audio stream is valid (buffers initialized)">
|
||||||
<Param type="AudioStream" name="stream" desc="" />
|
<Param type="AudioStream" name="stream" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="UnloadAudioStream" retType="void" paramCount="1" desc="Unload audio stream and free memory">
|
<Function name="UnloadAudioStream" retType="void" paramCount="1" desc="Unload audio stream and free memory">
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
#define MAX_CALLBACKS_TO_PARSE 64 // Maximum number of callbacks to parse
|
#define MAX_CALLBACKS_TO_PARSE 64 // Maximum number of callbacks to parse
|
||||||
#define MAX_FUNCS_TO_PARSE 1024 // Maximum number of functions to parse
|
#define MAX_FUNCS_TO_PARSE 1024 // Maximum number of functions to parse
|
||||||
|
|
||||||
#define MAX_LINE_LENGTH 512 // Maximum length of one line (including comments)
|
#define MAX_LINE_LENGTH 1024 // Maximum length of one line (including comments)
|
||||||
|
|
||||||
#define MAX_STRUCT_FIELDS 64 // Maximum number of struct fields
|
#define MAX_STRUCT_FIELDS 64 // Maximum number of struct fields
|
||||||
#define MAX_ENUM_VALUES 512 // Maximum number of enum values
|
#define MAX_ENUM_VALUES 512 // Maximum number of enum values
|
||||||
|
|
@ -139,7 +139,7 @@ typedef struct EnumInfo {
|
||||||
// Function info data
|
// Function info data
|
||||||
typedef struct FunctionInfo {
|
typedef struct FunctionInfo {
|
||||||
char name[64]; // Function name
|
char name[64]; // Function name
|
||||||
char desc[128]; // Function description (comment at the end)
|
char desc[512]; // Function description (comment at the end)
|
||||||
char retType[32]; // Return value type
|
char retType[32]; // Return value type
|
||||||
int paramCount; // Number of function parameters
|
int paramCount; // Number of function parameters
|
||||||
char paramType[MAX_FUNCTION_PARAMETERS][32]; // Parameters type
|
char paramType[MAX_FUNCTION_PARAMETERS][32]; // Parameters type
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ target_link_libraries(${PROJECT_NAME} raylib)
|
||||||
|
|
||||||
# Web Configurations
|
# Web Configurations
|
||||||
if (${PLATFORM} STREQUAL "Web")
|
if (${PLATFORM} STREQUAL "Web")
|
||||||
# Tell Emscripten to build an example.html file.
|
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html") # Tell Emscripten to build an example.html file.
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY -s GL_ENABLE_GET_PROC_ADDRESS=1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Checks if OSX and links appropriate frameworks (Only required on MacOS)
|
# Checks if OSX and links appropriate frameworks (Only required on MacOS)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,6 @@ Compiling for the web requires the [Emscripten SDK](https://emscripten.org/docs/
|
||||||
``` bash
|
``` bash
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
emcmake cmake .. -DPLATFORM=Web -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS="-s USE_GLFW=3" -DCMAKE_EXECUTABLE_SUFFIX=".html"
|
emcmake cmake .. -DPLATFORM=Web -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXECUTABLE_SUFFIX=".html"
|
||||||
emmake make
|
emmake make
|
||||||
```
|
```
|
||||||
|
|
|
||||||
387
projects/VS2022/examples/models_gpu_skinning.vcxproj
Normal file
387
projects/VS2022/examples/models_gpu_skinning.vcxproj
Normal file
|
|
@ -0,0 +1,387 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug.DLL|Win32">
|
||||||
|
<Configuration>Debug.DLL</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug.DLL|x64">
|
||||||
|
<Configuration>Debug.DLL</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release.DLL|Win32">
|
||||||
|
<Configuration>Release.DLL</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release.DLL|x64">
|
||||||
|
<Configuration>Release.DLL</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{8245DAD9-D402-4D5C-8F45-32229CD3B263}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>models_loading</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>models_gpu_skinning</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
|
||||||
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||||
|
<Message>Copy Debug DLL to output directory</Message>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||||
|
<Message>Copy Debug DLL to output directory</Message>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Message>Copy Release DLL to output directory</Message>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Message>Copy Release DLL to output directory</Message>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\examples\models\models_gpu_skinning.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\raylib\raylib.vcxproj">
|
||||||
|
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -293,12 +293,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_outline", "
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_tiling", "examples\shaders_texture_tiling.vcxproj", "{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_tiling", "examples\shaders_texture_tiling.vcxproj", "{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_svg_loading", "examples\textures_svg_loading.vcxproj", "{D8026C60-CCBC-45DF-9085-BF21569EB414}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_splines_drawing", "examples\shapes_splines_drawing.vcxproj", "{DF25E545-00FF-4E64-844C-7DF98991F901}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_splines_drawing", "examples\shapes_splines_drawing.vcxproj", "{DF25E545-00FF-4E64-844C-7DF98991F901}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_top_down_lights", "examples\shapes_top_down_lights.vcxproj", "{703BE7BA-5B99-4F70-806D-3A259F6A991E}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_top_down_lights", "examples\shapes_top_down_lights.vcxproj", "{703BE7BA-5B99-4F70-806D-3A259F6A991E}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_gpu_skinning", "examples\models_gpu_skinning.vcxproj", "{8245DAD9-D402-4D5C-8F45-32229CD3B263}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug.DLL|x64 = Debug.DLL|x64
|
Debug.DLL|x64 = Debug.DLL|x64
|
||||||
|
|
@ -2531,6 +2531,22 @@ Global
|
||||||
{703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x64.Build.0 = Release|x64
|
{703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x64.Build.0 = Release|x64
|
||||||
{703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.ActiveCfg = Release|Win32
|
{703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.Build.0 = Release|Win32
|
{703BE7BA-5B99-4F70-806D-3A259F6A991E}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x64.Build.0 = Release.DLL|x64
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release.DLL|x86.Build.0 = Release.DLL|Win32
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x64.Build.0 = Release|x64
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -2682,6 +2698,7 @@ Global
|
||||||
{D8026C60-CCBC-45DF-9085-BF21569EB414} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
|
{D8026C60-CCBC-45DF-9085-BF21569EB414} = {DA049009-21FF-4AC0-84E4-830DD1BCD0CE}
|
||||||
{DF25E545-00FF-4E64-844C-7DF98991F901} = {278D8859-20B1-428F-8448-064F46E1F021}
|
{DF25E545-00FF-4E64-844C-7DF98991F901} = {278D8859-20B1-428F-8448-064F46E1F021}
|
||||||
{703BE7BA-5B99-4F70-806D-3A259F6A991E} = {278D8859-20B1-428F-8448-064F46E1F021}
|
{703BE7BA-5B99-4F70-806D-3A259F6A991E} = {278D8859-20B1-428F-8448-064F46E1F021}
|
||||||
|
{8245DAD9-D402-4D5C-8F45-32229CD3B263} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
|
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
|
||||||
|
|
|
||||||
|
|
@ -352,9 +352,9 @@ SRC_DIR = src
|
||||||
OBJ_DIR = obj
|
OBJ_DIR = obj
|
||||||
|
|
||||||
# Define all object files from source files
|
# Define all object files from source files
|
||||||
SRC = $(call rwildcard, *.c, *.h)
|
SRC = $(call rwildcard, ./, *.c, *.h)
|
||||||
#OBJS = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
#OBJS = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
||||||
OBJS ?= main.c
|
OBJS = $(patsubst %.c,%.o,$(filter %.c,$(SRC)))
|
||||||
|
|
||||||
# For Android platform we call a custom Makefile.Android
|
# For Android platform we call a custom Makefile.Android
|
||||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,9 @@ RAYLIB_MODULE_RAYGUI_PATH ?= $(RAYLIB_SRC_PATH)/../../raygui/src
|
||||||
# Use external GLFW library instead of rglfw module
|
# Use external GLFW library instead of rglfw module
|
||||||
USE_EXTERNAL_GLFW ?= FALSE
|
USE_EXTERNAL_GLFW ?= FALSE
|
||||||
|
|
||||||
# Enable support for both Wayland and X11 by default on Linux when using GLFW
|
# Enable support for X11 by default on Linux when using GLFW
|
||||||
GLFW_LINUX_ENABLE_WAYLAND ?= TRUE
|
# NOTE: Wayland is disabled by default, only enable if you are sure
|
||||||
|
GLFW_LINUX_ENABLE_WAYLAND ?= FALSE
|
||||||
GLFW_LINUX_ENABLE_X11 ?= TRUE
|
GLFW_LINUX_ENABLE_X11 ?= TRUE
|
||||||
|
|
||||||
# PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally
|
# PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally
|
||||||
|
|
|
||||||
377
src/build.zig
377
src/build.zig
|
|
@ -1,377 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
const builtin = @import("builtin");
|
|
||||||
|
|
||||||
comptime {
|
|
||||||
if (builtin.zig_version.minor < 12) @compileError("Raylib requires zig version 0.12.0");
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(freakmangd): I don't like using a global here, but it prevents having to
|
|
||||||
// get the flags a second time when adding raygui
|
|
||||||
var raylib_flags_arr: std.ArrayListUnmanaged([]const u8) = .{};
|
|
||||||
|
|
||||||
/// we're not inside the actual build script recognized by the
|
|
||||||
/// zig build system; use this type where one would otherwise
|
|
||||||
/// use `@This()` when inside the actual entrypoint file.
|
|
||||||
const BuildScript = @import("../build.zig");
|
|
||||||
|
|
||||||
// This has been tested with zig version 0.12.0
|
|
||||||
pub fn addRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
|
||||||
const raylib_dep = b.dependencyFromBuildZig(BuildScript, .{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
.raudio = options.raudio,
|
|
||||||
.rmodels = options.rmodels,
|
|
||||||
.rshapes = options.rshapes,
|
|
||||||
.rtext = options.rtext,
|
|
||||||
.rtextures = options.rtextures,
|
|
||||||
.platform_drm = options.platform_drm,
|
|
||||||
.shared = options.shared,
|
|
||||||
.linux_display_backend = options.linux_display_backend,
|
|
||||||
.opengl_version = options.opengl_version,
|
|
||||||
.config = options.config,
|
|
||||||
});
|
|
||||||
const raylib = raylib_dep.artifact("raylib");
|
|
||||||
|
|
||||||
if (options.raygui) {
|
|
||||||
const raygui_dep = b.dependency(options.raygui_dependency_name, .{});
|
|
||||||
addRaygui(b, raylib, raygui_dep);
|
|
||||||
}
|
|
||||||
|
|
||||||
return raylib;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
|
||||||
raylib_flags_arr.clearRetainingCapacity();
|
|
||||||
|
|
||||||
const shared_flags = &[_][]const u8{
|
|
||||||
"-fPIC",
|
|
||||||
"-DBUILD_LIBTYPE_SHARED",
|
|
||||||
};
|
|
||||||
try raylib_flags_arr.appendSlice(b.allocator, &[_][]const u8{
|
|
||||||
"-std=gnu99",
|
|
||||||
"-D_GNU_SOURCE",
|
|
||||||
"-DGL_SILENCE_DEPRECATION=199309L",
|
|
||||||
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
|
|
||||||
});
|
|
||||||
if (options.config) |config| {
|
|
||||||
const file = try std.fs.path.join(b.allocator, &.{ std.fs.path.dirname(@src().file) orelse ".", "config.h" });
|
|
||||||
defer b.allocator.free(file);
|
|
||||||
const content = try std.fs.cwd().readFileAlloc(b.allocator, file, std.math.maxInt(usize));
|
|
||||||
defer b.allocator.free(content);
|
|
||||||
|
|
||||||
var lines = std.mem.splitScalar(u8, content, '\n');
|
|
||||||
while (lines.next()) |line| {
|
|
||||||
if (!std.mem.containsAtLeast(u8, line, 1, "SUPPORT")) continue;
|
|
||||||
if (std.mem.startsWith(u8, line, "//")) continue;
|
|
||||||
|
|
||||||
var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace
|
|
||||||
flag = flag["#define ".len - 1 ..]; // Remove #define
|
|
||||||
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace
|
|
||||||
flag = flag[0..std.mem.indexOf(u8, flag, " ").?]; // Flag is only one word, so capture till space
|
|
||||||
flag = try std.fmt.allocPrint(b.allocator, "-D{s}", .{flag}); // Prepend with -D
|
|
||||||
|
|
||||||
// If user specifies the flag skip it
|
|
||||||
if (std.mem.containsAtLeast(u8, config, 1, flag)) continue;
|
|
||||||
|
|
||||||
// Append default value from config.h to compile flags
|
|
||||||
try raylib_flags_arr.append(b.allocator, flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append config flags supplied by user to compile flags
|
|
||||||
try raylib_flags_arr.append(b.allocator, config);
|
|
||||||
|
|
||||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.shared) {
|
|
||||||
try raylib_flags_arr.appendSlice(b.allocator, shared_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
const raylib = if (options.shared)
|
|
||||||
b.addSharedLibrary(.{
|
|
||||||
.name = "raylib",
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
})
|
|
||||||
else
|
|
||||||
b.addStaticLibrary(.{
|
|
||||||
.name = "raylib",
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
raylib.linkLibC();
|
|
||||||
|
|
||||||
// No GLFW required on PLATFORM_DRM
|
|
||||||
if (!options.platform_drm) {
|
|
||||||
raylib.addIncludePath(b.path("src/external/glfw/include"));
|
|
||||||
}
|
|
||||||
|
|
||||||
var c_source_files = try std.ArrayList([]const u8).initCapacity(b.allocator, 2);
|
|
||||||
c_source_files.appendSliceAssumeCapacity(&.{ "rcore.c", "utils.c" });
|
|
||||||
|
|
||||||
if (options.raudio) {
|
|
||||||
try c_source_files.append("raudio.c");
|
|
||||||
}
|
|
||||||
if (options.rmodels) {
|
|
||||||
try c_source_files.append("rmodels.c");
|
|
||||||
}
|
|
||||||
if (options.rshapes) {
|
|
||||||
try c_source_files.append("rshapes.c");
|
|
||||||
}
|
|
||||||
if (options.rtext) {
|
|
||||||
try c_source_files.append("rtext.c");
|
|
||||||
}
|
|
||||||
if (options.rtextures) {
|
|
||||||
try c_source_files.append("rtextures.c");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.opengl_version != .auto) {
|
|
||||||
raylib.defineCMacro(options.opengl_version.toCMacroStr(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (target.result.os.tag) {
|
|
||||||
.windows => {
|
|
||||||
try c_source_files.append("rglfw.c");
|
|
||||||
raylib.linkSystemLibrary("winmm");
|
|
||||||
raylib.linkSystemLibrary("gdi32");
|
|
||||||
raylib.linkSystemLibrary("opengl32");
|
|
||||||
|
|
||||||
raylib.defineCMacro("PLATFORM_DESKTOP", null);
|
|
||||||
},
|
|
||||||
.linux => {
|
|
||||||
if (!options.platform_drm) {
|
|
||||||
try c_source_files.append("rglfw.c");
|
|
||||||
raylib.linkSystemLibrary("GL");
|
|
||||||
raylib.linkSystemLibrary("rt");
|
|
||||||
raylib.linkSystemLibrary("dl");
|
|
||||||
raylib.linkSystemLibrary("m");
|
|
||||||
|
|
||||||
raylib.addLibraryPath(.{ .cwd_relative = "/usr/lib" });
|
|
||||||
raylib.addIncludePath(.{ .cwd_relative = "/usr/include" });
|
|
||||||
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
|
||||||
raylib.defineCMacro("_GLFW_X11", null);
|
|
||||||
raylib.linkSystemLibrary("X11");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
|
|
||||||
_ = b.findProgram(&.{"wayland-scanner"}, &.{}) catch {
|
|
||||||
std.log.err(
|
|
||||||
\\ Wayland may not be installed on the system.
|
|
||||||
\\ You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend`
|
|
||||||
, .{});
|
|
||||||
@panic("No Wayland");
|
|
||||||
};
|
|
||||||
raylib.defineCMacro("_GLFW_WAYLAND", null);
|
|
||||||
raylib.linkSystemLibrary("wayland-client");
|
|
||||||
raylib.linkSystemLibrary("wayland-cursor");
|
|
||||||
raylib.linkSystemLibrary("wayland-egl");
|
|
||||||
raylib.linkSystemLibrary("xkbcommon");
|
|
||||||
raylib.addIncludePath(b.path("src"));
|
|
||||||
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
|
|
||||||
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
|
|
||||||
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
|
|
||||||
waylandGenerate(b, raylib, "viewporter.xml", "viewporter-client-protocol");
|
|
||||||
waylandGenerate(b, raylib, "relative-pointer-unstable-v1.xml", "relative-pointer-unstable-v1-client-protocol");
|
|
||||||
waylandGenerate(b, raylib, "pointer-constraints-unstable-v1.xml", "pointer-constraints-unstable-v1-client-protocol");
|
|
||||||
waylandGenerate(b, raylib, "fractional-scale-v1.xml", "fractional-scale-v1-client-protocol");
|
|
||||||
waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol");
|
|
||||||
waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol");
|
|
||||||
}
|
|
||||||
raylib.defineCMacro("PLATFORM_DESKTOP", null);
|
|
||||||
} else {
|
|
||||||
if (options.opengl_version == .auto) {
|
|
||||||
raylib.linkSystemLibrary("GLESv2");
|
|
||||||
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
raylib.linkSystemLibrary("EGL");
|
|
||||||
raylib.linkSystemLibrary("drm");
|
|
||||||
raylib.linkSystemLibrary("gbm");
|
|
||||||
raylib.linkSystemLibrary("pthread");
|
|
||||||
raylib.linkSystemLibrary("rt");
|
|
||||||
raylib.linkSystemLibrary("m");
|
|
||||||
raylib.linkSystemLibrary("dl");
|
|
||||||
raylib.addIncludePath(.{ .cwd_relative = "/usr/include/libdrm" });
|
|
||||||
|
|
||||||
raylib.defineCMacro("PLATFORM_DRM", null);
|
|
||||||
raylib.defineCMacro("EGL_NO_X11", null);
|
|
||||||
raylib.defineCMacro("DEFAULT_BATCH_BUFFER_ELEMENT", "2048");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.freebsd, .openbsd, .netbsd, .dragonfly => {
|
|
||||||
try c_source_files.append("rglfw.c");
|
|
||||||
raylib.linkSystemLibrary("GL");
|
|
||||||
raylib.linkSystemLibrary("rt");
|
|
||||||
raylib.linkSystemLibrary("dl");
|
|
||||||
raylib.linkSystemLibrary("m");
|
|
||||||
raylib.linkSystemLibrary("X11");
|
|
||||||
raylib.linkSystemLibrary("Xrandr");
|
|
||||||
raylib.linkSystemLibrary("Xinerama");
|
|
||||||
raylib.linkSystemLibrary("Xi");
|
|
||||||
raylib.linkSystemLibrary("Xxf86vm");
|
|
||||||
raylib.linkSystemLibrary("Xcursor");
|
|
||||||
|
|
||||||
raylib.defineCMacro("PLATFORM_DESKTOP", null);
|
|
||||||
},
|
|
||||||
.macos => {
|
|
||||||
// On macos rglfw.c include Objective-C files.
|
|
||||||
try raylib_flags_arr.append(b.allocator, "-ObjC");
|
|
||||||
raylib.root_module.addCSourceFile(.{
|
|
||||||
.file = b.path("src/rglfw.c"),
|
|
||||||
.flags = raylib_flags_arr.items,
|
|
||||||
});
|
|
||||||
_ = raylib_flags_arr.pop();
|
|
||||||
raylib.linkFramework("Foundation");
|
|
||||||
raylib.linkFramework("CoreServices");
|
|
||||||
raylib.linkFramework("CoreGraphics");
|
|
||||||
raylib.linkFramework("AppKit");
|
|
||||||
raylib.linkFramework("IOKit");
|
|
||||||
|
|
||||||
raylib.defineCMacro("PLATFORM_DESKTOP", null);
|
|
||||||
},
|
|
||||||
.emscripten => {
|
|
||||||
raylib.defineCMacro("PLATFORM_WEB", null);
|
|
||||||
if (options.opengl_version == .auto) {
|
|
||||||
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b.sysroot == null) {
|
|
||||||
@panic("Pass '--sysroot \"$EMSDK/upstream/emscripten\"'");
|
|
||||||
}
|
|
||||||
|
|
||||||
const cache_include = std.fs.path.join(b.allocator, &.{ b.sysroot.?, "cache", "sysroot", "include" }) catch @panic("Out of memory");
|
|
||||||
defer b.allocator.free(cache_include);
|
|
||||||
|
|
||||||
var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!");
|
|
||||||
dir.close();
|
|
||||||
raylib.addIncludePath(.{ .cwd_relative = cache_include });
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
@panic("Unsupported OS");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
raylib.addIncludePath(b.path("src"));
|
|
||||||
raylib.root_module.addCSourceFiles(.{
|
|
||||||
.root = b.path("src"),
|
|
||||||
.files = c_source_files.items,
|
|
||||||
.flags = raylib_flags_arr.items,
|
|
||||||
});
|
|
||||||
|
|
||||||
return raylib;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function does not need to be called if you passed .raygui = true to addRaylib
|
|
||||||
pub fn addRaygui(b: *std.Build, raylib: *std.Build.Step.Compile, raygui_dep: *std.Build.Dependency) void {
|
|
||||||
if (raylib_flags_arr.items.len == 0) {
|
|
||||||
@panic(
|
|
||||||
\\argument 2 `raylib` in `addRaygui` must come from b.dependency("raylib", ...).artifact("raylib")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var gen_step = b.addWriteFiles();
|
|
||||||
raylib.step.dependOn(&gen_step.step);
|
|
||||||
|
|
||||||
const raygui_c_path = gen_step.add("raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n");
|
|
||||||
raylib.addCSourceFile(.{ .file = raygui_c_path, .flags = raylib_flags_arr.items });
|
|
||||||
raylib.addIncludePath(raygui_dep.path("src"));
|
|
||||||
|
|
||||||
raylib.installHeader(raygui_dep.path("src/raygui.h"), "raygui.h");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Options = struct {
|
|
||||||
raudio: bool = true,
|
|
||||||
rmodels: bool = true,
|
|
||||||
rshapes: bool = true,
|
|
||||||
rtext: bool = true,
|
|
||||||
rtextures: bool = true,
|
|
||||||
raygui: bool = false,
|
|
||||||
platform_drm: bool = false,
|
|
||||||
shared: bool = false,
|
|
||||||
linux_display_backend: LinuxDisplayBackend = .Both,
|
|
||||||
opengl_version: OpenglVersion = .auto,
|
|
||||||
config: ?[]const u8 = null,
|
|
||||||
|
|
||||||
raygui_dependency_name: []const u8 = "raygui",
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const OpenglVersion = enum {
|
|
||||||
auto,
|
|
||||||
gl_1_1,
|
|
||||||
gl_2_1,
|
|
||||||
gl_3_3,
|
|
||||||
gl_4_3,
|
|
||||||
gles_2,
|
|
||||||
gles_3,
|
|
||||||
|
|
||||||
pub fn toCMacroStr(self: @This()) []const u8 {
|
|
||||||
switch (self) {
|
|
||||||
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
|
|
||||||
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
|
|
||||||
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
|
|
||||||
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
|
|
||||||
.gl_4_3 => return "GRAPHICS_API_OPENGL_43",
|
|
||||||
.gles_2 => return "GRAPHICS_API_OPENGL_ES2",
|
|
||||||
.gles_3 => return "GRAPHICS_API_OPENGL_ES3",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const LinuxDisplayBackend = enum {
|
|
||||||
X11,
|
|
||||||
Wayland,
|
|
||||||
Both,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
|
||||||
// Standard target options allows the person running `zig build` to choose
|
|
||||||
// what target to build for. Here we do not override the defaults, which
|
|
||||||
// means any target is allowed, and the default is native. Other options
|
|
||||||
// for restricting supported target set are available.
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
// Standard optimization options allow the person running `zig build` to select
|
|
||||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
|
||||||
// set a preferred release mode, allowing the user to decide how to optimize.
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const defaults = Options{};
|
|
||||||
const options = Options{
|
|
||||||
.platform_drm = b.option(bool, "platform_drm", "Compile raylib in native mode (no X11)") orelse defaults.platform_drm,
|
|
||||||
.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,
|
|
||||||
.rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures,
|
|
||||||
.rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes,
|
|
||||||
.shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared,
|
|
||||||
.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 null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const lib = try compileRaylib(b, target, optimize, options);
|
|
||||||
|
|
||||||
lib.installHeader(b.path("src/raylib.h"), "raylib.h");
|
|
||||||
lib.installHeader(b.path("src/raymath.h"), "raymath.h");
|
|
||||||
lib.installHeader(b.path("src/rlgl.h"), "rlgl.h");
|
|
||||||
|
|
||||||
b.installArtifact(lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
const waylandDir = "src/external/glfw/deps/wayland";
|
|
||||||
|
|
||||||
fn waylandGenerate(b: *std.Build, raylib: *std.Build.Step.Compile, comptime protocol: []const u8, comptime basename: []const u8) void {
|
|
||||||
const protocolDir = waylandDir ++ "/" ++ protocol;
|
|
||||||
const clientHeader = basename ++ ".h";
|
|
||||||
const privateCode = basename ++ "-code.h";
|
|
||||||
|
|
||||||
const client_step = b.addSystemCommand(&.{ "wayland-scanner", "client-header" });
|
|
||||||
client_step.addFileArg(b.path(protocolDir));
|
|
||||||
raylib.addIncludePath(client_step.addOutputFileArg(clientHeader).dirname());
|
|
||||||
|
|
||||||
const private_step = b.addSystemCommand(&.{ "wayland-scanner", "private-code" });
|
|
||||||
private_step.addFileArg(b.path(protocolDir));
|
|
||||||
raylib.addIncludePath(private_step.addOutputFileArg(privateCode).dirname());
|
|
||||||
|
|
||||||
raylib.step.dependOn(&client_step.step);
|
|
||||||
raylib.step.dependOn(&private_step.step);
|
|
||||||
}
|
|
||||||
28
src/config.h
28
src/config.h
|
|
@ -113,12 +113,22 @@
|
||||||
#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance
|
#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance
|
||||||
|
|
||||||
// Default shader vertex attribute locations
|
// Default shader vertex attribute locations
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
|
||||||
|
|
||||||
|
|
||||||
|
#define RL_SUPPORT_MESH_GPU_SKINNING // Remove this if your GPU does not support more than 8 VBOs
|
||||||
|
|
||||||
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Default shader vertex attribute names to set location points
|
// Default shader vertex attribute names to set location points
|
||||||
// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience
|
// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience
|
||||||
|
|
@ -170,7 +180,6 @@
|
||||||
//#define SUPPORT_FILEFORMAT_ASTC 1
|
//#define SUPPORT_FILEFORMAT_ASTC 1
|
||||||
//#define SUPPORT_FILEFORMAT_PKM 1
|
//#define SUPPORT_FILEFORMAT_PKM 1
|
||||||
//#define SUPPORT_FILEFORMAT_PVR 1
|
//#define SUPPORT_FILEFORMAT_PVR 1
|
||||||
//#define SUPPORT_FILEFORMAT_SVG 1
|
|
||||||
|
|
||||||
// Support image export functionality (.png, .bmp, .tga, .jpg, .qoi)
|
// Support image export functionality (.png, .bmp, .tga, .jpg, .qoi)
|
||||||
#define SUPPORT_IMAGE_EXPORT 1
|
#define SUPPORT_IMAGE_EXPORT 1
|
||||||
|
|
@ -225,7 +234,12 @@
|
||||||
// rmodels: Configuration values
|
// rmodels: Configuration values
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
|
#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
|
||||||
|
|
||||||
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
#define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh
|
||||||
|
#else
|
||||||
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
|
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
|
||||||
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module: raudio - Configuration Flags
|
// Module: raudio - Configuration Flags
|
||||||
|
|
|
||||||
267
src/external/RGFW.h
vendored
267
src/external/RGFW.h
vendored
|
|
@ -192,7 +192,7 @@
|
||||||
typedef u32 b32;
|
typedef u32 b32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RGFW_TRUE 1
|
#define RGFW_TRUE (!(0))
|
||||||
#define RGFW_FALSE 0
|
#define RGFW_FALSE 0
|
||||||
|
|
||||||
/* thse OS macros looks better & are standardized */
|
/* thse OS macros looks better & are standardized */
|
||||||
|
|
@ -276,11 +276,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RGFW_EGL
|
#ifdef RGFW_EGL
|
||||||
#if defined(__APPLE__)
|
|
||||||
#warning EGL is not supported for Cocoa, switching back to the native opengl api
|
|
||||||
#undef RGFW_EGL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#elif defined(RGFW_OSMESA)
|
#elif defined(RGFW_OSMESA)
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
|
|
@ -611,10 +606,17 @@ typedef struct RGFW_window {
|
||||||
/** * @defgroup Window_management
|
/** * @defgroup Window_management
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* the class name for X11 and WinAPI. apps with the same class will be grouped by the WM
|
||||||
|
* by default the class name will == the root window's name
|
||||||
|
*/
|
||||||
|
RGFWDEF void RGFW_setClassName(char* name);
|
||||||
|
|
||||||
/*! this has to be set before createWindow is called, else the fulscreen size is used */
|
/*! this has to be set before createWindow is called, else the fulscreen size is used */
|
||||||
RGFWDEF void RGFW_setBufferSize(RGFW_area size); /*!< the buffer cannot be resized (by RGFW) */
|
RGFWDEF void RGFW_setBufferSize(RGFW_area size); /*!< the buffer cannot be resized (by RGFW) */
|
||||||
|
|
||||||
RGFW_window* RGFW_createWindow(
|
RGFWDEF RGFW_window* RGFW_createWindow(
|
||||||
const char* name, /* name of the window */
|
const char* name, /* name of the window */
|
||||||
RGFW_rect rect, /* rect of window */
|
RGFW_rect rect, /* rect of window */
|
||||||
u16 args /* extra arguments (NULL / (u16)0 means no args used)*/
|
u16 args /* extra arguments (NULL / (u16)0 means no args used)*/
|
||||||
|
|
@ -635,7 +637,7 @@ RGFWDEF RGFW_area RGFW_getScreenSize(void);
|
||||||
although you still need some way to tell RGFW to process events eg. `RGFW_window_checkEvents`
|
although you still need some way to tell RGFW to process events eg. `RGFW_window_checkEvents`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RGFW_Event* RGFW_window_checkEvent(RGFW_window* win); /*!< check current event (returns a pointer to win->event or NULL if there is no event)*/
|
RGFWDEF RGFW_Event* RGFW_window_checkEvent(RGFW_window* win); /*!< check current event (returns a pointer to win->event or NULL if there is no event)*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
for RGFW_window_eventWait and RGFW_window_checkEvents
|
for RGFW_window_eventWait and RGFW_window_checkEvents
|
||||||
|
|
@ -706,7 +708,7 @@ RGFWDEF void RGFW_window_setName(RGFW_window* win,
|
||||||
char* name
|
char* name
|
||||||
);
|
);
|
||||||
|
|
||||||
void RGFW_window_setIcon(RGFW_window* win, /*!< source window */
|
RGFWDEF void RGFW_window_setIcon(RGFW_window* win, /*!< source window */
|
||||||
u8* icon /*!< icon bitmap */,
|
u8* icon /*!< icon bitmap */,
|
||||||
RGFW_area a /*!< width and height of the bitmap*/,
|
RGFW_area a /*!< width and height of the bitmap*/,
|
||||||
i32 channels /*!< how many channels the bitmap has (rgb : 3, rgba : 4) */
|
i32 channels /*!< how many channels the bitmap has (rgb : 3, rgba : 4) */
|
||||||
|
|
@ -1609,9 +1611,6 @@ RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) {
|
||||||
if (args & RGFW_FULLSCREEN)
|
if (args & RGFW_FULLSCREEN)
|
||||||
rect = RGFW_RECT(0, 0, screenR.w, screenR.h);
|
rect = RGFW_RECT(0, 0, screenR.w, screenR.h);
|
||||||
|
|
||||||
if (args & RGFW_CENTER)
|
|
||||||
rect = RGFW_RECT((screenR.w - rect.w) / 2, (screenR.h - rect.h) / 2, rect.w, rect.h);
|
|
||||||
|
|
||||||
/* set and init the new window's data */
|
/* set and init the new window's data */
|
||||||
win->r = rect;
|
win->r = rect;
|
||||||
win->event.inFocus = 1;
|
win->event.inFocus = 1;
|
||||||
|
|
@ -1627,7 +1626,7 @@ RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) {
|
||||||
void RGFW_window_scaleToMonitor(RGFW_window* win) {
|
void RGFW_window_scaleToMonitor(RGFW_window* win) {
|
||||||
RGFW_monitor monitor = RGFW_window_getMonitor(win);
|
RGFW_monitor monitor = RGFW_window_getMonitor(win);
|
||||||
|
|
||||||
RGFW_window_resize(win, RGFW_AREA(((u32) monitor.scaleX) * win->r.w, ((u32) monitor.scaleX) * win->r.h));
|
RGFW_window_resize(win, RGFW_AREA((u32)(monitor.scaleX * (float)win->r.w), (u32)(monitor.scaleX * (float)win->r.h)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1637,6 +1636,16 @@ RGFW_window* RGFW_root = NULL;
|
||||||
#define RGFW_HOLD_MOUSE (1L<<2) /*!< hold the moues still */
|
#define RGFW_HOLD_MOUSE (1L<<2) /*!< hold the moues still */
|
||||||
#define RGFW_MOUSE_LEFT (1L<<3) /* if mouse left the window */
|
#define RGFW_MOUSE_LEFT (1L<<3) /* if mouse left the window */
|
||||||
|
|
||||||
|
#ifdef RGFW_MACOS
|
||||||
|
RGFWDEF void RGFW_window_cocoaSetLayer(RGFW_window* win, void* layer);
|
||||||
|
RGFWDEF void* RGFW_cocoaGetLayer(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char* RGFW_className = NULL;
|
||||||
|
void RGFW_setClassName(char* name) {
|
||||||
|
RGFW_className = name;
|
||||||
|
}
|
||||||
|
|
||||||
void RGFW_clipboardFree(char* str) { RGFW_FREE(str); }
|
void RGFW_clipboardFree(char* str) { RGFW_FREE(str); }
|
||||||
|
|
||||||
RGFW_keyState RGFW_mouseButtons[5] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} };
|
RGFW_keyState RGFW_mouseButtons[5] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} };
|
||||||
|
|
@ -2073,6 +2082,8 @@ void RGFW_updateLockState(RGFW_window* win, b8 capital, b8 numlock) {
|
||||||
|
|
||||||
#ifdef RGFW_WINDOWS
|
#ifdef RGFW_WINDOWS
|
||||||
win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.hdc);
|
win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.hdc);
|
||||||
|
#elif defined(RGFW_MACOS)
|
||||||
|
win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType)0);
|
||||||
#else
|
#else
|
||||||
win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.display);
|
win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.display);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2104,8 +2115,15 @@ void RGFW_updateLockState(RGFW_window* win, b8 capital, b8 numlock) {
|
||||||
EGLint numConfigs;
|
EGLint numConfigs;
|
||||||
eglChooseConfig(win->src.EGL_display, egl_config, &config, 1, &numConfigs);
|
eglChooseConfig(win->src.EGL_display, egl_config, &config, 1, &numConfigs);
|
||||||
|
|
||||||
|
#if defined(RGFW_MACOS)
|
||||||
win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL);
|
void* layer = RGFW_cocoaGetLayer();
|
||||||
|
|
||||||
|
RGFW_window_cocoaSetLayer(win, layer);
|
||||||
|
|
||||||
|
win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) layer, NULL);
|
||||||
|
#else
|
||||||
|
win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
EGLint attribs[] = {
|
EGLint attribs[] = {
|
||||||
EGL_CONTEXT_CLIENT_VERSION,
|
EGL_CONTEXT_CLIENT_VERSION,
|
||||||
|
|
@ -2322,7 +2340,7 @@ Start of Linux / Unix defines
|
||||||
|
|
||||||
u8 RGFW_mouseIconSrc[] = { XC_arrow, XC_left_ptr, XC_xterm, XC_crosshair, XC_hand2, XC_sb_h_double_arrow, XC_sb_v_double_arrow, XC_bottom_left_corner, XC_bottom_right_corner, XC_fleur, XC_X_cursor};
|
u8 RGFW_mouseIconSrc[] = { XC_arrow, XC_left_ptr, XC_xterm, XC_crosshair, XC_hand2, XC_sb_h_double_arrow, XC_sb_v_double_arrow, XC_bottom_left_corner, XC_bottom_right_corner, XC_fleur, XC_X_cursor};
|
||||||
/*atoms needed for drag and drop*/
|
/*atoms needed for drag and drop*/
|
||||||
Atom XdndAware, XdndTypeList, XdndSelection, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished, XdndActionCopy, XdndActionMove, XdndActionLink, XdndActionAsk, XdndActionPrivate;
|
Atom XdndAware, XdndTypeList, XdndSelection, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished, XdndActionCopy, XtextPlain, XtextUriList;
|
||||||
|
|
||||||
Atom wm_delete_window = 0;
|
Atom wm_delete_window = 0;
|
||||||
|
|
||||||
|
|
@ -2563,9 +2581,13 @@ Start of Linux / Unix defines
|
||||||
// In your .desktop app, if you set the property
|
// In your .desktop app, if you set the property
|
||||||
// StartupWMClass=RGFW that will assoicate the launcher icon
|
// StartupWMClass=RGFW that will assoicate the launcher icon
|
||||||
// with your application - robrohan
|
// with your application - robrohan
|
||||||
|
|
||||||
|
if (RGFW_className == NULL)
|
||||||
|
RGFW_className = (char*)name;
|
||||||
|
|
||||||
XClassHint *hint = XAllocClassHint();
|
XClassHint *hint = XAllocClassHint();
|
||||||
assert(hint != NULL);
|
assert(hint != NULL);
|
||||||
hint->res_class = (char*)"RGFW";
|
hint->res_class = (char*)RGFW_className;
|
||||||
hint->res_name = (char*)name; // just use the window name as the app name
|
hint->res_name = (char*)name; // just use the window name as the app name
|
||||||
XSetClassHint((Display*) win->src.display, win->src.window, hint);
|
XSetClassHint((Display*) win->src.display, win->src.window, hint);
|
||||||
XFree(hint);
|
XFree(hint);
|
||||||
|
|
@ -2609,6 +2631,11 @@ Start of Linux / Unix defines
|
||||||
RGFW_window_scaleToMonitor(win);
|
RGFW_window_scaleToMonitor(win);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (args & RGFW_CENTER) {
|
||||||
|
RGFW_area screenR = RGFW_getScreenSize();
|
||||||
|
RGFW_window_move(win, RGFW_POINT((screenR.w - win->r.w) / 2, (screenR.h - win->r.h) / 2));
|
||||||
|
}
|
||||||
|
|
||||||
if (args & RGFW_NO_RESIZE) { /* make it so the user can't resize the window*/
|
if (args & RGFW_NO_RESIZE) { /* make it so the user can't resize the window*/
|
||||||
XSizeHints* sh = XAllocSizeHints();
|
XSizeHints* sh = XAllocSizeHints();
|
||||||
sh->flags = (1L << 4) | (1L << 5);
|
sh->flags = (1L << 4) | (1L << 5);
|
||||||
|
|
@ -2646,7 +2673,6 @@ Start of Linux / Unix defines
|
||||||
if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */
|
if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */
|
||||||
win->_winArgs |= RGFW_ALLOW_DND;
|
win->_winArgs |= RGFW_ALLOW_DND;
|
||||||
|
|
||||||
XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False);
|
|
||||||
XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False);
|
XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False);
|
||||||
XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False);
|
XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False);
|
||||||
|
|
||||||
|
|
@ -2660,15 +2686,16 @@ Start of Linux / Unix defines
|
||||||
|
|
||||||
/* actions */
|
/* actions */
|
||||||
XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False);
|
XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False);
|
||||||
XdndActionMove = XInternAtom((Display*) win->src.display, "XdndActionMove", False);
|
|
||||||
XdndActionLink = XInternAtom((Display*) win->src.display, "XdndActionLink", False);
|
XtextUriList = XInternAtom((Display*) win->src.display, "text/uri-list", False);
|
||||||
XdndActionAsk = XInternAtom((Display*) win->src.display, "XdndActionAsk", False);
|
XtextPlain = XInternAtom((Display*) win->src.display, "text/plain", False);
|
||||||
XdndActionPrivate = XInternAtom((Display*) win->src.display, "XdndActionPrivate", False);
|
|
||||||
const Atom version = 5;
|
XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False);
|
||||||
|
const u8 version = 5;
|
||||||
|
|
||||||
XChangeProperty((Display*) win->src.display, (Window) win->src.window,
|
XChangeProperty((Display*) win->src.display, (Window) win->src.window,
|
||||||
XdndAware, 4, 32,
|
XdndAware, 4, 32,
|
||||||
PropModeReplace, (u8*) &version, 1); /*!< turns on drag and drop */
|
PropModeReplace, &version, 1); /*!< turns on drag and drop */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RGFW_EGL
|
#ifdef RGFW_EGL
|
||||||
|
|
@ -2716,17 +2743,16 @@ Start of Linux / Unix defines
|
||||||
return RGFWMouse;
|
return RGFWMouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct XDND {
|
|
||||||
long source, version;
|
|
||||||
i32 format;
|
|
||||||
} XDND; /*!< data structure for xdnd events */
|
|
||||||
XDND xdnd;
|
|
||||||
|
|
||||||
int xAxis = 0, yAxis = 0;
|
int xAxis = 0, yAxis = 0;
|
||||||
|
|
||||||
RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) {
|
RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) {
|
||||||
assert(win != NULL);
|
assert(win != NULL);
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
long source, version;
|
||||||
|
i32 format;
|
||||||
|
} xdnd;
|
||||||
|
|
||||||
if (win->event.type == 0)
|
if (win->event.type == 0)
|
||||||
RGFW_resetKey();
|
RGFW_resetKey();
|
||||||
|
|
||||||
|
|
@ -2893,13 +2919,16 @@ Start of Linux / Unix defines
|
||||||
|
|
||||||
win->event.droppedFilesCount = 0;
|
win->event.droppedFilesCount = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
much of this event (drag and drop code) is source from glfw
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((win->_winArgs & RGFW_ALLOW_DND) == 0)
|
if ((win->_winArgs & RGFW_ALLOW_DND) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
XEvent reply = { ClientMessage };
|
||||||
|
reply.xclient.window = xdnd.source;
|
||||||
|
reply.xclient.format = 32;
|
||||||
|
reply.xclient.data.l[0] = (long) win->src.window;
|
||||||
|
reply.xclient.data.l[1] = 0;
|
||||||
|
reply.xclient.data.l[2] = None;
|
||||||
|
|
||||||
if (E.xclient.message_type == XdndEnter) {
|
if (E.xclient.message_type == XdndEnter) {
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
Atom* formats;
|
Atom* formats;
|
||||||
|
|
@ -2944,28 +2973,11 @@ Start of Linux / Unix defines
|
||||||
formats = real_formats;
|
formats = real_formats;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 i;
|
unsigned long i;
|
||||||
for (i = 0; i < (u32)count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
char* name = XGetAtomName((Display*) win->src.display, formats[i]);
|
if (formats[i] == XtextUriList || formats[i] == XtextPlain) {
|
||||||
|
xdnd.format = formats[i];
|
||||||
char* links[2] = { (char*) (const char*) "text/uri-list", (char*) (const char*) "text/plain" };
|
break;
|
||||||
for (; 1; name++) {
|
|
||||||
u32 j;
|
|
||||||
for (j = 0; j < 2; j++) {
|
|
||||||
if (*links[j] != *name) {
|
|
||||||
links[j] = (char*) (const char*) "\1";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*links[j] == '\0' && *name == '\0')
|
|
||||||
xdnd.format = formats[i];
|
|
||||||
|
|
||||||
if (*links[j] != '\0' && *links[j] != '\1')
|
|
||||||
links[j]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*name == '\0')
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2994,13 +3006,8 @@ Start of Linux / Unix defines
|
||||||
win->event.point.x = xpos;
|
win->event.point.x = xpos;
|
||||||
win->event.point.y = ypos;
|
win->event.point.y = ypos;
|
||||||
|
|
||||||
XEvent reply = { ClientMessage };
|
|
||||||
reply.xclient.window = xdnd.source;
|
reply.xclient.window = xdnd.source;
|
||||||
reply.xclient.message_type = XdndStatus;
|
reply.xclient.message_type = XdndStatus;
|
||||||
reply.xclient.format = 32;
|
|
||||||
reply.xclient.data.l[0] = (long) win->src.window;
|
|
||||||
reply.xclient.data.l[2] = 0;
|
|
||||||
reply.xclient.data.l[3] = 0;
|
|
||||||
|
|
||||||
if (xdnd.format) {
|
if (xdnd.format) {
|
||||||
reply.xclient.data.l[1] = 1;
|
reply.xclient.data.l[1] = 1;
|
||||||
|
|
@ -3035,12 +3042,6 @@ Start of Linux / Unix defines
|
||||||
time);
|
time);
|
||||||
} else if (xdnd.version >= 2) {
|
} else if (xdnd.version >= 2) {
|
||||||
XEvent reply = { ClientMessage };
|
XEvent reply = { ClientMessage };
|
||||||
reply.xclient.window = xdnd.source;
|
|
||||||
reply.xclient.message_type = XdndFinished;
|
|
||||||
reply.xclient.format = 32;
|
|
||||||
reply.xclient.data.l[0] = (long) win->src.window;
|
|
||||||
reply.xclient.data.l[1] = 0;
|
|
||||||
reply.xclient.data.l[2] = None;
|
|
||||||
|
|
||||||
XSendEvent((Display*) win->src.display, xdnd.source,
|
XSendEvent((Display*) win->src.display, xdnd.source,
|
||||||
False, NoEventMask, &reply);
|
False, NoEventMask, &reply);
|
||||||
|
|
@ -3125,11 +3126,7 @@ Start of Linux / Unix defines
|
||||||
XFree(data);
|
XFree(data);
|
||||||
|
|
||||||
if (xdnd.version >= 2) {
|
if (xdnd.version >= 2) {
|
||||||
XEvent reply = { ClientMessage };
|
|
||||||
reply.xclient.window = xdnd.source;
|
|
||||||
reply.xclient.message_type = XdndFinished;
|
reply.xclient.message_type = XdndFinished;
|
||||||
reply.xclient.format = 32;
|
|
||||||
reply.xclient.data.l[0] = (long) win->src.window;
|
|
||||||
reply.xclient.data.l[1] = result;
|
reply.xclient.data.l[1] = result;
|
||||||
reply.xclient.data.l[2] = XdndActionCopy;
|
reply.xclient.data.l[2] = XdndActionCopy;
|
||||||
|
|
||||||
|
|
@ -3480,7 +3477,7 @@ Start of Linux / Unix defines
|
||||||
*size = sizeN;
|
*size = sizeN;
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
almost all of this function is sourced from GLFW
|
almost all of this function is sourced from GLFW
|
||||||
|
|
@ -3520,9 +3517,6 @@ Start of Linux / Unix defines
|
||||||
XEvent reply = { SelectionNotify };
|
XEvent reply = { SelectionNotify };
|
||||||
reply.xselection.property = 0;
|
reply.xselection.property = 0;
|
||||||
|
|
||||||
const Atom formats[] = { UTF8_STRING, XA_STRING };
|
|
||||||
const i32 formatCount = sizeof(formats) / sizeof(formats[0]);
|
|
||||||
|
|
||||||
if (request->target == TARGETS) {
|
if (request->target == TARGETS) {
|
||||||
const Atom targets[] = { TARGETS,
|
const Atom targets[] = { TARGETS,
|
||||||
MULTIPLE,
|
MULTIPLE,
|
||||||
|
|
@ -3552,15 +3546,7 @@ Start of Linux / Unix defines
|
||||||
|
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
for (i = 0; i < (u32)count; i += 2) {
|
for (i = 0; i < (u32)count; i += 2) {
|
||||||
i32 j;
|
if (targets[i] == UTF8_STRING || targets[i] == XA_STRING) {
|
||||||
|
|
||||||
for (j = 0; j < formatCount; j++) {
|
|
||||||
if (targets[i] == formats[j])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j < formatCount)
|
|
||||||
{
|
|
||||||
XChangeProperty((Display*) RGFW_root->src.display,
|
XChangeProperty((Display*) RGFW_root->src.display,
|
||||||
request->requestor,
|
request->requestor,
|
||||||
targets[i + 1],
|
targets[i + 1],
|
||||||
|
|
@ -3727,32 +3713,54 @@ Start of Linux / Unix defines
|
||||||
RGFW_monitor monitor;
|
RGFW_monitor monitor;
|
||||||
|
|
||||||
Display* display = XOpenDisplay(NULL);
|
Display* display = XOpenDisplay(NULL);
|
||||||
|
|
||||||
|
RGFW_area size = RGFW_getScreenSize();
|
||||||
|
|
||||||
monitor.rect = RGFW_RECT(0, 0, DisplayWidth(display, screen), DisplayHeight(display, screen));
|
monitor.rect = RGFW_RECT(0, 0, size.w, size.h);
|
||||||
monitor.physW = (monitor.rect.w * 25.4f / 96.f);
|
monitor.physW = DisplayWidthMM(display, screen);
|
||||||
monitor.physH = (monitor.rect.h * 25.4f / 96.f);
|
monitor.physH = DisplayHeightMM(display, screen);
|
||||||
|
|
||||||
strncpy(monitor.name, DisplayString(display), 128);
|
|
||||||
|
|
||||||
XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY);
|
XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY);
|
||||||
|
|
||||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(display, RootWindow(display, screen));
|
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(display, RootWindow(display, screen));
|
||||||
|
|
||||||
XRRCrtcInfo* ci = NULL;
|
XRRCrtcInfo* ci = NULL;
|
||||||
int crtc = 0;
|
int crtc = screen;
|
||||||
|
|
||||||
if (sr->ncrtc > crtc) {
|
if (sr->ncrtc > crtc) {
|
||||||
ci = XRRGetCrtcInfo(display, sr, sr->crtcs[crtc]);
|
ci = XRRGetCrtcInfo(display, sr, sr->crtcs[crtc]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ci == NULL) {
|
if (ci == NULL) {
|
||||||
|
float dpi_width = round((double)monitor.rect.w/(((double)monitor.physW)/25.4));
|
||||||
|
float dpi_height = round((double)monitor.rect.h/(((double)monitor.physH)/25.4));
|
||||||
|
|
||||||
|
monitor.scaleX = (float) (dpi_width) / (float) 96;
|
||||||
|
monitor.scaleY = (float) (dpi_height) / (float) 96;
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
XCloseDisplay(display);
|
XCloseDisplay(display);
|
||||||
return monitor;
|
return monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XRROutputInfo* info = XRRGetOutputInfo (display, sr, sr->outputs[screen]);
|
||||||
|
monitor.physW = info->mm_width;
|
||||||
|
monitor.physH = info->mm_height;
|
||||||
|
|
||||||
monitor.rect.x = ci->x;
|
monitor.rect.x = ci->x;
|
||||||
monitor.rect.y = ci->y;
|
monitor.rect.y = ci->y;
|
||||||
|
monitor.rect.w = ci->width;
|
||||||
|
monitor.rect.h = ci->height;
|
||||||
|
|
||||||
|
float dpi_width = round((double)monitor.rect.w/(((double)monitor.physW)/25.4));
|
||||||
|
float dpi_height = round((double)monitor.rect.h/(((double)monitor.physH)/25.4));
|
||||||
|
|
||||||
|
monitor.scaleX = (float) (dpi_width) / (float) 96;
|
||||||
|
monitor.scaleY = (float) (dpi_height) / (float) 96;
|
||||||
|
|
||||||
|
if (monitor.scaleX > 1 && monitor.scaleX < 1.1)
|
||||||
|
monitor.scaleX = 1;
|
||||||
|
|
||||||
|
if (monitor.scaleY > 1 && monitor.scaleY < 1.1)
|
||||||
|
monitor.scaleY = 1;
|
||||||
|
|
||||||
XRRFreeCrtcInfo(ci);
|
XRRFreeCrtcInfo(ci);
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
|
|
@ -4150,9 +4158,6 @@ RGFW_Event RGFW_eventPipe_pop(RGFW_window* win) {
|
||||||
|
|
||||||
if (win->src.eventLen >= 0)
|
if (win->src.eventLen >= 0)
|
||||||
ev = win->src.events[win->src.eventLen];
|
ev = win->src.events[win->src.eventLen];
|
||||||
else {
|
|
||||||
printf("H2\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ev;
|
return ev;
|
||||||
}
|
}
|
||||||
|
|
@ -4675,6 +4680,10 @@ static const struct wl_callback_listener wl_surface_frame_listener = {
|
||||||
decoration_manager, win->src.xdg_toplevel);
|
decoration_manager, win->src.xdg_toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args & RGFW_CENTER) {
|
||||||
|
RGFW_area screenR = RGFW_getScreenSize();
|
||||||
|
RGFW_window_move(win, RGFW_POINT((screenR.w - win->r.w) / 2, (screenR.h - win->r.h) / 2));
|
||||||
|
}
|
||||||
|
|
||||||
if (args & RGFW_OPENGL_SOFTWARE)
|
if (args & RGFW_OPENGL_SOFTWARE)
|
||||||
setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
|
setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
|
||||||
|
|
@ -5007,6 +5016,10 @@ static const struct wl_callback_listener wl_surface_frame_listener = {
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include <shellscalingapi.h>
|
#include <shellscalingapi.h>
|
||||||
|
|
||||||
|
#include <winuser.h>
|
||||||
|
|
||||||
|
__declspec(dllimport) int __stdcall WideCharToMultiByte( UINT CodePage, DWORD dwFlags, const WCHAR* lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar);
|
||||||
|
|
||||||
#ifndef RGFW_NO_XINPUT
|
#ifndef RGFW_NO_XINPUT
|
||||||
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
|
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
|
||||||
PFN_XInputGetState XInputGetStateSRC = NULL;
|
PFN_XInputGetState XInputGetStateSRC = NULL;
|
||||||
|
|
@ -5224,14 +5237,15 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
}
|
}
|
||||||
|
|
||||||
void RGFW_releaseCursor(RGFW_window* win) {
|
void RGFW_releaseCursor(RGFW_window* win) {
|
||||||
|
RGFW_UNUSED(win);
|
||||||
ClipCursor(NULL);
|
ClipCursor(NULL);
|
||||||
const RAWINPUTDEVICE id = { 0x01, 0x02, RIDEV_REMOVE, NULL };
|
const RAWINPUTDEVICE id = { 0x01, 0x02, RIDEV_REMOVE, NULL };
|
||||||
RegisterRawInputDevices(&id, 1, sizeof(id));
|
RegisterRawInputDevices(&id, 1, sizeof(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RGFW_captureCursor(RGFW_window* win, RGFW_rect rect) {
|
void RGFW_captureCursor(RGFW_window* win, RGFW_rect rect) {
|
||||||
RGFW_UNUSED(win)
|
RGFW_UNUSED(win); RGFW_UNUSED(rect);
|
||||||
|
|
||||||
RECT clipRect;
|
RECT clipRect;
|
||||||
GetClientRect(win->src.window, &clipRect);
|
GetClientRect(win->src.window, &clipRect);
|
||||||
ClientToScreen(win->src.window, (POINT*) &clipRect.left);
|
ClientToScreen(win->src.window, (POINT*) &clipRect.left);
|
||||||
|
|
@ -5252,6 +5266,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
if (RGFW_Shcore_dll == NULL) {
|
if (RGFW_Shcore_dll == NULL) {
|
||||||
RGFW_Shcore_dll = LoadLibraryA("shcore.dll");
|
RGFW_Shcore_dll = LoadLibraryA("shcore.dll");
|
||||||
GetDpiForMonitorSRC = (PFN_GetDpiForMonitor)(void*)GetProcAddress(RGFW_Shcore_dll, "GetDpiForMonitor");
|
GetDpiForMonitorSRC = (PFN_GetDpiForMonitor)(void*)GetProcAddress(RGFW_Shcore_dll, "GetDpiForMonitor");
|
||||||
|
SetProcessDPIAware();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -5286,7 +5301,10 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
WNDCLASSA Class = { };
|
WNDCLASSA Class = { };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Class.lpszClassName = name;
|
if (RGFW_className == NULL)
|
||||||
|
RGFW_className = (char*)name;
|
||||||
|
|
||||||
|
Class.lpszClassName = RGFW_className;
|
||||||
Class.hInstance = inh;
|
Class.hInstance = inh;
|
||||||
Class.hCursor = LoadCursor(NULL, IDC_ARROW);
|
Class.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
Class.lpfnWndProc = WndProc;
|
Class.lpfnWndProc = WndProc;
|
||||||
|
|
@ -5499,6 +5517,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
if (args & RGFW_SCALE_TO_MONITOR)
|
if (args & RGFW_SCALE_TO_MONITOR)
|
||||||
RGFW_window_scaleToMonitor(win);
|
RGFW_window_scaleToMonitor(win);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (args & RGFW_CENTER) {
|
||||||
|
RGFW_area screenR = RGFW_getScreenSize();
|
||||||
|
RGFW_window_move(win, RGFW_POINT((screenR.w - win->r.w) / 2, (screenR.h - win->r.h) / 2));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef RGFW_EGL
|
#ifdef RGFW_EGL
|
||||||
if ((args & RGFW_NO_INIT_API) == 0)
|
if ((args & RGFW_NO_INIT_API) == 0)
|
||||||
|
|
@ -6100,7 +6123,8 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
|
|
||||||
if (GetDpiForMonitor != NULL) {
|
if (GetDpiForMonitor != NULL) {
|
||||||
u32 x, y;
|
u32 x, y;
|
||||||
GetDpiForMonitor(src, MDT_ANGULAR_DPI, &x, &y);
|
GetDpiForMonitor(src, MDT_EFFECTIVE_DPI, &x, &y);
|
||||||
|
|
||||||
monitor.scaleX = (float) (x) / (float) USER_DEFAULT_SCREEN_DPI;
|
monitor.scaleX = (float) (x) / (float) USER_DEFAULT_SCREEN_DPI;
|
||||||
monitor.scaleY = (float) (y) / (float) USER_DEFAULT_SCREEN_DPI;
|
monitor.scaleY = (float) (y) / (float) USER_DEFAULT_SCREEN_DPI;
|
||||||
}
|
}
|
||||||
|
|
@ -6115,7 +6139,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
/* Calculate physical height in inches */
|
/* Calculate physical height in inches */
|
||||||
monitor.physW = GetSystemMetrics(SM_CYSCREEN) / (float) ppiX;
|
monitor.physW = GetSystemMetrics(SM_CYSCREEN) / (float) ppiX;
|
||||||
monitor.physH = GetSystemMetrics(SM_CXSCREEN) / (float) ppiY;
|
monitor.physH = GetSystemMetrics(SM_CXSCREEN) / (float) ppiY;
|
||||||
|
|
||||||
return monitor;
|
return monitor;
|
||||||
}
|
}
|
||||||
#endif /* RGFW_NO_MONITOR */
|
#endif /* RGFW_NO_MONITOR */
|
||||||
|
|
@ -6150,7 +6174,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
RGFW_mInfo info;
|
RGFW_mInfo info;
|
||||||
info.iIndex = 0;
|
info.iIndex = 0;
|
||||||
while (EnumDisplayMonitors(NULL, NULL, GetMonitorHandle, (LPARAM) &info));
|
while (EnumDisplayMonitors(NULL, NULL, GetMonitorHandle, (LPARAM) &info));
|
||||||
|
|
||||||
return RGFW_monitors;
|
return RGFW_monitors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7102,7 +7126,6 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
id fileURL = objc_msgSend_arr(fileURLs, sel_registerName("objectAtIndex:"), i);
|
id fileURL = objc_msgSend_arr(fileURLs, sel_registerName("objectAtIndex:"), i);
|
||||||
const char *filePath = ((const char* (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("UTF8String"));
|
const char *filePath = ((const char* (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("UTF8String"));
|
||||||
// printf("File: %s\n", filePath);
|
|
||||||
strncpy(win->event.droppedFiles[i], filePath, RGFW_MAX_PATH);
|
strncpy(win->event.droppedFiles[i], filePath, RGFW_MAX_PATH);
|
||||||
win->event.droppedFiles[i][RGFW_MAX_PATH - 1] = '\0';
|
win->event.droppedFiles[i][RGFW_MAX_PATH - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
@ -7206,6 +7229,16 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RGFW_window_cocoaSetLayer(RGFW_window* win, void* layer) {
|
||||||
|
objc_msgSend_void_id(win->src.view, sel_registerName("setLayer"), layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* RGFW_cocoaGetLayer(void) {
|
||||||
|
return objc_msgSend_class(objc_getClass("CAMetalLayer"), sel_registerName("layer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NSPasteboardType const NSPasteboardTypeURL = "public.url";
|
NSPasteboardType const NSPasteboardTypeURL = "public.url";
|
||||||
NSPasteboardType const NSPasteboardTypeFileURL = "public.file-url";
|
NSPasteboardType const NSPasteboardTypeFileURL = "public.file-url";
|
||||||
|
|
||||||
|
|
@ -7261,6 +7294,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
NSString* str = NSString_stringWithUTF8String(name);
|
NSString* str = NSString_stringWithUTF8String(name);
|
||||||
objc_msgSend_void_id(win->src.window, sel_registerName("setTitle:"), str);
|
objc_msgSend_void_id(win->src.window, sel_registerName("setTitle:"), str);
|
||||||
|
|
||||||
|
#ifdef RGFW_EGL
|
||||||
|
if ((args & RGFW_NO_INIT_API) == 0)
|
||||||
|
RGFW_createOpenGLContext(win);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RGFW_OPENGL
|
#ifdef RGFW_OPENGL
|
||||||
if ((args & RGFW_NO_INIT_API) == 0) {
|
if ((args & RGFW_NO_INIT_API) == 0) {
|
||||||
void* attrs = RGFW_initFormatAttribs(args & RGFW_OPENGL_SOFTWARE);
|
void* attrs = RGFW_initFormatAttribs(args & RGFW_OPENGL_SOFTWARE);
|
||||||
|
|
@ -7327,6 +7365,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
RGFW_window_scaleToMonitor(win);
|
RGFW_window_scaleToMonitor(win);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (args & RGFW_CENTER) {
|
||||||
|
RGFW_area screenR = RGFW_getScreenSize();
|
||||||
|
RGFW_window_move(win, RGFW_POINT((screenR.w - win->r.w) / 2, (screenR.h - win->r.h) / 2));
|
||||||
|
}
|
||||||
|
|
||||||
if (args & RGFW_HIDE_MOUSE)
|
if (args & RGFW_HIDE_MOUSE)
|
||||||
RGFW_window_showMouse(win, 0);
|
RGFW_window_showMouse(win, 0);
|
||||||
|
|
||||||
|
|
@ -7933,6 +7976,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
}
|
}
|
||||||
|
|
||||||
void RGFW_releaseCursor(RGFW_window* win) {
|
void RGFW_releaseCursor(RGFW_window* win) {
|
||||||
|
RGFW_UNUSED(win);
|
||||||
CGAssociateMouseAndMouseCursorPosition(1);
|
CGAssociateMouseAndMouseCursorPosition(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7992,13 +8036,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
monitor.rect = RGFW_RECT((int) bounds.origin.x, (int) bounds.origin.y, (int) bounds.size.width, (int) bounds.size.height);
|
monitor.rect = RGFW_RECT((int) bounds.origin.x, (int) bounds.origin.y, (int) bounds.size.width, (int) bounds.size.height);
|
||||||
|
|
||||||
CGSize screenSizeMM = CGDisplayScreenSize(display);
|
CGSize screenSizeMM = CGDisplayScreenSize(display);
|
||||||
monitor.physW = screenSizeMM.width / 25.4;
|
monitor.physW = screenSizeMM.width;
|
||||||
monitor.physH = screenSizeMM.height / 25.4;
|
monitor.physH = screenSizeMM.height;
|
||||||
|
|
||||||
monitor.scaleX = (monitor.rect.w / (screenSizeMM.width)) / 2.6;
|
monitor.scaleX = ((monitor.rect.w / (screenSizeMM.width / 25.4)) / 96) + 0.25;
|
||||||
monitor.scaleY = (monitor.rect.h / (screenSizeMM.height)) / 2.6;
|
monitor.scaleY = ((monitor.rect.h / (screenSizeMM.height / 25.4)) / 96) + 0.25;
|
||||||
|
|
||||||
snprintf(monitor.name, 128, "%i %i %i", CGDisplayModelNumber(display), CGDisplayVendorNumber(display), CGDisplaySerialNumber(display));
|
|
||||||
|
|
||||||
return monitor;
|
return monitor;
|
||||||
}
|
}
|
||||||
|
|
@ -8088,6 +8130,8 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
|
||||||
#if defined(RGFW_OPENGL)
|
#if defined(RGFW_OPENGL)
|
||||||
|
|
||||||
NSOpenGLContext_setValues(win->src.ctx, &swapInterval, 222);
|
NSOpenGLContext_setValues(win->src.ctx, &swapInterval, 222);
|
||||||
|
#else
|
||||||
|
RGFW_UNUSED(swapInterval);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -8530,7 +8574,7 @@ RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) {
|
||||||
emscripten_webgl_make_context_current(win->src.ctx);
|
emscripten_webgl_make_context_current(win->src.ctx);
|
||||||
|
|
||||||
#ifdef LEGACY_GL_EMULATION
|
#ifdef LEGACY_GL_EMULATION
|
||||||
EM_ASM("Module.useWebGL = true; GLImmediate.init();");
|
EM_ASM("Module.useWebGL = true; GLImmediate.init();");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
emscripten_set_canvas_element_size("#canvas", rect.w, rect.h);
|
emscripten_set_canvas_element_size("#canvas", rect.w, rect.h);
|
||||||
|
|
@ -8873,11 +8917,12 @@ u64 RGFW_getTime(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RGFW_releaseCursor(RGFW_window* win) {
|
void RGFW_releaseCursor(RGFW_window* win) {
|
||||||
|
RGFW_UNUSED(win);
|
||||||
emscripten_exit_pointerlock();
|
emscripten_exit_pointerlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RGFW_captureCursor(RGFW_window* win, RGFW_rect r) {
|
void RGFW_captureCursor(RGFW_window* win, RGFW_rect r) {
|
||||||
RGFW_UNUSED(win)
|
RGFW_UNUSED(win); RGFW_UNUSED(r);
|
||||||
|
|
||||||
emscripten_request_pointerlock("#canvas", 1);
|
emscripten_request_pointerlock("#canvas", 1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
src/external/glfw/src/mappings.h
vendored
1
src/external/glfw/src/mappings.h
vendored
|
|
@ -996,6 +996,7 @@ const char* _glfwDefaultMappings[] =
|
||||||
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,",
|
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,",
|
||||||
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
|
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
|
||||||
"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
|
"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
|
||||||
|
"03000000af1e00002400000010010000,Clockwork Pi DevTerm,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b9,x:b3,y:b0,platform:Linux,",
|
||||||
#endif // GLFW_BUILD_LINUX_JOYSTICK
|
#endif // GLFW_BUILD_LINUX_JOYSTICK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
3053
src/external/nanosvg.h
vendored
3053
src/external/nanosvg.h
vendored
File diff suppressed because it is too large
Load Diff
1458
src/external/nanosvgrast.h
vendored
1458
src/external/nanosvgrast.h
vendored
File diff suppressed because it is too large
Load Diff
2
src/external/par_shapes.h
vendored
2
src/external/par_shapes.h
vendored
|
|
@ -1130,7 +1130,7 @@ static par_shapes__rule* par_shapes__pick_rule(const char* name,
|
||||||
total += rule->weight;
|
total += rule->weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float r = (float) rand() / RAND_MAX;
|
float r = (float) rand() / (float) RAND_MAX;
|
||||||
float t = 0;
|
float t = 0;
|
||||||
for (int i = 0; i < nrules; i++) {
|
for (int i = 0; i < nrules; i++) {
|
||||||
rule = rules + i;
|
rule = rules + i;
|
||||||
|
|
|
||||||
13
src/external/rl_gputex.h
vendored
13
src/external/rl_gputex.h
vendored
|
|
@ -185,6 +185,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
||||||
if (header->ddspf.flags == 0x40) // No alpha channel
|
if (header->ddspf.flags == 0x40) // No alpha channel
|
||||||
{
|
{
|
||||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||||
|
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||||
image_data = RL_MALLOC(data_size);
|
image_data = RL_MALLOC(data_size);
|
||||||
|
|
||||||
memcpy(image_data, file_data_ptr, data_size);
|
memcpy(image_data, file_data_ptr, data_size);
|
||||||
|
|
@ -196,6 +197,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
||||||
if (header->ddspf.a_bit_mask == 0x8000) // 1bit alpha
|
if (header->ddspf.a_bit_mask == 0x8000) // 1bit alpha
|
||||||
{
|
{
|
||||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||||
|
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||||
image_data = RL_MALLOC(data_size);
|
image_data = RL_MALLOC(data_size);
|
||||||
|
|
||||||
memcpy(image_data, file_data_ptr, data_size);
|
memcpy(image_data, file_data_ptr, data_size);
|
||||||
|
|
@ -215,6 +217,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
||||||
else if (header->ddspf.a_bit_mask == 0xf000) // 4bit alpha
|
else if (header->ddspf.a_bit_mask == 0xf000) // 4bit alpha
|
||||||
{
|
{
|
||||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||||
|
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||||
image_data = RL_MALLOC(data_size);
|
image_data = RL_MALLOC(data_size);
|
||||||
|
|
||||||
memcpy(image_data, file_data_ptr, data_size);
|
memcpy(image_data, file_data_ptr, data_size);
|
||||||
|
|
@ -236,6 +239,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
||||||
else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed
|
else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed
|
||||||
{
|
{
|
||||||
int data_size = image_pixel_size*3*sizeof(unsigned char);
|
int data_size = image_pixel_size*3*sizeof(unsigned char);
|
||||||
|
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||||
image_data = RL_MALLOC(data_size);
|
image_data = RL_MALLOC(data_size);
|
||||||
|
|
||||||
memcpy(image_data, file_data_ptr, data_size);
|
memcpy(image_data, file_data_ptr, data_size);
|
||||||
|
|
@ -245,6 +249,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
||||||
else if ((header->ddspf.flags == 0x41) && (header->ddspf.rgb_bit_count == 32)) // DDS_RGBA, no compressed
|
else if ((header->ddspf.flags == 0x41) && (header->ddspf.rgb_bit_count == 32)) // DDS_RGBA, no compressed
|
||||||
{
|
{
|
||||||
int data_size = image_pixel_size*4*sizeof(unsigned char);
|
int data_size = image_pixel_size*4*sizeof(unsigned char);
|
||||||
|
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||||
image_data = RL_MALLOC(data_size);
|
image_data = RL_MALLOC(data_size);
|
||||||
|
|
||||||
memcpy(image_data, file_data_ptr, data_size);
|
memcpy(image_data, file_data_ptr, data_size);
|
||||||
|
|
@ -265,9 +270,11 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
||||||
}
|
}
|
||||||
else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed
|
else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed
|
||||||
{
|
{
|
||||||
// NOTE: This forces only 1 mipmap to be loaded which is not really correct but it works
|
int data_size = 0;
|
||||||
int data_size = (header->pitch_or_linear_size < file_size - 0x80) ? header->pitch_or_linear_size : file_size - 0x80;
|
|
||||||
*mips = 1;
|
// Calculate data size, including all mipmaps
|
||||||
|
if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size + header->pitch_or_linear_size / 3;
|
||||||
|
else data_size = header->pitch_or_linear_size;
|
||||||
|
|
||||||
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
|
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
|
||||||
|
|
||||||
|
|
|
||||||
1657
src/external/stb_image_resize2.h
vendored
1657
src/external/stb_image_resize2.h
vendored
File diff suppressed because it is too large
Load Diff
|
|
@ -74,7 +74,7 @@ typedef struct {
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
extern CoreData CORE; // Global CORE state context
|
extern CoreData CORE; // Global CORE state context
|
||||||
|
extern bool isGpuReady; // Flag to note GPU has been initialized successfully
|
||||||
static PlatformData platform = { 0 }; // Platform specific data
|
static PlatformData platform = { 0 }; // Platform specific data
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -694,16 +694,16 @@ void PollInputEvents(void)
|
||||||
// Process this event
|
// Process this event
|
||||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||||
|
|
||||||
// NOTE: Never close window, native activity is controlled by the system!
|
// NOTE: Allow closing the window in case a configuration change happened.
|
||||||
|
// The android_main function should be allowed to return to its caller in order for the
|
||||||
|
// Android OS to relaunch the activity.
|
||||||
if (platform.app->destroyRequested != 0)
|
if (platform.app->destroyRequested != 0)
|
||||||
{
|
{
|
||||||
//CORE.Window.shouldClose = true;
|
CORE.Window.shouldClose = true;
|
||||||
//ANativeActivity_finish(platform.app->activity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -781,7 +781,7 @@ int InitPlatform(void)
|
||||||
// Process this event
|
// Process this event
|
||||||
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
|
||||||
|
|
||||||
// NOTE: Never close window, native activity is controlled by the system!
|
// NOTE: It's highly likely destroyRequested will never be non-zero at the start of the activity lifecycle.
|
||||||
//if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
|
//if (platform.app->destroyRequested != 0) CORE.Window.shouldClose = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -812,6 +812,12 @@ void ClosePlatform(void)
|
||||||
eglTerminate(platform.device);
|
eglTerminate(platform.device);
|
||||||
platform.device = EGL_NO_DISPLAY;
|
platform.device = EGL_NO_DISPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Reset global state in case the activity is being relaunched.
|
||||||
|
if (platform.app->destroyRequested != 0) {
|
||||||
|
CORE = (CoreData){0};
|
||||||
|
platform = (PlatformData){0};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize display device and framebuffer
|
// Initialize display device and framebuffer
|
||||||
|
|
@ -982,6 +988,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
||||||
// Initialize OpenGL context (states and resources)
|
// Initialize OpenGL context (states and resources)
|
||||||
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
||||||
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||||
|
isGpuReady = true;
|
||||||
|
|
||||||
// Setup default viewport
|
// Setup default viewport
|
||||||
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,7 @@ static void ErrorCallback(int error, const char *description);
|
||||||
|
|
||||||
// Window callbacks events
|
// Window callbacks events
|
||||||
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
||||||
|
static void WindowPosCallback(GLFWwindow* window, int x, int y); // GLFW3 WindowPos Callback, runs when window is moved
|
||||||
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||||
static void WindowMaximizeCallback(GLFWwindow* window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
|
static void WindowMaximizeCallback(GLFWwindow* window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
|
||||||
static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
|
static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
|
||||||
|
|
@ -147,7 +148,7 @@ void ToggleFullscreen(void)
|
||||||
if (!CORE.Window.fullscreen)
|
if (!CORE.Window.fullscreen)
|
||||||
{
|
{
|
||||||
// Store previous window position (in case we exit fullscreen)
|
// Store previous window position (in case we exit fullscreen)
|
||||||
glfwGetWindowPos(platform.handle, &CORE.Window.position.x, &CORE.Window.position.y);
|
CORE.Window.previousPosition = CORE.Window.position;
|
||||||
|
|
||||||
int monitorCount = 0;
|
int monitorCount = 0;
|
||||||
int monitorIndex = GetCurrentMonitor();
|
int monitorIndex = GetCurrentMonitor();
|
||||||
|
|
@ -179,7 +180,11 @@ void ToggleFullscreen(void)
|
||||||
CORE.Window.fullscreen = false;
|
CORE.Window.fullscreen = false;
|
||||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||||
|
|
||||||
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
glfwSetWindowMonitor(platform.handle, NULL, CORE.Window.previousPosition.x, CORE.Window.previousPosition.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||||
|
|
||||||
|
// we update the window position right away
|
||||||
|
CORE.Window.position.x = CORE.Window.previousPosition.x;
|
||||||
|
CORE.Window.position.y = CORE.Window.previousPosition.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
|
// Try to enable GPU V-Sync, so frames are limited to screen refresh rate (60Hz -> 60 FPS)
|
||||||
|
|
@ -190,11 +195,11 @@ void ToggleFullscreen(void)
|
||||||
// Toggle borderless windowed mode
|
// Toggle borderless windowed mode
|
||||||
void ToggleBorderlessWindowed(void)
|
void ToggleBorderlessWindowed(void)
|
||||||
{
|
{
|
||||||
// Leave fullscreen before attempting to set borderless windowed mode and get screen position from it
|
// Leave fullscreen before attempting to set borderless windowed mode
|
||||||
bool wasOnFullscreen = false;
|
bool wasOnFullscreen = false;
|
||||||
if (CORE.Window.fullscreen)
|
if (CORE.Window.fullscreen)
|
||||||
{
|
{
|
||||||
CORE.Window.previousPosition = CORE.Window.position;
|
// fullscreen already saves the previous position so it does not need to be set here again
|
||||||
ToggleFullscreen();
|
ToggleFullscreen();
|
||||||
wasOnFullscreen = true;
|
wasOnFullscreen = true;
|
||||||
}
|
}
|
||||||
|
|
@ -213,7 +218,7 @@ void ToggleBorderlessWindowed(void)
|
||||||
{
|
{
|
||||||
// Store screen position and size
|
// Store screen position and size
|
||||||
// NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here
|
// NOTE: If it was on fullscreen, screen position was already stored, so skip setting it here
|
||||||
if (!wasOnFullscreen) glfwGetWindowPos(platform.handle, &CORE.Window.previousPosition.x, &CORE.Window.previousPosition.y);
|
if (!wasOnFullscreen) CORE.Window.previousPosition = CORE.Window.position;
|
||||||
CORE.Window.previousScreen = CORE.Window.screen;
|
CORE.Window.previousScreen = CORE.Window.screen;
|
||||||
|
|
||||||
// Set undecorated and topmost modes and flags
|
// Set undecorated and topmost modes and flags
|
||||||
|
|
@ -255,6 +260,9 @@ void ToggleBorderlessWindowed(void)
|
||||||
glfwFocusWindow(platform.handle);
|
glfwFocusWindow(platform.handle);
|
||||||
|
|
||||||
CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
||||||
|
|
||||||
|
CORE.Window.position.x = CORE.Window.previousPosition.x;
|
||||||
|
CORE.Window.position.y = CORE.Window.previousPosition.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor");
|
else TRACELOG(LOG_WARNING, "GLFW: Failed to find video mode for selected monitor");
|
||||||
|
|
@ -592,6 +600,9 @@ void SetWindowTitle(const char *title)
|
||||||
// Set window position on screen (windowed mode)
|
// Set window position on screen (windowed mode)
|
||||||
void SetWindowPosition(int x, int y)
|
void SetWindowPosition(int x, int y)
|
||||||
{
|
{
|
||||||
|
// Update CORE.Window.position as well
|
||||||
|
CORE.Window.position.x = x;
|
||||||
|
CORE.Window.position.y = y;
|
||||||
glfwSetWindowPos(platform.handle, x, y);
|
glfwSetWindowPos(platform.handle, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -614,8 +625,9 @@ void SetWindowMonitor(int monitor)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_INFO, "GLFW: Selected monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
|
TRACELOG(LOG_INFO, "GLFW: Selected monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
|
||||||
|
|
||||||
const int screenWidth = CORE.Window.screen.width;
|
// Here the render width has to be used again in case high dpi flag is enabled
|
||||||
const int screenHeight = CORE.Window.screen.height;
|
const int screenWidth = CORE.Window.render.width;
|
||||||
|
const int screenHeight = CORE.Window.render.height;
|
||||||
int monitorWorkareaX = 0;
|
int monitorWorkareaX = 0;
|
||||||
int monitorWorkareaY = 0;
|
int monitorWorkareaY = 0;
|
||||||
int monitorWorkareaWidth = 0;
|
int monitorWorkareaWidth = 0;
|
||||||
|
|
@ -1222,7 +1234,6 @@ void PollInputEvents(void)
|
||||||
glfwSetWindowShouldClose(platform.handle, GLFW_FALSE);
|
glfwSetWindowShouldClose(platform.handle, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -1278,7 +1289,7 @@ int InitPlatform(void)
|
||||||
// Disable GlFW auto iconify behaviour
|
// Disable GlFW auto iconify behaviour
|
||||||
// Auto Iconify automatically minimizes (iconifies) the window if the window loses focus
|
// Auto Iconify automatically minimizes (iconifies) the window if the window loses focus
|
||||||
// additionally auto iconify restores the hardware resolution of the monitor if the window that loses focus is a fullscreen window
|
// additionally auto iconify restores the hardware resolution of the monitor if the window that loses focus is a fullscreen window
|
||||||
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
|
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
|
||||||
|
|
||||||
// Check window creation flags
|
// Check window creation flags
|
||||||
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true;
|
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) CORE.Window.fullscreen = true;
|
||||||
|
|
@ -1435,7 +1446,7 @@ int InitPlatform(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
|
TRACELOG(LOG_INFO, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
|
||||||
|
|
||||||
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
|
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
|
||||||
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
|
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),
|
||||||
|
|
@ -1569,11 +1580,16 @@ int InitPlatform(void)
|
||||||
int monitorHeight = 0;
|
int monitorHeight = 0;
|
||||||
glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);
|
glfwGetMonitorWorkarea(monitor, &monitorX, &monitorY, &monitorWidth, &monitorHeight);
|
||||||
|
|
||||||
int posX = monitorX + (monitorWidth - (int)CORE.Window.screen.width)/2;
|
// Here CORE.Window.render.width/height should be used instead of CORE.Window.screen.width/height to center the window correctly when the high dpi flag is enabled.
|
||||||
int posY = monitorY + (monitorHeight - (int)CORE.Window.screen.height)/2;
|
int posX = monitorX + (monitorWidth - (int)CORE.Window.render.width)/2;
|
||||||
|
int posY = monitorY + (monitorHeight - (int)CORE.Window.render.height)/2;
|
||||||
if (posX < monitorX) posX = monitorX;
|
if (posX < monitorX) posX = monitorX;
|
||||||
if (posY < monitorY) posY = monitorY;
|
if (posY < monitorY) posY = monitorY;
|
||||||
SetWindowPosition(posX, posY);
|
SetWindowPosition(posX, posY);
|
||||||
|
|
||||||
|
// Update CORE.Window.position here so it is correct from the start
|
||||||
|
CORE.Window.position.x = posX;
|
||||||
|
CORE.Window.position.y = posY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load OpenGL extensions
|
// Load OpenGL extensions
|
||||||
|
|
@ -1585,6 +1601,7 @@ int InitPlatform(void)
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Set window callback events
|
// Set window callback events
|
||||||
glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
|
glfwSetWindowSizeCallback(platform.handle, WindowSizeCallback); // NOTE: Resizing not allowed by default!
|
||||||
|
glfwSetWindowPosCallback(platform.handle, WindowPosCallback);
|
||||||
glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback);
|
glfwSetWindowMaximizeCallback(platform.handle, WindowMaximizeCallback);
|
||||||
glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback);
|
glfwSetWindowIconifyCallback(platform.handle, WindowIconifyCallback);
|
||||||
glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback);
|
glfwSetWindowFocusCallback(platform.handle, WindowFocusCallback);
|
||||||
|
|
@ -1681,7 +1698,12 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
|
||||||
|
|
||||||
// NOTE: Postprocessing texture is not scaled to new size
|
// NOTE: Postprocessing texture is not scaled to new size
|
||||||
}
|
}
|
||||||
|
static void WindowPosCallback(GLFWwindow* window, int x, int y)
|
||||||
|
{
|
||||||
|
// Set current window position
|
||||||
|
CORE.Window.position.x = x;
|
||||||
|
CORE.Window.position.y = y;
|
||||||
|
}
|
||||||
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
|
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
|
||||||
{
|
{
|
||||||
CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f);
|
CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
*
|
*
|
||||||
* rcore_desktop_rgfw template - Functions to manage window, graphics device and inputs
|
* rcore_desktop_rgfw - Functions to manage window, graphics device and inputs
|
||||||
*
|
*
|
||||||
* PLATFORM: RGFW
|
* PLATFORM: RGFW
|
||||||
* - Windows (Win32, Win64)
|
* - Windows (Win32, Win64)
|
||||||
|
|
@ -69,6 +69,7 @@ void CloseWindow(void);
|
||||||
#define CloseWindow CloseWindow_win32
|
#define CloseWindow CloseWindow_win32
|
||||||
#define ShowCursor __imp_ShowCursor
|
#define ShowCursor __imp_ShowCursor
|
||||||
#define _APISETSTRING_
|
#define _APISETSTRING_
|
||||||
|
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
|
@ -76,10 +77,6 @@ void CloseWindow(void);
|
||||||
#define Size NSSIZE
|
#define Size NSSIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../external/RGFW.h"
|
#include "../external/RGFW.h"
|
||||||
|
|
||||||
#if defined(__WIN32) || defined(__WIN64)
|
#if defined(__WIN32) || defined(__WIN64)
|
||||||
|
|
@ -291,7 +288,6 @@ void SetWindowState(unsigned int flags)
|
||||||
}
|
}
|
||||||
if (flags & FLAG_WINDOW_RESIZABLE)
|
if (flags & FLAG_WINDOW_RESIZABLE)
|
||||||
{
|
{
|
||||||
printf("%i %i\n", platform.window->r.w, platform.window->r.h);
|
|
||||||
RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
|
RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
|
||||||
RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
|
RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
|
||||||
}
|
}
|
||||||
|
|
@ -538,10 +534,8 @@ void *GetWindowHandle(void)
|
||||||
{
|
{
|
||||||
#ifdef RGFW_WEBASM
|
#ifdef RGFW_WEBASM
|
||||||
return (void*)platform.window->src.ctx;
|
return (void*)platform.window->src.ctx;
|
||||||
#elif !defined(RGFW_WINDOWS)
|
|
||||||
return (void *)platform.window->src.window;
|
|
||||||
#else
|
#else
|
||||||
return platform.window->src.hwnd;
|
return (void*)platform.window->src.window;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -692,7 +686,7 @@ void DisableCursor(void)
|
||||||
{
|
{
|
||||||
RGFW_disableCursor = true;
|
RGFW_disableCursor = true;
|
||||||
|
|
||||||
RGFW_window_mouseHold(platform.window, RGFW_AREA(CORE.Window.screen.width / 2, CORE.Window.screen.height / 2));
|
RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
|
||||||
|
|
||||||
HideCursor();
|
HideCursor();
|
||||||
}
|
}
|
||||||
|
|
@ -876,9 +870,8 @@ void PollInputEvents(void)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
CORE.Window.resizedLastFrame = false;
|
CORE.Window.resizedLastFrame = false;
|
||||||
|
|
||||||
|
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||||
#define RGFW_HOLD_MOUSE (1L<<2)
|
#define RGFW_HOLD_MOUSE (1L<<2)
|
||||||
#if defined(RGFW_X11) //|| defined(RGFW_MACOS)
|
|
||||||
if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
|
if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
|
||||||
{
|
{
|
||||||
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
|
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
|
||||||
|
|
@ -888,11 +881,9 @@ void PollInputEvents(void)
|
||||||
{
|
{
|
||||||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
while (RGFW_window_checkEvent(platform.window))
|
while (RGFW_window_checkEvent(platform.window))
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((platform.window->event.type >= RGFW_jsButtonPressed) && (platform.window->event.type <= RGFW_jsAxisMove))
|
if ((platform.window->event.type >= RGFW_jsButtonPressed) && (platform.window->event.type <= RGFW_jsAxisMove))
|
||||||
{
|
{
|
||||||
if (!CORE.Input.Gamepad.ready[platform.window->event.joystick])
|
if (!CORE.Input.Gamepad.ready[platform.window->event.joystick])
|
||||||
|
|
@ -944,7 +935,7 @@ void PollInputEvents(void)
|
||||||
SetupViewport(platform.window->r.w, platform.window->r.h);
|
SetupViewport(platform.window->r.w, platform.window->r.h);
|
||||||
CORE.Window.screen.width = platform.window->r.w;
|
CORE.Window.screen.width = platform.window->r.w;
|
||||||
CORE.Window.screen.height = platform.window->r.h;
|
CORE.Window.screen.height = platform.window->r.h;
|
||||||
CORE.Window.currentFbo.width = platform.window->r.w;;
|
CORE.Window.currentFbo.width = platform.window->r.w;
|
||||||
CORE.Window.currentFbo.height = platform.window->r.h;
|
CORE.Window.currentFbo.height = platform.window->r.h;
|
||||||
CORE.Window.resizedLastFrame = true;
|
CORE.Window.resizedLastFrame = true;
|
||||||
} break;
|
} break;
|
||||||
|
|
@ -1034,15 +1025,8 @@ void PollInputEvents(void)
|
||||||
{
|
{
|
||||||
if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
|
if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
|
||||||
{
|
{
|
||||||
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
|
CORE.Input.Mouse.currentPosition.x += (float)event->point.x;
|
||||||
|
CORE.Input.Mouse.currentPosition.y += (float)event->point.y;
|
||||||
if (event->point.x)
|
|
||||||
CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x;
|
|
||||||
if (event->point.y)
|
|
||||||
CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y;
|
|
||||||
|
|
||||||
CORE.Input.Mouse.currentPosition.x = (float)event->point.x;
|
|
||||||
CORE.Input.Mouse.currentPosition.y = (float)event->point.y;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1209,7 +1193,6 @@ void PollInputEvents(void)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -1266,7 +1249,6 @@ int InitPlatform(void)
|
||||||
*/
|
*/
|
||||||
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
||||||
|
|
||||||
|
|
||||||
if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1);
|
if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1);
|
||||||
|
|
||||||
RGFW_window_makeCurrent(platform.window);
|
RGFW_window_makeCurrent(platform.window);
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,13 @@
|
||||||
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
|
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Defines and Macros
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
#ifndef MAX_CLIPBOARD_BUFFER_LENGTH
|
||||||
|
#define MAX_CLIPBOARD_BUFFER_LENGTH 1024 // Size of the clipboard buffer used on GetClipboardText()
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -852,10 +859,22 @@ void SetClipboardText(const char *text)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get clipboard text content
|
// Get clipboard text content
|
||||||
// NOTE: returned string must be freed with SDL_free()
|
|
||||||
const char *GetClipboardText(void)
|
const char *GetClipboardText(void)
|
||||||
{
|
{
|
||||||
return SDL_GetClipboardText();
|
static char buffer[MAX_CLIPBOARD_BUFFER_LENGTH] = { 0 };
|
||||||
|
|
||||||
|
char *clipboard = SDL_GetClipboardText();
|
||||||
|
|
||||||
|
int clipboardSize = snprintf(buffer, sizeof(buffer), "%s", clipboard);
|
||||||
|
if (clipboardSize >= MAX_CLIPBOARD_BUFFER_LENGTH)
|
||||||
|
{
|
||||||
|
char *truncate = buffer + MAX_CLIPBOARD_BUFFER_LENGTH - 4;
|
||||||
|
sprintf(truncate, "...");
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(clipboard);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show mouse cursor
|
// Show mouse cursor
|
||||||
|
|
@ -1589,8 +1608,7 @@ int InitPlatform(void)
|
||||||
// Initialize storage system
|
// Initialize storage system
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Define base path for storage
|
// Define base path for storage
|
||||||
CORE.Storage.basePath = SDL_GetBasePath(); // Alternative: GetWorkingDirectory();
|
CORE.Storage.basePath = SDL_GetBasePath(); // Alternative: GetWorkingDirectory();
|
||||||
CHDIR(CORE.Storage.basePath);
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully");
|
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully");
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ static const short linuxToRaylibMap[KEYMAP_SIZE] = {
|
||||||
[BTN_TL] = GAMEPAD_BUTTON_LEFT_TRIGGER_1,
|
[BTN_TL] = GAMEPAD_BUTTON_LEFT_TRIGGER_1,
|
||||||
[BTN_TL2] = GAMEPAD_BUTTON_LEFT_TRIGGER_2,
|
[BTN_TL2] = GAMEPAD_BUTTON_LEFT_TRIGGER_2,
|
||||||
[BTN_TR] = GAMEPAD_BUTTON_RIGHT_TRIGGER_1,
|
[BTN_TR] = GAMEPAD_BUTTON_RIGHT_TRIGGER_1,
|
||||||
[BTN_TR2] GAMEPAD_BUTTON_RIGHT_TRIGGER_2,
|
[BTN_TR2] = GAMEPAD_BUTTON_RIGHT_TRIGGER_2,
|
||||||
[BTN_SELECT] = GAMEPAD_BUTTON_MIDDLE_LEFT,
|
[BTN_SELECT] = GAMEPAD_BUTTON_MIDDLE_LEFT,
|
||||||
[BTN_MODE] = GAMEPAD_BUTTON_MIDDLE,
|
[BTN_MODE] = GAMEPAD_BUTTON_MIDDLE,
|
||||||
[BTN_START] = GAMEPAD_BUTTON_MIDDLE_RIGHT,
|
[BTN_START] = GAMEPAD_BUTTON_MIDDLE_RIGHT,
|
||||||
|
|
@ -763,8 +763,10 @@ int InitPlatform(void)
|
||||||
|
|
||||||
drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);
|
drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);
|
TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);
|
||||||
|
|
||||||
if ((con->connection == DRM_MODE_CONNECTED) && (con->encoder_id))
|
// In certain cases the status of the conneciton is reported as UKNOWN, but it is still connected.
|
||||||
|
// This might be a hardware or software limitation like on Raspberry Pi Zero with composite output.
|
||||||
|
if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) && (con->encoder_id))
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");
|
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");
|
||||||
platform.connector = con;
|
platform.connector = con;
|
||||||
|
|
@ -1478,7 +1480,6 @@ static void ConfigureEvdevDevice(char *device)
|
||||||
TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true;
|
TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (TEST_BIT(evBits, EV_KEY))
|
if (TEST_BIT(evBits, EV_KEY))
|
||||||
{
|
{
|
||||||
// The first 32 keys as defined in input-event-codes.h are pretty much
|
// The first 32 keys as defined in input-event-codes.h are pretty much
|
||||||
|
|
|
||||||
|
|
@ -430,7 +430,6 @@ void PollInputEvents(void)
|
||||||
// TODO: Poll input events for current platform
|
// TODO: Poll input events for current platform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,8 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GLFWwindow *handle; // GLFW window handle (graphic device)
|
GLFWwindow *handle; // GLFW window handle (graphic device)
|
||||||
bool ourFullscreen; // Internal var to filter our handling of fullscreen vs the user handling of fullscreen
|
bool ourFullscreen; // Internal var to filter our handling of fullscreen vs the user handling of fullscreen
|
||||||
|
int unmaximizedWidth; // Internal var to store the unmaximized window (canvas) width
|
||||||
|
int unmaximizedHeight; // Internal var to store the unmaximized window (canvas) height
|
||||||
} PlatformData;
|
} PlatformData;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -317,7 +319,18 @@ void ToggleBorderlessWindowed(void)
|
||||||
// Set window state: maximized, if resizable
|
// Set window state: maximized, if resizable
|
||||||
void MaximizeWindow(void)
|
void MaximizeWindow(void)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "MaximizeWindow() not available on target platform");
|
if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE && !(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED))
|
||||||
|
{
|
||||||
|
platform.unmaximizedWidth = CORE.Window.screen.width;
|
||||||
|
platform.unmaximizedHeight = CORE.Window.screen.height;
|
||||||
|
|
||||||
|
const int tabWidth = EM_ASM_INT( { return window.innerWidth; }, 0);
|
||||||
|
const int tabHeight = EM_ASM_INT( { return window.innerHeight; }, 0);
|
||||||
|
|
||||||
|
if (tabWidth && tabHeight) glfwSetWindowSize(platform.handle, tabWidth, tabHeight);
|
||||||
|
|
||||||
|
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set window state: minimized
|
// Set window state: minimized
|
||||||
|
|
@ -329,7 +342,12 @@ void MinimizeWindow(void)
|
||||||
// Set window state: not minimized/maximized
|
// Set window state: not minimized/maximized
|
||||||
void RestoreWindow(void)
|
void RestoreWindow(void)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "RestoreWindow() not available on target platform");
|
if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE && (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED))
|
||||||
|
{
|
||||||
|
if (platform.unmaximizedWidth && platform.unmaximizedHeight) glfwSetWindowSize(platform.handle, platform.unmaximizedWidth, platform.unmaximizedHeight);
|
||||||
|
|
||||||
|
CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set window configuration state using flags
|
// Set window configuration state using flags
|
||||||
|
|
@ -398,9 +416,20 @@ void SetWindowState(unsigned int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// State change: FLAG_WINDOW_MAXIMIZED
|
// State change: FLAG_WINDOW_MAXIMIZED
|
||||||
if ((flags & FLAG_WINDOW_MAXIMIZED) > 0)
|
if (((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) != (flags & FLAG_WINDOW_MAXIMIZED)) && ((flags & FLAG_WINDOW_MAXIMIZED) > 0))
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MAXIMIZED) not available on target platform");
|
if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE)
|
||||||
|
{
|
||||||
|
platform.unmaximizedWidth = CORE.Window.screen.width;
|
||||||
|
platform.unmaximizedHeight = CORE.Window.screen.height;
|
||||||
|
|
||||||
|
const int tabWidth = EM_ASM_INT( { return window.innerWidth; }, 0);
|
||||||
|
const int tabHeight = EM_ASM_INT( { return window.innerHeight; }, 0);
|
||||||
|
|
||||||
|
if (tabWidth && tabHeight) glfwSetWindowSize(platform.handle, tabWidth, tabHeight);
|
||||||
|
|
||||||
|
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// State change: FLAG_WINDOW_UNFOCUSED
|
// State change: FLAG_WINDOW_UNFOCUSED
|
||||||
|
|
@ -516,9 +545,14 @@ void ClearWindowState(unsigned int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// State change: FLAG_WINDOW_MAXIMIZED
|
// State change: FLAG_WINDOW_MAXIMIZED
|
||||||
if ((flags & FLAG_WINDOW_MAXIMIZED) > 0)
|
if (((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0) && ((flags & FLAG_WINDOW_MAXIMIZED) > 0))
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MAXIMIZED) not available on target platform");
|
if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE)
|
||||||
|
{
|
||||||
|
if (platform.unmaximizedWidth && platform.unmaximizedHeight) glfwSetWindowSize(platform.handle, platform.unmaximizedWidth, platform.unmaximizedHeight);
|
||||||
|
|
||||||
|
CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// State change: FLAG_WINDOW_UNDECORATED
|
// State change: FLAG_WINDOW_UNDECORATED
|
||||||
|
|
@ -639,7 +673,9 @@ void SetWindowSize(int width, int height)
|
||||||
// Set window opacity, value opacity is between 0.0 and 1.0
|
// Set window opacity, value opacity is between 0.0 and 1.0
|
||||||
void SetWindowOpacity(float opacity)
|
void SetWindowOpacity(float opacity)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform");
|
if (opacity >= 1.0f) opacity = 1.0f;
|
||||||
|
else if (opacity <= 0.0f) opacity = 0.0f;
|
||||||
|
EM_ASM({ document.getElementById('canvas').style.opacity = $0; }, opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set window focused
|
// Set window focused
|
||||||
|
|
@ -935,7 +971,6 @@ void PollInputEvents(void)
|
||||||
// so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed!
|
// so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed!
|
||||||
//for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };
|
//for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };
|
||||||
|
|
||||||
|
|
||||||
// Gamepad support using emscripten API
|
// Gamepad support using emscripten API
|
||||||
// NOTE: GLFW3 joystick functionality not available in web
|
// NOTE: GLFW3 joystick functionality not available in web
|
||||||
|
|
||||||
|
|
|
||||||
16
src/raudio.c
16
src/raudio.c
|
|
@ -892,8 +892,8 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
|
||||||
return wave;
|
return wave;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if wave data is ready
|
// Checks if wave data is valid (data loaded and parameters)
|
||||||
bool IsWaveReady(Wave wave)
|
bool IsWaveValid(Wave wave)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
|
@ -993,8 +993,8 @@ Sound LoadSoundAlias(Sound source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Checks if a sound is ready
|
// Checks if a sound is valid (data loaded and buffers initialized)
|
||||||
bool IsSoundReady(Sound sound)
|
bool IsSoundValid(Sound sound)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
|
@ -1726,8 +1726,8 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
|
||||||
return music;
|
return music;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if a music stream is ready
|
// Checks if a music stream is valid (context and buffers initialized)
|
||||||
bool IsMusicReady(Music music)
|
bool IsMusicValid(Music music)
|
||||||
{
|
{
|
||||||
return ((music.ctxData != NULL) && // Validate context loaded
|
return ((music.ctxData != NULL) && // Validate context loaded
|
||||||
(music.frameCount > 0) && // Validate audio frame count
|
(music.frameCount > 0) && // Validate audio frame count
|
||||||
|
|
@ -2119,8 +2119,8 @@ AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if an audio stream is ready
|
// Checks if an audio stream is valid (buffers initialized)
|
||||||
bool IsAudioStreamReady(AudioStream stream)
|
bool IsAudioStreamValid(AudioStream stream)
|
||||||
{
|
{
|
||||||
return ((stream.buffer != NULL) && // Validate stream buffer
|
return ((stream.buffer != NULL) && // Validate stream buffer
|
||||||
(stream.sampleRate > 0) && // Validate sample rate is supported
|
(stream.sampleRate > 0) && // Validate sample rate is supported
|
||||||
|
|
|
||||||
57
src/raylib.h
57
src/raylib.h
|
|
@ -352,8 +352,10 @@ typedef struct Mesh {
|
||||||
// Animation vertex data
|
// Animation vertex data
|
||||||
float *animVertices; // Animated vertex positions (after bones transformations)
|
float *animVertices; // Animated vertex positions (after bones transformations)
|
||||||
float *animNormals; // Animated normals (after bones transformations)
|
float *animNormals; // Animated normals (after bones transformations)
|
||||||
unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning)
|
unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) (shader-location = 6)
|
||||||
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning)
|
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7)
|
||||||
|
Matrix *boneMatrices; // Bones animated transformation matrices
|
||||||
|
int boneCount; // Number of bones
|
||||||
|
|
||||||
// OpenGL identifiers
|
// OpenGL identifiers
|
||||||
unsigned int vaoId; // OpenGL Vertex Array Object id
|
unsigned int vaoId; // OpenGL Vertex Array Object id
|
||||||
|
|
@ -790,7 +792,10 @@ typedef enum {
|
||||||
SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap
|
SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap
|
||||||
SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance
|
SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance
|
||||||
SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter
|
SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter
|
||||||
SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf
|
SHADER_LOC_MAP_BRDF, // Shader location: sampler2d texture: brdf
|
||||||
|
SHADER_LOC_VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds
|
||||||
|
SHADER_LOC_VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights
|
||||||
|
SHADER_LOC_BONE_MATRICES // Shader location: array of matrices uniform: boneMatrices
|
||||||
} ShaderLocationIndex;
|
} ShaderLocationIndex;
|
||||||
|
|
||||||
#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
|
#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
|
||||||
|
|
@ -968,8 +973,8 @@ RLAPI bool IsWindowResized(void); // Check if wi
|
||||||
RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled
|
RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled
|
||||||
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP)
|
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP)
|
||||||
RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags
|
RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags
|
||||||
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP)
|
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed [resizes monitor to match window resolution] (only PLATFORM_DESKTOP)
|
||||||
RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP)
|
RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed [resizes window to match monitor resolution] (only PLATFORM_DESKTOP)
|
||||||
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
|
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
|
||||||
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP)
|
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP)
|
||||||
RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP)
|
RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP)
|
||||||
|
|
@ -1039,7 +1044,7 @@ RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR s
|
||||||
// NOTE: Shader functionality is not available on OpenGL 1.1
|
// NOTE: Shader functionality is not available on OpenGL 1.1
|
||||||
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
|
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
|
||||||
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
|
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
|
||||||
RLAPI bool IsShaderReady(Shader shader); // Check if a shader is ready
|
RLAPI bool IsShaderValid(Shader shader); // Check if a shader is valid (loaded on GPU)
|
||||||
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
||||||
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
|
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
|
||||||
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
|
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
|
||||||
|
|
@ -1122,11 +1127,12 @@ RLAPI const char *GetDirectoryPath(const char *filePath); // Get full pa
|
||||||
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
|
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
|
||||||
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
|
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
|
||||||
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
|
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
|
||||||
|
RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success
|
||||||
RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success
|
RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success
|
||||||
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
|
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
|
||||||
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
|
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
|
||||||
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths
|
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths
|
||||||
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan
|
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result
|
||||||
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
|
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
|
||||||
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
|
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
|
||||||
RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths
|
RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths
|
||||||
|
|
@ -1138,6 +1144,10 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
|
||||||
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
|
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
|
||||||
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
|
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
|
||||||
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
|
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
|
||||||
|
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
|
||||||
|
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||||
|
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||||
|
|
||||||
|
|
||||||
// Automation events functionality
|
// Automation events functionality
|
||||||
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
||||||
|
|
@ -1205,7 +1215,7 @@ RLAPI int GetTouchPointCount(void); // Get number of t
|
||||||
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||||
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
|
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
|
||||||
RLAPI int GetGestureDetected(void); // Get latest detected gesture
|
RLAPI int GetGestureDetected(void); // Get latest detected gesture
|
||||||
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
|
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
|
||||||
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||||
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
|
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
|
||||||
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
|
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
|
||||||
|
|
@ -1228,8 +1238,8 @@ RLAPI Texture2D GetShapesTexture(void); // Get t
|
||||||
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
|
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
|
||||||
|
|
||||||
// Basic shapes drawing functions
|
// Basic shapes drawing functions
|
||||||
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel
|
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel using geometry [Can be slow, use with care]
|
||||||
RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
|
RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel using geometry (Vector version) [Can be slow, use with care]
|
||||||
RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
|
RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
|
||||||
RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines)
|
RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines)
|
||||||
RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads)
|
RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads)
|
||||||
|
|
@ -1306,13 +1316,12 @@ RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2);
|
||||||
// NOTE: These functions do not require GPU access
|
// NOTE: These functions do not require GPU access
|
||||||
RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
|
RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
|
||||||
RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
|
RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
|
||||||
RLAPI Image LoadImageSvg(const char *fileNameOrString, int width, int height); // Load image from SVG file data or string with specified size
|
|
||||||
RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data)
|
RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data)
|
||||||
RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer
|
RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer
|
||||||
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'
|
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'
|
||||||
RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data
|
RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data
|
||||||
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot)
|
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot)
|
||||||
RLAPI bool IsImageReady(Image image); // Check if an image is ready
|
RLAPI bool IsImageValid(Image image); // Check if an image is valid (data and parameters)
|
||||||
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||||
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
|
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
|
||||||
RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer
|
RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer
|
||||||
|
|
@ -1398,9 +1407,9 @@ RLAPI Texture2D LoadTexture(const char *fileName);
|
||||||
RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
|
RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
|
||||||
RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported
|
RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported
|
||||||
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
|
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
|
||||||
RLAPI bool IsTextureReady(Texture2D texture); // Check if a texture is ready
|
RLAPI bool IsTextureValid(Texture2D texture); // Check if a texture is valid (loaded in GPU)
|
||||||
RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
|
RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
|
||||||
RLAPI bool IsRenderTextureReady(RenderTexture2D target); // Check if a render texture is ready
|
RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if a render texture is valid (loaded in GPU)
|
||||||
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
|
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
|
||||||
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
|
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
|
||||||
RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data
|
RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data
|
||||||
|
|
@ -1431,6 +1440,7 @@ RLAPI Color ColorBrightness(Color color, float factor); // G
|
||||||
RLAPI Color ColorContrast(Color color, float contrast); // Get color with contrast correction, contrast values between -1.0f and 1.0f
|
RLAPI Color ColorContrast(Color color, float contrast); // Get color with contrast correction, contrast values between -1.0f and 1.0f
|
||||||
RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f
|
RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f
|
||||||
RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint
|
RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint
|
||||||
|
RLAPI Color ColorLerp(Color color1, Color color2, float factor); // Get color lerp interpolation between two colors, factor [0.0f..1.0f]
|
||||||
RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value
|
RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value
|
||||||
RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
|
RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
|
||||||
RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer
|
RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer
|
||||||
|
|
@ -1443,10 +1453,10 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
|
||||||
// Font loading/unloading functions
|
// Font loading/unloading functions
|
||||||
RLAPI Font GetFontDefault(void); // Get the default Font
|
RLAPI Font GetFontDefault(void); // Get the default Font
|
||||||
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
|
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
|
||||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set
|
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
|
||||||
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
|
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
|
||||||
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
|
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
|
||||||
RLAPI bool IsFontReady(Font font); // Check if a font is ready
|
RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked)
|
||||||
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use
|
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use
|
||||||
RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
|
RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
|
||||||
RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM)
|
RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM)
|
||||||
|
|
@ -1536,7 +1546,7 @@ RLAPI void DrawGrid(int slices, float spacing);
|
||||||
// Model management functions
|
// Model management functions
|
||||||
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
|
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
|
||||||
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
|
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
|
||||||
RLAPI bool IsModelReady(Model model); // Check if a model is ready
|
RLAPI bool IsModelValid(Model model); // Check if a model is valid (loaded in GPU, VAO/VBOs)
|
||||||
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
|
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
|
||||||
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
|
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
|
||||||
|
|
||||||
|
|
@ -1545,6 +1555,8 @@ RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint);
|
||||||
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
|
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||||
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
|
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
|
||||||
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
||||||
|
RLAPI void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points
|
||||||
|
RLAPI void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters
|
||||||
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
|
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
|
||||||
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
|
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
|
||||||
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
|
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
|
||||||
|
|
@ -1577,7 +1589,7 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
|
||||||
// Material loading/unloading functions
|
// Material loading/unloading functions
|
||||||
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
|
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
|
||||||
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
|
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
|
||||||
RLAPI bool IsMaterialReady(Material material); // Check if a material is ready
|
RLAPI bool IsMaterialValid(Material material); // Check if a material is valid (shader assigned, map textures loaded in GPU)
|
||||||
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
|
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
|
||||||
RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
|
RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
|
||||||
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
|
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
|
||||||
|
|
@ -1588,6 +1600,7 @@ RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame);
|
||||||
RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
|
RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
|
||||||
RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data
|
RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data
|
||||||
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
|
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
|
||||||
|
RLAPI void UpdateModelAnimationBoneMatrices(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (Note GPU skinning does not work on Mac)
|
||||||
|
|
||||||
// Collision detection functions
|
// Collision detection functions
|
||||||
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
|
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
|
||||||
|
|
@ -1614,11 +1627,11 @@ RLAPI float GetMasterVolume(void); // Get mas
|
||||||
// Wave/Sound loading/unloading functions
|
// Wave/Sound loading/unloading functions
|
||||||
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
|
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
|
||||||
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
|
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
|
||||||
RLAPI bool IsWaveReady(Wave wave); // Checks if wave data is ready
|
RLAPI bool IsWaveValid(Wave wave); // Checks if wave data is valid (data loaded and parameters)
|
||||||
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
|
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
|
||||||
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
|
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
|
||||||
RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data
|
RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data
|
||||||
RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready
|
RLAPI bool IsSoundValid(Sound sound); // Checks if a sound is valid (data loaded and buffers initialized)
|
||||||
RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data
|
RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data
|
||||||
RLAPI void UnloadWave(Wave wave); // Unload wave data
|
RLAPI void UnloadWave(Wave wave); // Unload wave data
|
||||||
RLAPI void UnloadSound(Sound sound); // Unload sound
|
RLAPI void UnloadSound(Sound sound); // Unload sound
|
||||||
|
|
@ -1644,7 +1657,7 @@ RLAPI void UnloadWaveSamples(float *samples); // Unload
|
||||||
// Music management functions
|
// Music management functions
|
||||||
RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
|
RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
|
||||||
RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data
|
RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data
|
||||||
RLAPI bool IsMusicReady(Music music); // Checks if a music stream is ready
|
RLAPI bool IsMusicValid(Music music); // Checks if a music stream is valid (context and buffers initialized)
|
||||||
RLAPI void UnloadMusicStream(Music music); // Unload music stream
|
RLAPI void UnloadMusicStream(Music music); // Unload music stream
|
||||||
RLAPI void PlayMusicStream(Music music); // Start music playing
|
RLAPI void PlayMusicStream(Music music); // Start music playing
|
||||||
RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing
|
RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing
|
||||||
|
|
@ -1661,7 +1674,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur
|
||||||
|
|
||||||
// AudioStream management functions
|
// AudioStream management functions
|
||||||
RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
|
RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
|
||||||
RLAPI bool IsAudioStreamReady(AudioStream stream); // Checks if an audio stream is ready
|
RLAPI bool IsAudioStreamValid(AudioStream stream); // Checks if an audio stream is valid (buffers initialized)
|
||||||
RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
|
RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
|
||||||
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data
|
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data
|
||||||
RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
||||||
|
|
|
||||||
356
src/raymath.h
356
src/raymath.h
|
|
@ -1,6 +1,6 @@
|
||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
*
|
*
|
||||||
* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
* raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
||||||
*
|
*
|
||||||
* CONVENTIONS:
|
* CONVENTIONS:
|
||||||
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
|
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
* - Functions are always self-contained, no function use another raymath function inside,
|
* - Functions are always self-contained, no function use another raymath function inside,
|
||||||
* required code is directly re-implemented inside
|
* required code is directly re-implemented inside
|
||||||
* - Functions input parameters are always received by value (2 unavoidable exceptions)
|
* - Functions input parameters are always received by value (2 unavoidable exceptions)
|
||||||
* - Functions use always a "result" variable for return
|
* - Functions use always a "result" variable for return (except C++ operators)
|
||||||
* - Functions are always defined inline
|
* - Functions are always defined inline
|
||||||
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
|
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
|
||||||
* - No compound literals used to make sure libray is compatible with C++
|
* - No compound literals used to make sure libray is compatible with C++
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
* Define static inline functions code, so #include header suffices for use.
|
* Define static inline functions code, so #include header suffices for use.
|
||||||
* This may use up lots of memory.
|
* This may use up lots of memory.
|
||||||
*
|
*
|
||||||
|
* #define RAYMATH_DISABLE_CPP_OPERATORS
|
||||||
|
* Disables C++ operator overloads for raymath types.
|
||||||
*
|
*
|
||||||
* LICENSE: zlib/libpng
|
* LICENSE: zlib/libpng
|
||||||
*
|
*
|
||||||
|
|
@ -2580,4 +2582,354 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && !defined(RAYMATH_DISABLE_CPP_OPERATORS)
|
||||||
|
|
||||||
|
// Optional C++ math operators
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Vector2 operators
|
||||||
|
static constexpr Vector2 Vector2Zeros = { 0, 0 };
|
||||||
|
static constexpr Vector2 Vector2Ones = { 1, 1 };
|
||||||
|
static constexpr Vector2 Vector2UnitX = { 1, 0 };
|
||||||
|
static constexpr Vector2 Vector2UnitY = { 0, 1 };
|
||||||
|
|
||||||
|
inline Vector2 operator + (const Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
return Vector2Add(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector2& operator += (Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector2Add(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator - (const Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
return Vector2Subtract(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector2& operator -= (Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector2Subtract(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator * (const Vector2& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
return Vector2Scale(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector2& operator *= (Vector2& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector2Scale(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator * (const Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
return Vector2Multiply(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector2& operator *= (Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector2Multiply(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator * (const Vector2& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
return Vector2Transform(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector2& operator -= (Vector2& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector2Transform(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator / (const Vector2& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
return Vector2Scale(lhs, 1.0f / rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector2& operator /= (Vector2& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector2Scale(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 operator / (const Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
return Vector2Divide(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector2& operator /= (Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector2Divide(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator == (const Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const Vector2& lhs, const Vector2& rhs)
|
||||||
|
{
|
||||||
|
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vector3 operators
|
||||||
|
static constexpr Vector3 Vector3Zeros = { 0, 0, 0 };
|
||||||
|
static constexpr Vector3 Vector3Ones = { 1, 1, 1 };
|
||||||
|
static constexpr Vector3 Vector3UnitX = { 1, 0, 0 };
|
||||||
|
static constexpr Vector3 Vector3UnitY = { 0, 1, 0 };
|
||||||
|
static constexpr Vector3 Vector3UnitZ = { 0, 0, 1 };
|
||||||
|
|
||||||
|
inline Vector3 operator + (const Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
return Vector3Add(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector3& operator += (Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector3Add(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator - (const Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
return Vector3Subtract(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector3& operator -= (Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector3Subtract(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator * (const Vector3& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
return Vector3Scale(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector3& operator *= (Vector3& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector3Scale(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator * (const Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
return Vector3Multiply(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector3& operator *= (Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector3Multiply(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator * (const Vector3& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
return Vector3Transform(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector3& operator -= (Vector3& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector3Transform(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator / (const Vector3& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
return Vector3Scale(lhs, 1.0f / rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector3& operator /= (Vector3& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector3Scale(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator / (const Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
return Vector3Divide(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector3& operator /= (Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector3Divide(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator == (const Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const Vector3& lhs, const Vector3& rhs)
|
||||||
|
{
|
||||||
|
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vector4 operators
|
||||||
|
static constexpr Vector4 Vector4Zeros = { 0, 0, 0, 0 };
|
||||||
|
static constexpr Vector4 Vector4Ones = { 1, 1, 1, 1 };
|
||||||
|
static constexpr Vector4 Vector4UnitX = { 1, 0, 0, 0 };
|
||||||
|
static constexpr Vector4 Vector4UnitY = { 0, 1, 0, 0 };
|
||||||
|
static constexpr Vector4 Vector4UnitZ = { 0, 0, 1, 0 };
|
||||||
|
static constexpr Vector4 Vector4UnitW = { 0, 0, 0, 1 };
|
||||||
|
|
||||||
|
inline Vector4 operator + (const Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
return Vector4Add(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector4& operator += (Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector4Add(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 operator - (const Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
return Vector4Subtract(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector4& operator -= (Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector4Subtract(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 operator * (const Vector4& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
return Vector4Scale(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector4& operator *= (Vector4& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector4Scale(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 operator * (const Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
return Vector4Multiply(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector4& operator *= (Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector4Multiply(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 operator / (const Vector4& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
return Vector4Scale(lhs, 1.0f / rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector4& operator /= (Vector4& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector4Scale(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector4 operator / (const Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
return Vector4Divide(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector4& operator /= (Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
lhs = Vector4Divide(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator == (const Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z) && FloatEquals(lhs.w, rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const Vector4& lhs, const Vector4& rhs)
|
||||||
|
{
|
||||||
|
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z) || !FloatEquals(lhs.w, rhs.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quaternion operators
|
||||||
|
static constexpr Quaternion QuaternionZeros = { 0, 0, 0, 0 };
|
||||||
|
static constexpr Quaternion QuaternionOnes = { 1, 1, 1, 1 };
|
||||||
|
static constexpr Quaternion QuaternionUnitX = { 0, 0, 0, 1 };
|
||||||
|
|
||||||
|
inline Quaternion operator + (const Quaternion& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
return QuaternionAddValue(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Quaternion& operator += (Quaternion& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
lhs = QuaternionAddValue(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion operator - (const Quaternion& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
return QuaternionSubtractValue(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Quaternion& operator -= (Quaternion& lhs, const float& rhs)
|
||||||
|
{
|
||||||
|
lhs = QuaternionSubtractValue(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Quaternion operator * (const Quaternion& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
return QuaternionTransform(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Quaternion& operator *= (Quaternion& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
lhs = QuaternionTransform(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matrix operators
|
||||||
|
inline Matrix operator + (const Matrix& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
return MatrixAdd(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Matrix& operator += (Matrix& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
lhs = MatrixAdd(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Matrix operator - (const Matrix& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
return MatrixSubtract(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Matrix& operator -= (Matrix& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
lhs = MatrixSubtract(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Matrix operator * (const Matrix& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
return MatrixMultiply(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Matrix& operator *= (Matrix& lhs, const Matrix& rhs)
|
||||||
|
{
|
||||||
|
lhs = MatrixMultiply(lhs, rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
#endif // C++ operators
|
||||||
|
|
||||||
#endif // RAYMATH_H
|
#endif // RAYMATH_H
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,6 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
|
||||||
|
|
||||||
#endif // RCAMERA_H
|
#endif // RCAMERA_H
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************************
|
/***********************************************************************************
|
||||||
*
|
*
|
||||||
* CAMERA IMPLEMENTATION
|
* CAMERA IMPLEMENTATION
|
||||||
|
|
@ -444,11 +443,17 @@ void UpdateCamera(Camera *camera, int mode)
|
||||||
bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
||||||
bool rotateUp = false;
|
bool rotateUp = false;
|
||||||
|
|
||||||
|
// Camera speeds based on frame time
|
||||||
|
float cameraMoveSpeed = CAMERA_MOVE_SPEED*GetFrameTime();
|
||||||
|
float cameraRotationSpeed = CAMERA_ROTATION_SPEED*GetFrameTime();
|
||||||
|
float cameraPanSpeed = CAMERA_PAN_SPEED*GetFrameTime();
|
||||||
|
float cameraOrbitalSpeed = CAMERA_ORBITAL_SPEED*GetFrameTime();
|
||||||
|
|
||||||
if (mode == CAMERA_CUSTOM) {}
|
if (mode == CAMERA_CUSTOM) {}
|
||||||
else if (mode == CAMERA_ORBITAL)
|
else if (mode == CAMERA_ORBITAL)
|
||||||
{
|
{
|
||||||
// Orbital can just orbit
|
// Orbital can just orbit
|
||||||
Matrix rotation = MatrixRotate(GetCameraUp(camera), CAMERA_ORBITAL_SPEED*GetFrameTime());
|
Matrix rotation = MatrixRotate(GetCameraUp(camera), cameraOrbitalSpeed);
|
||||||
Vector3 view = Vector3Subtract(camera->position, camera->target);
|
Vector3 view = Vector3Subtract(camera->position, camera->target);
|
||||||
view = Vector3Transform(view, rotation);
|
view = Vector3Transform(view, rotation);
|
||||||
camera->position = Vector3Add(camera->target, view);
|
camera->position = Vector3Add(camera->target, view);
|
||||||
|
|
@ -456,22 +461,22 @@ void UpdateCamera(Camera *camera, int mode)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Camera rotation
|
// Camera rotation
|
||||||
if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
|
if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
|
||||||
if (IsKeyDown(KEY_UP)) CameraPitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
|
if (IsKeyDown(KEY_UP)) CameraPitch(camera, cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
|
||||||
if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget);
|
if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -cameraRotationSpeed, rotateAroundTarget);
|
||||||
if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget);
|
if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, cameraRotationSpeed, rotateAroundTarget);
|
||||||
if (IsKeyDown(KEY_Q)) CameraRoll(camera, -CAMERA_ROTATION_SPEED);
|
if (IsKeyDown(KEY_Q)) CameraRoll(camera, -cameraRotationSpeed);
|
||||||
if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED);
|
if (IsKeyDown(KEY_E)) CameraRoll(camera, cameraRotationSpeed);
|
||||||
|
|
||||||
// Camera movement
|
// Camera movement
|
||||||
// Camera pan (for CAMERA_FREE)
|
// Camera pan (for CAMERA_FREE)
|
||||||
if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
|
if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
|
||||||
{
|
{
|
||||||
const Vector2 mouseDelta = GetMouseDelta();
|
const Vector2 mouseDelta = GetMouseDelta();
|
||||||
if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane);
|
if (mouseDelta.x > 0.0f) CameraMoveRight(camera, cameraPanSpeed, moveInWorldPlane);
|
||||||
if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane);
|
if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -cameraPanSpeed, moveInWorldPlane);
|
||||||
if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED);
|
if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -cameraPanSpeed);
|
||||||
if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED);
|
if (mouseDelta.y < 0.0f) CameraMoveUp(camera, cameraPanSpeed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -481,7 +486,6 @@ void UpdateCamera(Camera *camera, int mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard support
|
// Keyboard support
|
||||||
float cameraMoveSpeed = CAMERA_MOVE_SPEED*GetFrameTime();
|
|
||||||
if (IsKeyDown(KEY_W)) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
|
if (IsKeyDown(KEY_W)) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
|
||||||
if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
|
if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
|
||||||
if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);
|
if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);
|
||||||
|
|
|
||||||
427
src/rcore.c
427
src/rcore.c
|
|
@ -165,6 +165,10 @@ unsigned int __stdcall timeBeginPeriod(unsigned int uPeriod);
|
||||||
unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#include <sys/syslimits.h>
|
#include <sys/syslimits.h>
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
|
|
@ -187,14 +191,16 @@ unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <direct.h> // Required for: _getch(), _chdir()
|
#include <io.h> // Required for: _access() [Used in FileExists()]
|
||||||
|
#include <direct.h> // Required for: _getch(), _chdir(), _mkdir()
|
||||||
#define GETCWD _getcwd // NOTE: MSDN recommends not to use getcwd(), chdir()
|
#define GETCWD _getcwd // NOTE: MSDN recommends not to use getcwd(), chdir()
|
||||||
#define CHDIR _chdir
|
#define CHDIR _chdir
|
||||||
#include <io.h> // Required for: _access() [Used in FileExists()]
|
#define MKDIR(dir) _mkdir(dir)
|
||||||
#else
|
#else
|
||||||
#include <unistd.h> // Required for: getch(), chdir() (POSIX), access()
|
#include <unistd.h> // Required for: getch(), chdir(), mkdir(), access()
|
||||||
#define GETCWD getcwd
|
#define GETCWD getcwd
|
||||||
#define CHDIR chdir
|
#define CHDIR chdir
|
||||||
|
#define MKDIR(dir) mkdir(dir, 0777)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -247,6 +253,10 @@ unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
||||||
#define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record
|
#define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DIRECTORY_FILTER_TAG
|
||||||
|
#define DIRECTORY_FILTER_TAG "DIR" // Name tag used to request directory inclusion on directory scan
|
||||||
|
#endif // NOTE: Used in ScanDirectoryFiles(), ScanDirectoryFilesRecursively() and LoadDirectoryFilesEx()
|
||||||
|
|
||||||
// Flags operation macros
|
// Flags operation macros
|
||||||
#define FLAG_SET(n, f) ((n) |= (f))
|
#define FLAG_SET(n, f) ((n) |= (f))
|
||||||
#define FLAG_CLEAR(n, f) ((n) &= ~(f))
|
#define FLAG_CLEAR(n, f) ((n) &= ~(f))
|
||||||
|
|
@ -360,10 +370,15 @@ typedef struct CoreData {
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported symbol, required for some bindings
|
RLAPI const char *raylib_version = RAYLIB_VERSION; // raylib version exported symbol, required for some bindings
|
||||||
|
|
||||||
CoreData CORE = { 0 }; // Global CORE state context
|
CoreData CORE = { 0 }; // Global CORE state context
|
||||||
|
|
||||||
|
// Flag to note GPU acceleration is available,
|
||||||
|
// referenced from other modules to support GPU data loading
|
||||||
|
// NOTE: Useful to allow Texture, RenderTexture, Font.texture, Mesh.vaoId/vboId, Shader loading
|
||||||
|
bool isGpuReady = false;
|
||||||
|
|
||||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||||
static int screenshotCounter = 0; // Screenshots counter
|
static int screenshotCounter = 0; // Screenshots counter
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SUPPORT_GIF_RECORDING)
|
#if defined(SUPPORT_GIF_RECORDING)
|
||||||
|
|
@ -563,7 +578,6 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
|
||||||
//void DisableCursor(void)
|
//void DisableCursor(void)
|
||||||
|
|
||||||
// Initialize window and OpenGL context
|
// Initialize window and OpenGL context
|
||||||
// NOTE: data parameter could be used to pass any kind of required data to the initialization
|
|
||||||
void InitWindow(int width, int height, const char *title)
|
void InitWindow(int width, int height, const char *title)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
|
TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);
|
||||||
|
|
@ -637,28 +651,31 @@ void InitWindow(int width, int height, const char *title)
|
||||||
// Initialize rlgl default data (buffers and shaders)
|
// Initialize rlgl default data (buffers and shaders)
|
||||||
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
||||||
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||||
|
isGpuReady = true; // Flag to note GPU has been initialized successfully
|
||||||
|
|
||||||
// Setup default viewport
|
// Setup default viewport
|
||||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||||
|
|
||||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_MODULE_RTEXT)
|
||||||
// Load default font
|
#if defined(SUPPORT_DEFAULT_FONT)
|
||||||
// WARNING: External function: Module required: rtext
|
// Load default font
|
||||||
LoadFontDefault();
|
// WARNING: External function: Module required: rtext
|
||||||
#if defined(SUPPORT_MODULE_RSHAPES)
|
LoadFontDefault();
|
||||||
// Set font white rectangle for shapes drawing, so shapes and text can be batched together
|
#if defined(SUPPORT_MODULE_RSHAPES)
|
||||||
// WARNING: rshapes module is required, if not available, default internal white rectangle is used
|
// Set font white rectangle for shapes drawing, so shapes and text can be batched together
|
||||||
Rectangle rec = GetFontDefault().recs[95];
|
// WARNING: rshapes module is required, if not available, default internal white rectangle is used
|
||||||
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
|
Rectangle rec = GetFontDefault().recs[95];
|
||||||
{
|
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
|
||||||
// NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering
|
{
|
||||||
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 });
|
// NOTE: We try to maxime rec padding to avoid pixel bleeding on MSAA filtering
|
||||||
}
|
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 2, rec.y + 2, 1, 1 });
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
// NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding
|
{
|
||||||
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
|
// NOTE: We set up a 1px padding on char rectangle to avoid pixel bleeding
|
||||||
}
|
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#if defined(SUPPORT_MODULE_RSHAPES)
|
#if defined(SUPPORT_MODULE_RSHAPES)
|
||||||
|
|
@ -674,7 +691,7 @@ void InitWindow(int width, int height, const char *title)
|
||||||
|
|
||||||
// Initialize random seed
|
// Initialize random seed
|
||||||
SetRandomSeed((unsigned int)time(NULL));
|
SetRandomSeed((unsigned int)time(NULL));
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
|
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1287,6 +1304,8 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
||||||
// vertex color location = 3
|
// vertex color location = 3
|
||||||
// vertex tangent location = 4
|
// vertex tangent location = 4
|
||||||
// vertex texcoord2 location = 5
|
// vertex texcoord2 location = 5
|
||||||
|
// vertex boneIds location = 6
|
||||||
|
// vertex boneWeights location = 7
|
||||||
|
|
||||||
// NOTE: If any location is not found, loc point becomes -1
|
// NOTE: If any location is not found, loc point becomes -1
|
||||||
|
|
||||||
|
|
@ -1302,6 +1321,8 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
||||||
shader.locs[SHADER_LOC_VERTEX_NORMAL] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL);
|
shader.locs[SHADER_LOC_VERTEX_NORMAL] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL);
|
||||||
shader.locs[SHADER_LOC_VERTEX_TANGENT] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
|
shader.locs[SHADER_LOC_VERTEX_TANGENT] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
|
||||||
shader.locs[SHADER_LOC_VERTEX_COLOR] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
|
shader.locs[SHADER_LOC_VERTEX_COLOR] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
|
||||||
|
shader.locs[SHADER_LOC_VERTEX_BONEIDS] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);
|
||||||
|
shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS);
|
||||||
|
|
||||||
// Get handles to GLSL uniform locations (vertex shader)
|
// Get handles to GLSL uniform locations (vertex shader)
|
||||||
shader.locs[SHADER_LOC_MATRIX_MVP] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP);
|
shader.locs[SHADER_LOC_MATRIX_MVP] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP);
|
||||||
|
|
@ -1309,6 +1330,7 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
||||||
shader.locs[SHADER_LOC_MATRIX_PROJECTION] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION);
|
shader.locs[SHADER_LOC_MATRIX_PROJECTION] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION);
|
||||||
shader.locs[SHADER_LOC_MATRIX_MODEL] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL);
|
shader.locs[SHADER_LOC_MATRIX_MODEL] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL);
|
||||||
shader.locs[SHADER_LOC_MATRIX_NORMAL] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL);
|
shader.locs[SHADER_LOC_MATRIX_NORMAL] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL);
|
||||||
|
shader.locs[SHADER_LOC_BONE_MATRICES] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES);
|
||||||
|
|
||||||
// Get handles to GLSL uniform locations (fragment shader)
|
// Get handles to GLSL uniform locations (fragment shader)
|
||||||
shader.locs[SHADER_LOC_COLOR_DIFFUSE] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR);
|
shader.locs[SHADER_LOC_COLOR_DIFFUSE] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR);
|
||||||
|
|
@ -1320,10 +1342,10 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a shader is ready
|
// Check if a shader is valid (loaded on GPU)
|
||||||
bool IsShaderReady(Shader shader)
|
bool IsShaderValid(Shader shader)
|
||||||
{
|
{
|
||||||
return ((shader.id > 0) && // Validate shader id (loaded successfully)
|
return ((shader.id > 0) && // Validate shader id (GPU loaded successfully)
|
||||||
(shader.locs != NULL)); // Validate memory has been allocated for default shader locations
|
(shader.locs != NULL)); // Validate memory has been allocated for default shader locations
|
||||||
|
|
||||||
// The following locations are tried to be set automatically (locs[i] >= 0),
|
// The following locations are tried to be set automatically (locs[i] >= 0),
|
||||||
|
|
@ -2153,6 +2175,28 @@ const char *GetApplicationDirectory(void)
|
||||||
appDir[0] = '.';
|
appDir[0] = '.';
|
||||||
appDir[1] = '/';
|
appDir[1] = '/';
|
||||||
}
|
}
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
size_t size = sizeof(appDir);
|
||||||
|
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
|
||||||
|
|
||||||
|
if (sysctl(mib, 4, appDir, &size, NULL, 0) == 0)
|
||||||
|
{
|
||||||
|
int len = strlen(appDir);
|
||||||
|
for (int i = len; i >= 0; --i)
|
||||||
|
{
|
||||||
|
if (appDir[i] == '/')
|
||||||
|
{
|
||||||
|
appDir[i + 1] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appDir[0] = '.';
|
||||||
|
appDir[1] = '/';
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return appDir;
|
return appDir;
|
||||||
|
|
@ -2224,6 +2268,40 @@ void UnloadDirectoryFiles(FilePathList files)
|
||||||
RL_FREE(files.paths);
|
RL_FREE(files.paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create directories (including full path requested), returns 0 on success
|
||||||
|
int MakeDirectory(const char *dirPath)
|
||||||
|
{
|
||||||
|
if ((dirPath == NULL) || (dirPath[0] == '\0')) return 1; // Path is not valid
|
||||||
|
if (DirectoryExists(dirPath)) return 0; // Path already exists (is valid)
|
||||||
|
|
||||||
|
// Copy path string to avoid modifying original
|
||||||
|
int len = (int)strlen(dirPath) + 1;
|
||||||
|
char *pathcpy = (char *)RL_CALLOC(len, 1);
|
||||||
|
memcpy(pathcpy, dirPath, len);
|
||||||
|
|
||||||
|
// Iterate over pathcpy, create each subdirectory as needed
|
||||||
|
for (int i = 0; (i < len) && (pathcpy[i] != '\0'); i++)
|
||||||
|
{
|
||||||
|
if (pathcpy[i] == ':') i++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((pathcpy[i] == '\\') || (pathcpy[i] == '/'))
|
||||||
|
{
|
||||||
|
pathcpy[i] = '\0';
|
||||||
|
if (!DirectoryExists(pathcpy)) MKDIR(pathcpy);
|
||||||
|
pathcpy[i] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create final directory
|
||||||
|
if (!DirectoryExists(pathcpy)) MKDIR(pathcpy);
|
||||||
|
|
||||||
|
RL_FREE(pathcpy);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Change working directory, returns true on success
|
// Change working directory, returns true on success
|
||||||
bool ChangeDirectory(const char *dir)
|
bool ChangeDirectory(const char *dir)
|
||||||
{
|
{
|
||||||
|
|
@ -2499,6 +2577,265 @@ unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize)
|
||||||
return decodedData;
|
return decodedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute CRC32 hash code
|
||||||
|
unsigned int ComputeCRC32(unsigned char *data, int dataSize)
|
||||||
|
{
|
||||||
|
static unsigned int crcTable[256] = {
|
||||||
|
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||||
|
0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||||
|
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||||
|
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||||
|
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||||
|
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||||
|
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||||
|
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||||
|
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||||
|
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||||
|
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||||
|
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||||
|
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||||
|
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||||
|
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||||
|
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||||
|
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||||
|
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||||
|
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||||
|
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||||
|
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||||
|
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||||
|
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||||
|
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||||
|
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||||
|
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||||
|
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||||
|
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||||
|
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||||
|
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||||
|
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||||
|
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int crc = ~0u;
|
||||||
|
|
||||||
|
for (int i = 0; i < dataSize; i++) crc = (crc >> 8) ^ crcTable[data[i] ^ (crc & 0xff)];
|
||||||
|
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute MD5 hash code
|
||||||
|
// NOTE: Returns a static int[4] array (16 bytes)
|
||||||
|
unsigned int *ComputeMD5(unsigned char *data, int dataSize)
|
||||||
|
{
|
||||||
|
#define ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
|
||||||
|
|
||||||
|
static unsigned int hash[4] = { 0 }; // Hash to be returned
|
||||||
|
|
||||||
|
// WARNING: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
|
||||||
|
|
||||||
|
// NOTE: r specifies the per-round shift amounts
|
||||||
|
unsigned int r[] = {
|
||||||
|
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||||
|
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||||
|
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||||
|
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
|
||||||
|
};
|
||||||
|
|
||||||
|
// Using binary integer part of the sines of integers (in radians) as constants
|
||||||
|
unsigned int k[] = {
|
||||||
|
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||||
|
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||||
|
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||||
|
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||||
|
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||||
|
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||||
|
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||||
|
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||||
|
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||||
|
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||||
|
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||||
|
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||||
|
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||||
|
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||||
|
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||||
|
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
|
||||||
|
};
|
||||||
|
|
||||||
|
hash[0] = 0x67452301;
|
||||||
|
hash[1] = 0xefcdab89;
|
||||||
|
hash[2] = 0x98badcfe;
|
||||||
|
hash[3] = 0x10325476;
|
||||||
|
|
||||||
|
// Pre-processing: adding a single 1 bit
|
||||||
|
// Append '1' bit to message
|
||||||
|
// NOTE: The input bytes are considered as bits strings,
|
||||||
|
// where the first bit is the most significant bit of the byte
|
||||||
|
|
||||||
|
// Pre-processing: padding with zeros
|
||||||
|
// Append '0' bit until message length in bit 448 (mod 512)
|
||||||
|
// Append length mod (2 pow 64) to message
|
||||||
|
|
||||||
|
int newDataSize = ((((dataSize + 8)/64) + 1)*64) - 8;
|
||||||
|
|
||||||
|
unsigned char *msg = RL_CALLOC(newDataSize + 64, 1); // Initialize with '0' bits, allocating 64 extra bytes
|
||||||
|
memcpy(msg, data, dataSize);
|
||||||
|
msg[dataSize] = 128; // Write the '1' bit
|
||||||
|
|
||||||
|
unsigned int bitsLen = 8*dataSize;
|
||||||
|
memcpy(msg + newDataSize, &bitsLen, 4); // Append the len in bits at the end of the buffer
|
||||||
|
|
||||||
|
// Process the message in successive 512-bit chunks for each 512-bit chunk of message
|
||||||
|
for (int offset = 0; offset < newDataSize; offset += (512/8))
|
||||||
|
{
|
||||||
|
// Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15
|
||||||
|
unsigned int *w = (unsigned int *)(msg + offset);
|
||||||
|
|
||||||
|
// Initialize hash value for this chunk
|
||||||
|
unsigned int a = hash[0];
|
||||||
|
unsigned int b = hash[1];
|
||||||
|
unsigned int c = hash[2];
|
||||||
|
unsigned int d = hash[3];
|
||||||
|
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
unsigned int f = 0;
|
||||||
|
unsigned int g = 0;
|
||||||
|
|
||||||
|
if (i < 16)
|
||||||
|
{
|
||||||
|
f = (b & c) | ((~b) & d);
|
||||||
|
g = i;
|
||||||
|
}
|
||||||
|
else if (i < 32)
|
||||||
|
{
|
||||||
|
f = (d & b) | ((~d) & c);
|
||||||
|
g = (5*i + 1)%16;
|
||||||
|
}
|
||||||
|
else if (i < 48)
|
||||||
|
{
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
g = (3*i + 5)%16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f = c ^ (b | (~d));
|
||||||
|
g = (7*i)%16;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int temp = d;
|
||||||
|
d = c;
|
||||||
|
c = b;
|
||||||
|
b = b + ROTATE_LEFT((a + f + k[i] + w[g]), r[i]);
|
||||||
|
a = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add chunk's hash to result so far
|
||||||
|
hash[0] += a;
|
||||||
|
hash[1] += b;
|
||||||
|
hash[2] += c;
|
||||||
|
hash[3] += d;
|
||||||
|
}
|
||||||
|
|
||||||
|
RL_FREE(msg);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute SHA-1 hash code
|
||||||
|
// NOTE: Returns a static int[5] array (20 bytes)
|
||||||
|
unsigned int *ComputeSHA1(unsigned char *data, int dataSize) {
|
||||||
|
#define ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
|
||||||
|
|
||||||
|
static unsigned int hash[5] = { 0 }; // Hash to be returned
|
||||||
|
|
||||||
|
// Initialize hash values
|
||||||
|
hash[0] = 0x67452301;
|
||||||
|
hash[1] = 0xEFCDAB89;
|
||||||
|
hash[2] = 0x98BADCFE;
|
||||||
|
hash[3] = 0x10325476;
|
||||||
|
hash[4] = 0xC3D2E1F0;
|
||||||
|
|
||||||
|
// Pre-processing: adding a single 1 bit
|
||||||
|
// Append '1' bit to message
|
||||||
|
// NOTE: The input bytes are considered as bits strings,
|
||||||
|
// where the first bit is the most significant bit of the byte
|
||||||
|
|
||||||
|
// Pre-processing: padding with zeros
|
||||||
|
// Append '0' bit until message length in bit 448 (mod 512)
|
||||||
|
// Append length mod (2 pow 64) to message
|
||||||
|
|
||||||
|
int newDataSize = ((((dataSize + 8)/64) + 1)*64);
|
||||||
|
|
||||||
|
unsigned char *msg = RL_CALLOC(newDataSize, 1); // Initialize with '0' bits
|
||||||
|
memcpy(msg, data, dataSize);
|
||||||
|
msg[dataSize] = 128; // Write the '1' bit
|
||||||
|
|
||||||
|
unsigned int bitsLen = 8*dataSize;
|
||||||
|
msg[newDataSize-1] = bitsLen;
|
||||||
|
|
||||||
|
// Process the message in successive 512-bit chunks
|
||||||
|
for (int offset = 0; offset < newDataSize; offset += (512/8))
|
||||||
|
{
|
||||||
|
// Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15
|
||||||
|
unsigned int w[80] = {0};
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
w[i] = (msg[offset + (i * 4) + 0] << 24) |
|
||||||
|
(msg[offset + (i * 4) + 1] << 16) |
|
||||||
|
(msg[offset + (i * 4) + 2] << 8) |
|
||||||
|
(msg[offset + (i * 4) + 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message schedule: extend the sixteen 32-bit words into eighty 32-bit words:
|
||||||
|
for (int i = 16; i < 80; ++i) {
|
||||||
|
w[i] = ROTATE_LEFT(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize hash value for this chunk
|
||||||
|
unsigned int a = hash[0];
|
||||||
|
unsigned int b = hash[1];
|
||||||
|
unsigned int c = hash[2];
|
||||||
|
unsigned int d = hash[3];
|
||||||
|
unsigned int e = hash[4];
|
||||||
|
|
||||||
|
for (int i = 0; i < 80; i++)
|
||||||
|
{
|
||||||
|
unsigned int f = 0;
|
||||||
|
unsigned int k = 0;
|
||||||
|
|
||||||
|
if (i < 20) {
|
||||||
|
f = (b & c) | ((~b) & d);
|
||||||
|
k = 0x5A827999;
|
||||||
|
} else if (i < 40) {
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
k = 0x6ED9EBA1;
|
||||||
|
} else if (i < 60) {
|
||||||
|
f = (b & c) | (b & d) | (c & d);
|
||||||
|
k = 0x8F1BBCDC;
|
||||||
|
} else {
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
k = 0xCA62C1D6;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int temp = ROTATE_LEFT(a, 5) + f + e + k + w[i];
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = ROTATE_LEFT(b, 30);
|
||||||
|
b = a;
|
||||||
|
a = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add this chunk's hash to result so far
|
||||||
|
hash[0] += a;
|
||||||
|
hash[1] += b;
|
||||||
|
hash[2] += c;
|
||||||
|
hash[3] += d;
|
||||||
|
hash[4] += e;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(msg);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition: Automation Events Recording and Playing
|
// Module Functions Definition: Automation Events Recording and Playing
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -3305,10 +3642,21 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
|
||||||
|
|
||||||
if (filter != NULL)
|
if (filter != NULL)
|
||||||
{
|
{
|
||||||
if (IsFileExtension(path, filter))
|
if (IsPathFile(path))
|
||||||
{
|
{
|
||||||
strcpy(files->paths[files->count], path);
|
if (IsFileExtension(path, filter))
|
||||||
files->count++;
|
{
|
||||||
|
strcpy(files->paths[files->count], path);
|
||||||
|
files->count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (TextFindIndex(filter, DIRECTORY_FILTER_TAG) >= 0)
|
||||||
|
{
|
||||||
|
strcpy(files->paths[files->count], path);
|
||||||
|
files->count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -3368,7 +3716,22 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ScanDirectoryFilesRecursively(path, files, filter);
|
else
|
||||||
|
{
|
||||||
|
if ((filter != NULL) && (TextFindIndex(filter, DIRECTORY_FILTER_TAG) >= 0))
|
||||||
|
{
|
||||||
|
strcpy(files->paths[files->count], path);
|
||||||
|
files->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files->count >= files->capacity)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "FILEIO: Maximum filepath scan capacity reached (%i files)", files->capacity);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanDirectoryFilesRecursively(path, files, filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -434,7 +434,7 @@ int GetGestureDetected(void)
|
||||||
return (GESTURES.enabledFlags & GESTURES.current);
|
return (GESTURES.enabledFlags & GESTURES.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hold time measured in ms
|
// Hold time measured in seconds
|
||||||
float GetGestureHoldDuration(void)
|
float GetGestureHoldDuration(void)
|
||||||
{
|
{
|
||||||
// NOTE: time is calculated on current gesture HOLD
|
// NOTE: time is calculated on current gesture HOLD
|
||||||
|
|
@ -517,7 +517,7 @@ static double rgGetCurrentTime(void)
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
unsigned long long int clockFrequency, currentTime;
|
unsigned long long int clockFrequency, currentTime;
|
||||||
|
|
||||||
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
|
QueryPerformanceFrequency(&clockFrequency); // BE CAREFUL: Costly operation!
|
||||||
QueryPerformanceCounter(¤tTime);
|
QueryPerformanceCounter(¤tTime);
|
||||||
|
|
||||||
time = (double)currentTime/clockFrequency; // Time in seconds
|
time = (double)currentTime/clockFrequency; // Time in seconds
|
||||||
|
|
|
||||||
121
src/rlgl.h
121
src/rlgl.h
|
|
@ -68,12 +68,15 @@
|
||||||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
|
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
|
||||||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
|
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
|
||||||
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
|
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
|
||||||
|
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS "vertexBoneIds" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS
|
||||||
|
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
|
||||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
|
||||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
|
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
|
||||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
|
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
|
||||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)))
|
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)))
|
||||||
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
||||||
|
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES "boneMatrices" // bone matrices
|
||||||
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
||||||
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
|
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
|
||||||
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
|
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
|
||||||
|
|
@ -324,22 +327,33 @@
|
||||||
|
|
||||||
// Default shader vertex attribute locations
|
// Default shader vertex attribute locations
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD 1
|
||||||
#endif
|
#endif
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL 2
|
||||||
#endif
|
#endif
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR 3
|
||||||
#endif
|
#endif
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT 4
|
||||||
#endif
|
#endif
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
|
||||||
|
#endif
|
||||||
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
|
||||||
|
#endif
|
||||||
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
|
||||||
|
#endif
|
||||||
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -527,6 +541,10 @@ typedef enum {
|
||||||
RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int)
|
RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int)
|
||||||
RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int)
|
RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int)
|
||||||
RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int)
|
RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int)
|
||||||
|
RL_SHADER_UNIFORM_UINT, // Shader uniform type: unsigned int
|
||||||
|
RL_SHADER_UNIFORM_UIVEC2, // Shader uniform type: uivec2 (2 unsigned int)
|
||||||
|
RL_SHADER_UNIFORM_UIVEC3, // Shader uniform type: uivec3 (3 unsigned int)
|
||||||
|
RL_SHADER_UNIFORM_UIVEC4, // Shader uniform type: uivec4 (4 unsigned int)
|
||||||
RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d
|
RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d
|
||||||
} rlShaderUniformDataType;
|
} rlShaderUniformDataType;
|
||||||
|
|
||||||
|
|
@ -665,7 +683,7 @@ RLAPI void rlDisableScissorTest(void); // Disable scissor test
|
||||||
RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
|
RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
|
||||||
RLAPI void rlEnableWireMode(void); // Enable wire mode
|
RLAPI void rlEnableWireMode(void); // Enable wire mode
|
||||||
RLAPI void rlEnablePointMode(void); // Enable point mode
|
RLAPI void rlEnablePointMode(void); // Enable point mode
|
||||||
RLAPI void rlDisableWireMode(void); // Disable wire mode ( and point ) maybe rename
|
RLAPI void rlDisableWireMode(void); // Disable wire (and point) mode
|
||||||
RLAPI void rlSetLineWidth(float width); // Set the line drawing width
|
RLAPI void rlSetLineWidth(float width); // Set the line drawing width
|
||||||
RLAPI float rlGetLineWidth(void); // Get the line drawing width
|
RLAPI float rlGetLineWidth(void); // Get the line drawing width
|
||||||
RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
|
RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
|
||||||
|
|
@ -755,6 +773,7 @@ RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName);
|
||||||
RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute
|
RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute
|
||||||
RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform
|
RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform
|
||||||
RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix
|
RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix
|
||||||
|
RLAPI void rlSetUniformMatrices(int locIndex, const Matrix *mat, int count); // Set shader value matrices
|
||||||
RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler
|
RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler
|
||||||
RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations)
|
RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations)
|
||||||
|
|
||||||
|
|
@ -973,6 +992,12 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
|
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS "vertexBoneIds" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS
|
||||||
|
#endif
|
||||||
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
|
||||||
|
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
|
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
|
||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
|
||||||
|
|
@ -992,6 +1017,9 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
||||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR
|
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR
|
||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES
|
||||||
|
#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES "boneMatrices" // bone matrices
|
||||||
|
#endif
|
||||||
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0
|
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0
|
||||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1948,6 +1976,7 @@ void rlEnableWireMode(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable point mode
|
||||||
void rlEnablePointMode(void)
|
void rlEnablePointMode(void)
|
||||||
{
|
{
|
||||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||||
|
|
@ -1956,6 +1985,7 @@ void rlEnablePointMode(void)
|
||||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable wire mode
|
// Disable wire mode
|
||||||
void rlDisableWireMode(void)
|
void rlDisableWireMode(void)
|
||||||
{
|
{
|
||||||
|
|
@ -2442,25 +2472,47 @@ void rlLoadExtensions(void *loader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check instanced rendering support
|
// Check instanced rendering support
|
||||||
if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // Web ANGLE
|
if (strstr(extList[i], (const char*)"instanced_arrays") != NULL) // Broad check for instanced_arrays
|
||||||
{
|
{
|
||||||
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE");
|
// Specific check
|
||||||
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE");
|
if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // ANGLE
|
||||||
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE");
|
{
|
||||||
|
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE");
|
||||||
if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
|
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE");
|
||||||
}
|
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE");
|
||||||
else
|
}
|
||||||
{
|
else if (strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0) // EXT
|
||||||
if ((strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0) && // Standard EXT
|
|
||||||
(strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0))
|
|
||||||
{
|
{
|
||||||
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT");
|
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT");
|
||||||
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT");
|
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT");
|
||||||
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT");
|
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT");
|
||||||
|
|
||||||
if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
|
|
||||||
}
|
}
|
||||||
|
else if (strcmp(extList[i], (const char *)"GL_NV_instanced_arrays") == 0) // NVIDIA GLES
|
||||||
|
{
|
||||||
|
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedNV");
|
||||||
|
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedNV");
|
||||||
|
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorNV");
|
||||||
|
}
|
||||||
|
|
||||||
|
// The feature will only be marked as supported if the elements from GL_XXX_instanced_arrays are present
|
||||||
|
if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
|
||||||
|
}
|
||||||
|
else if (strstr(extList[i], (const char *)"draw_instanced") != NULL)
|
||||||
|
{
|
||||||
|
// GL_ANGLE_draw_instanced doesn't exist
|
||||||
|
if (strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0)
|
||||||
|
{
|
||||||
|
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT");
|
||||||
|
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT");
|
||||||
|
}
|
||||||
|
else if (strcmp(extList[i], (const char*)"GL_NV_draw_instanced") == 0)
|
||||||
|
{
|
||||||
|
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedNV");
|
||||||
|
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedNV");
|
||||||
|
}
|
||||||
|
|
||||||
|
// But the functions will at least be loaded if only GL_XX_EXT_draw_instanced exist
|
||||||
|
if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check NPOT textures support
|
// Check NPOT textures support
|
||||||
|
|
@ -4143,6 +4195,11 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
|
||||||
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
|
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
|
||||||
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
|
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
|
||||||
|
|
||||||
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);
|
||||||
|
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS);
|
||||||
|
#endif
|
||||||
|
|
||||||
// NOTE: If some attrib name is no found on the shader, it locations becomes -1
|
// NOTE: If some attrib name is no found on the shader, it locations becomes -1
|
||||||
|
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
@ -4234,8 +4291,16 @@ void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
|
||||||
case RL_SHADER_UNIFORM_IVEC2: glUniform2iv(locIndex, count, (int *)value); break;
|
case RL_SHADER_UNIFORM_IVEC2: glUniform2iv(locIndex, count, (int *)value); break;
|
||||||
case RL_SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break;
|
case RL_SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break;
|
||||||
case RL_SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break;
|
case RL_SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break;
|
||||||
|
#if !defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
case RL_SHADER_UNIFORM_UINT: glUniform1uiv(locIndex, count, (unsigned int *)value); break;
|
||||||
|
case RL_SHADER_UNIFORM_UIVEC2: glUniform2uiv(locIndex, count, (unsigned int *)value); break;
|
||||||
|
case RL_SHADER_UNIFORM_UIVEC3: glUniform3uiv(locIndex, count, (unsigned int *)value); break;
|
||||||
|
case RL_SHADER_UNIFORM_UIVEC4: glUniform4uiv(locIndex, count, (unsigned int *)value); break;
|
||||||
|
#endif
|
||||||
case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break;
|
case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break;
|
||||||
default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized");
|
default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized");
|
||||||
|
|
||||||
|
// TODO: Support glUniform1uiv(), glUniform2uiv(), glUniform3uiv(), glUniform4uiv()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -4269,6 +4334,14 @@ void rlSetUniformMatrix(int locIndex, Matrix mat)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set shader value uniform matrix
|
||||||
|
void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count)
|
||||||
|
{
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
glUniformMatrix4fv(locIndex, count, true, (const float*)matrices);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Set shader value uniform sampler
|
// Set shader value uniform sampler
|
||||||
void rlSetUniformSampler(int locIndex, unsigned int textureId)
|
void rlSetUniformSampler(int locIndex, unsigned int textureId)
|
||||||
{
|
{
|
||||||
|
|
@ -4410,14 +4483,14 @@ void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSi
|
||||||
// Get SSBO buffer size
|
// Get SSBO buffer size
|
||||||
unsigned int rlGetShaderBufferSize(unsigned int id)
|
unsigned int rlGetShaderBufferSize(unsigned int id)
|
||||||
{
|
{
|
||||||
GLint64 size = 0;
|
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_43)
|
#if defined(GRAPHICS_API_OPENGL_43)
|
||||||
|
GLint64 size = 0;
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
|
||||||
glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size);
|
glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size);
|
||||||
#endif
|
|
||||||
|
|
||||||
return (size > 0)? (unsigned int)size : 0;
|
return (size > 0)? (unsigned int)size : 0;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read SSBO buffer data (GPU->CPU)
|
// Read SSBO buffer data (GPU->CPU)
|
||||||
|
|
|
||||||
640
src/rmodels.c
640
src/rmodels.c
|
|
@ -130,7 +130,7 @@
|
||||||
#define MAX_MATERIAL_MAPS 12 // Maximum number of maps supported
|
#define MAX_MATERIAL_MAPS 12 // Maximum number of maps supported
|
||||||
#endif
|
#endif
|
||||||
#ifndef MAX_MESH_VERTEX_BUFFERS
|
#ifndef MAX_MESH_VERTEX_BUFFERS
|
||||||
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
|
#define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -426,14 +426,14 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
// Basic implementation, do not use it!
|
// Basic implementation, do not use it!
|
||||||
// For a sphere with 16 rings and 16 slices it requires 8640 cos()/sin() function calls!
|
// For a sphere with 16 rings and 16 slices it requires 8640 cos()/sin() function calls!
|
||||||
// New optimized version below only requires 4 cos()/sin() calls
|
// New optimized version below only requires 4 cos()/sin() calls
|
||||||
|
|
||||||
rlPushMatrix();
|
rlPushMatrix();
|
||||||
// NOTE: Transformation is applied in inverse order (scale -> translate)
|
// NOTE: Transformation is applied in inverse order (scale -> translate)
|
||||||
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
rlTranslatef(centerPos.x, centerPos.y, centerPos.z);
|
||||||
rlScalef(radius, radius, radius);
|
rlScalef(radius, radius, radius);
|
||||||
|
|
||||||
rlBegin(RL_TRIANGLES);
|
rlBegin(RL_TRIANGLES);
|
||||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
|
|
@ -488,7 +488,7 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
|
||||||
|
|
||||||
for (int i = 0; i < rings + 1; i++)
|
for (int i = 0; i < rings + 1; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < slices; j++)
|
for (int j = 0; j < slices; j++)
|
||||||
{
|
{
|
||||||
vertices[0] = vertices[2]; // Rotate around y axis to set up vertices for next face
|
vertices[0] = vertices[2]; // Rotate around y axis to set up vertices for next face
|
||||||
vertices[1] = vertices[3];
|
vertices[1] = vertices[3];
|
||||||
|
|
@ -702,7 +702,6 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
|
||||||
rlPopMatrix();
|
rlPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Draw a wired cylinder with base at startPos and top at endPos
|
// Draw a wired cylinder with base at startPos and top at endPos
|
||||||
// NOTE: It could be also used for pyramid and cone
|
// NOTE: It could be also used for pyramid and cone
|
||||||
void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color)
|
void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color)
|
||||||
|
|
@ -1156,8 +1155,8 @@ Model LoadModelFromMesh(Mesh mesh)
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a model is ready
|
// Check if a model is valid (loaded in GPU, VAO/VBOs)
|
||||||
bool IsModelReady(Model model)
|
bool IsModelValid(Model model)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
|
@ -1167,7 +1166,23 @@ bool IsModelReady(Model model)
|
||||||
(model.meshCount > 0) && // Validate mesh count
|
(model.meshCount > 0) && // Validate mesh count
|
||||||
(model.materialCount > 0)) result = true; // Validate material count
|
(model.materialCount > 0)) result = true; // Validate material count
|
||||||
|
|
||||||
// NOTE: This is a very general model validation, many elements could be validated from a model...
|
// NOTE: Many elements could be validated from a model, including every model mesh VAO/VBOs
|
||||||
|
// but some VBOs could not be used, it depends on Mesh vertex data
|
||||||
|
for (int i = 0; i < model.meshCount; i++)
|
||||||
|
{
|
||||||
|
if ((model.meshes[i].vertices != NULL) && (model.meshes[i].vboId[0] == 0)) { result = false; break; } // Vertex position buffer not uploaded to GPU
|
||||||
|
if ((model.meshes[i].texcoords != NULL) && (model.meshes[i].vboId[1] == 0)) { result = false; break; } // Vertex textcoords buffer not uploaded to GPU
|
||||||
|
if ((model.meshes[i].normals != NULL) && (model.meshes[i].vboId[2] == 0)) { result = false; break; } // Vertex normals buffer not uploaded to GPU
|
||||||
|
if ((model.meshes[i].colors != NULL) && (model.meshes[i].vboId[3] == 0)) { result = false; break; } // Vertex colors buffer not uploaded to GPU
|
||||||
|
if ((model.meshes[i].tangents != NULL) && (model.meshes[i].vboId[4] == 0)) { result = false; break; } // Vertex tangents buffer not uploaded to GPU
|
||||||
|
if ((model.meshes[i].texcoords2 != NULL) && (model.meshes[i].vboId[5] == 0)) { result = false; break; } // Vertex texcoords2 buffer not uploaded to GPU
|
||||||
|
if ((model.meshes[i].indices != NULL) && (model.meshes[i].vboId[6] == 0)) { result = false; break; } // Vertex indices buffer not uploaded to GPU
|
||||||
|
if ((model.meshes[i].boneIds != NULL) && (model.meshes[i].vboId[7] == 0)) { result = false; break; } // Vertex boneIds buffer not uploaded to GPU
|
||||||
|
if ((model.meshes[i].boneWeights != NULL) && (model.meshes[i].vboId[8] == 0)) { result = false; break; } // Vertex boneWeights buffer not uploaded to GPU
|
||||||
|
|
||||||
|
// NOTE: Some OpenGL versions do not support VAO, so we don't check it
|
||||||
|
//if (model.meshes[i].vaoId == 0) { result = false; break }
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -1246,13 +1261,18 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
mesh->vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
|
mesh->vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
|
||||||
|
|
||||||
mesh->vaoId = 0; // Vertex Array Object
|
mesh->vaoId = 0; // Vertex Array Object
|
||||||
mesh->vboId[0] = 0; // Vertex buffer: positions
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION] = 0; // Vertex buffer: positions
|
||||||
mesh->vboId[1] = 0; // Vertex buffer: texcoords
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD] = 0; // Vertex buffer: texcoords
|
||||||
mesh->vboId[2] = 0; // Vertex buffer: normals
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL] = 0; // Vertex buffer: normals
|
||||||
mesh->vboId[3] = 0; // Vertex buffer: colors
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR] = 0; // Vertex buffer: colors
|
||||||
mesh->vboId[4] = 0; // Vertex buffer: tangents
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT] = 0; // Vertex buffer: tangents
|
||||||
mesh->vboId[5] = 0; // Vertex buffer: texcoords2
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2] = 0; // Vertex buffer: texcoords2
|
||||||
mesh->vboId[6] = 0; // Vertex buffer: indices
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES] = 0; // Vertex buffer: indices
|
||||||
|
|
||||||
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS] = 0; // Vertex buffer: boneIds
|
||||||
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS] = 0; // Vertex buffer: boneWeights
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
mesh->vaoId = rlLoadVertexArray();
|
mesh->vaoId = rlLoadVertexArray();
|
||||||
|
|
@ -1262,12 +1282,12 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
|
|
||||||
// Enable vertex attributes: position (shader-location = 0)
|
// Enable vertex attributes: position (shader-location = 0)
|
||||||
void *vertices = (mesh->animVertices != NULL)? mesh->animVertices : mesh->vertices;
|
void *vertices = (mesh->animVertices != NULL)? mesh->animVertices : mesh->vertices;
|
||||||
mesh->vboId[0] = rlLoadVertexBuffer(vertices, mesh->vertexCount*3*sizeof(float), dynamic);
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION] = rlLoadVertexBuffer(vertices, mesh->vertexCount*3*sizeof(float), dynamic);
|
||||||
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION);
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION);
|
||||||
|
|
||||||
// Enable vertex attributes: texcoords (shader-location = 1)
|
// Enable vertex attributes: texcoords (shader-location = 1)
|
||||||
mesh->vboId[1] = rlLoadVertexBuffer(mesh->texcoords, mesh->vertexCount*2*sizeof(float), dynamic);
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD] = rlLoadVertexBuffer(mesh->texcoords, mesh->vertexCount*2*sizeof(float), dynamic);
|
||||||
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, 2, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD);
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD);
|
||||||
|
|
||||||
|
|
@ -1278,7 +1298,7 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
{
|
{
|
||||||
// Enable vertex attributes: normals (shader-location = 2)
|
// Enable vertex attributes: normals (shader-location = 2)
|
||||||
void *normals = (mesh->animNormals != NULL)? mesh->animNormals : mesh->normals;
|
void *normals = (mesh->animNormals != NULL)? mesh->animNormals : mesh->normals;
|
||||||
mesh->vboId[2] = rlLoadVertexBuffer(normals, mesh->vertexCount*3*sizeof(float), dynamic);
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL] = rlLoadVertexBuffer(normals, mesh->vertexCount*3*sizeof(float), dynamic);
|
||||||
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL);
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
@ -1294,7 +1314,7 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
if (mesh->colors != NULL)
|
if (mesh->colors != NULL)
|
||||||
{
|
{
|
||||||
// Enable vertex attribute: color (shader-location = 3)
|
// Enable vertex attribute: color (shader-location = 3)
|
||||||
mesh->vboId[3] = rlLoadVertexBuffer(mesh->colors, mesh->vertexCount*4*sizeof(unsigned char), dynamic);
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR] = rlLoadVertexBuffer(mesh->colors, mesh->vertexCount*4*sizeof(unsigned char), dynamic);
|
||||||
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, 4, RL_UNSIGNED_BYTE, 1, 0, 0);
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, 4, RL_UNSIGNED_BYTE, 1, 0, 0);
|
||||||
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR);
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR);
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1330,7 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
if (mesh->tangents != NULL)
|
if (mesh->tangents != NULL)
|
||||||
{
|
{
|
||||||
// Enable vertex attribute: tangent (shader-location = 4)
|
// Enable vertex attribute: tangent (shader-location = 4)
|
||||||
mesh->vboId[4] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), dynamic);
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), dynamic);
|
||||||
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, 4, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, 4, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT);
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT);
|
||||||
}
|
}
|
||||||
|
|
@ -1326,7 +1346,7 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
if (mesh->texcoords2 != NULL)
|
if (mesh->texcoords2 != NULL)
|
||||||
{
|
{
|
||||||
// Enable vertex attribute: texcoord2 (shader-location = 5)
|
// Enable vertex attribute: texcoord2 (shader-location = 5)
|
||||||
mesh->vboId[5] = rlLoadVertexBuffer(mesh->texcoords2, mesh->vertexCount*2*sizeof(float), dynamic);
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2] = rlLoadVertexBuffer(mesh->texcoords2, mesh->vertexCount*2*sizeof(float), dynamic);
|
||||||
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, 2, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2);
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2);
|
||||||
}
|
}
|
||||||
|
|
@ -1339,9 +1359,43 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2);
|
rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
if (mesh->boneIds != NULL)
|
||||||
|
{
|
||||||
|
// Enable vertex attribute: boneIds (shader-location = 7)
|
||||||
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS] = rlLoadVertexBuffer(mesh->boneIds, mesh->vertexCount*4*sizeof(unsigned char), dynamic);
|
||||||
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, 4, RL_UNSIGNED_BYTE, 0, 0, 0);
|
||||||
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Default vertex attribute: boneIds
|
||||||
|
// WARNING: Default value provided to shader if location available
|
||||||
|
float value[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
|
rlSetVertexAttributeDefault(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, value, SHADER_ATTRIB_VEC4, 4);
|
||||||
|
rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh->boneWeights != NULL)
|
||||||
|
{
|
||||||
|
// Enable vertex attribute: boneWeights (shader-location = 8)
|
||||||
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS] = rlLoadVertexBuffer(mesh->boneWeights, mesh->vertexCount*4*sizeof(float), dynamic);
|
||||||
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, 4, RL_FLOAT, 0, 0, 0);
|
||||||
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Default vertex attribute: boneWeights
|
||||||
|
// WARNING: Default value provided to shader if location available
|
||||||
|
float value[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
|
rlSetVertexAttributeDefault(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, value, SHADER_ATTRIB_VEC4, 2);
|
||||||
|
rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mesh->indices != NULL)
|
if (mesh->indices != NULL)
|
||||||
{
|
{
|
||||||
mesh->vboId[6] = rlLoadVertexBufferElement(mesh->indices, mesh->triangleCount*3*sizeof(unsigned short), dynamic);
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES] = rlLoadVertexBufferElement(mesh->indices, mesh->triangleCount*3*sizeof(unsigned short), dynamic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh->vaoId > 0) TRACELOG(LOG_INFO, "VAO: [ID %i] Mesh uploaded successfully to VRAM (GPU)", mesh->vaoId);
|
if (mesh->vaoId > 0) TRACELOG(LOG_INFO, "VAO: [ID %i] Mesh uploaded successfully to VRAM (GPU)", mesh->vaoId);
|
||||||
|
|
@ -1451,6 +1505,14 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
|
|
||||||
// Upload model normal matrix (if locations available)
|
// Upload model normal matrix (if locations available)
|
||||||
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
|
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
|
||||||
|
|
||||||
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
// Upload Bone Transforms
|
||||||
|
if (material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1 && mesh.boneMatrices)
|
||||||
|
{
|
||||||
|
rlSetUniformMatrices(material.shader.locs[SHADER_LOC_BONE_MATRICES], mesh.boneMatrices, mesh.boneCount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
// Bind active texture maps (if available)
|
// Bind active texture maps (if available)
|
||||||
|
|
@ -1478,19 +1540,19 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
if (!rlEnableVertexArray(mesh.vaoId))
|
if (!rlEnableVertexArray(mesh.vaoId))
|
||||||
{
|
{
|
||||||
// Bind mesh VBO data: vertex position (shader-location = 0)
|
// Bind mesh VBO data: vertex position (shader-location = 0)
|
||||||
rlEnableVertexBuffer(mesh.vboId[0]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
||||||
rlEnableVertexBuffer(mesh.vboId[1]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
|
||||||
|
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
|
if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
|
||||||
{
|
{
|
||||||
// Bind mesh VBO data: vertex normals (shader-location = 2)
|
// Bind mesh VBO data: vertex normals (shader-location = 2)
|
||||||
rlEnableVertexBuffer(mesh.vboId[2]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
|
||||||
}
|
}
|
||||||
|
|
@ -1498,9 +1560,9 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
// Bind mesh VBO data: vertex colors (shader-location = 3, if available)
|
// Bind mesh VBO data: vertex colors (shader-location = 3, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
|
if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
|
||||||
{
|
{
|
||||||
if (mesh.vboId[3] != 0)
|
if (mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR] != 0)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[3]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
|
||||||
}
|
}
|
||||||
|
|
@ -1517,7 +1579,7 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
|
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
|
if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[4]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
|
||||||
}
|
}
|
||||||
|
|
@ -1525,12 +1587,30 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
|
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
|
if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[5]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
// Bind mesh VBO data: vertex bone ids (shader-location = 6, if available)
|
||||||
|
if (material.shader.locs[SHADER_LOC_VERTEX_BONEIDS] != -1)
|
||||||
|
{
|
||||||
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS]);
|
||||||
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEIDS], 4, RL_UNSIGNED_BYTE, 0, 0, 0);
|
||||||
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEIDS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind mesh VBO data: vertex bone weights (shader-location = 7, if available)
|
||||||
|
if (material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS] != -1)
|
||||||
|
{
|
||||||
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS]);
|
||||||
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS], 4, RL_FLOAT, 0, 0, 0);
|
||||||
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int eyeCount = 1;
|
int eyeCount = 1;
|
||||||
|
|
@ -1671,6 +1751,15 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
|
|
||||||
// Upload model normal matrix (if locations available)
|
// Upload model normal matrix (if locations available)
|
||||||
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
|
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
|
||||||
|
|
||||||
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
// Upload Bone Transforms
|
||||||
|
if (material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1 && mesh.boneMatrices)
|
||||||
|
{
|
||||||
|
rlSetUniformMatrices(material.shader.locs[SHADER_LOC_BONE_MATRICES], mesh.boneMatrices, mesh.boneCount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
||||||
// Bind active texture maps (if available)
|
// Bind active texture maps (if available)
|
||||||
|
|
@ -1696,19 +1785,19 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
if (!rlEnableVertexArray(mesh.vaoId))
|
if (!rlEnableVertexArray(mesh.vaoId))
|
||||||
{
|
{
|
||||||
// Bind mesh VBO data: vertex position (shader-location = 0)
|
// Bind mesh VBO data: vertex position (shader-location = 0)
|
||||||
rlEnableVertexBuffer(mesh.vboId[0]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
||||||
rlEnableVertexBuffer(mesh.vboId[1]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
|
||||||
|
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
|
if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
|
||||||
{
|
{
|
||||||
// Bind mesh VBO data: vertex normals (shader-location = 2)
|
// Bind mesh VBO data: vertex normals (shader-location = 2)
|
||||||
rlEnableVertexBuffer(mesh.vboId[2]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
|
||||||
}
|
}
|
||||||
|
|
@ -1716,9 +1805,9 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
// Bind mesh VBO data: vertex colors (shader-location = 3, if available)
|
// Bind mesh VBO data: vertex colors (shader-location = 3, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
|
if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
|
||||||
{
|
{
|
||||||
if (mesh.vboId[3] != 0)
|
if (mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR] != 0)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[3]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
|
||||||
}
|
}
|
||||||
|
|
@ -1735,7 +1824,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
|
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
|
if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[4]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
|
||||||
}
|
}
|
||||||
|
|
@ -1743,12 +1832,30 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
|
||||||
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
|
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
|
||||||
if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
|
if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
|
||||||
{
|
{
|
||||||
rlEnableVertexBuffer(mesh.vboId[5]);
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
|
// Bind mesh VBO data: vertex bone ids (shader-location = 6, if available)
|
||||||
|
if (material.shader.locs[SHADER_LOC_VERTEX_BONEIDS] != -1)
|
||||||
|
{
|
||||||
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS]);
|
||||||
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEIDS], 4, RL_UNSIGNED_BYTE, 0, 0, 0);
|
||||||
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEIDS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind mesh VBO data: vertex bone weights (shader-location = 7, if available)
|
||||||
|
if (material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS] != -1)
|
||||||
|
{
|
||||||
|
rlEnableVertexBuffer(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS]);
|
||||||
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS], 4, RL_FLOAT, 0, 0, 0);
|
||||||
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int eyeCount = 1;
|
int eyeCount = 1;
|
||||||
|
|
@ -1825,6 +1932,7 @@ void UnloadMesh(Mesh mesh)
|
||||||
RL_FREE(mesh.animNormals);
|
RL_FREE(mesh.animNormals);
|
||||||
RL_FREE(mesh.boneWeights);
|
RL_FREE(mesh.boneWeights);
|
||||||
RL_FREE(mesh.boneIds);
|
RL_FREE(mesh.boneIds);
|
||||||
|
RL_FREE(mesh.boneMatrices);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export mesh data to file
|
// Export mesh data to file
|
||||||
|
|
@ -2004,7 +2112,6 @@ bool ExportMeshAsCode(Mesh mesh, const char *fileName)
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)
|
#if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)
|
||||||
// Process obj materials
|
// Process obj materials
|
||||||
static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, int materialCount)
|
static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, int materialCount)
|
||||||
|
|
@ -2016,6 +2123,8 @@ static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, i
|
||||||
// NOTE: Uses default shader, which only supports MATERIAL_MAP_DIFFUSE
|
// NOTE: Uses default shader, which only supports MATERIAL_MAP_DIFFUSE
|
||||||
materials[m] = LoadMaterialDefault();
|
materials[m] = LoadMaterialDefault();
|
||||||
|
|
||||||
|
if (mats == NULL) continue;
|
||||||
|
|
||||||
// Get default texture, in case no texture is defined
|
// Get default texture, in case no texture is defined
|
||||||
// NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
|
// NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
|
||||||
materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = (Texture2D){ rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = (Texture2D){ rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
||||||
|
|
@ -2089,14 +2198,16 @@ Material LoadMaterialDefault(void)
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a material is ready
|
// Check if a material is valid (map textures loaded in GPU)
|
||||||
bool IsMaterialReady(Material material)
|
bool IsMaterialValid(Material material)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if ((material.maps != NULL) && // Validate material contain some map
|
if ((material.maps != NULL) && // Validate material contain some map
|
||||||
(material.shader.id > 0)) result = true; // Validate material shader is valid
|
(material.shader.id > 0)) result = true; // Validate material shader is valid
|
||||||
|
|
||||||
|
// TODO: Check if available maps contain loaded textures
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2253,6 +2364,50 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateModelAnimationBoneMatrices(Model model, ModelAnimation anim, int frame)
|
||||||
|
{
|
||||||
|
if ((anim.frameCount > 0) && (anim.bones != NULL) && (anim.framePoses != NULL))
|
||||||
|
{
|
||||||
|
if (frame >= anim.frameCount) frame = frame%anim.frameCount;
|
||||||
|
|
||||||
|
for (int i = 0; i < model.meshCount; i++)
|
||||||
|
{
|
||||||
|
if (model.meshes[i].boneMatrices)
|
||||||
|
{
|
||||||
|
assert(model.meshes[i].boneCount == anim.boneCount);
|
||||||
|
|
||||||
|
for (int boneId = 0; boneId < model.meshes[i].boneCount; boneId++)
|
||||||
|
{
|
||||||
|
Vector3 inTranslation = model.bindPose[boneId].translation;
|
||||||
|
Quaternion inRotation = model.bindPose[boneId].rotation;
|
||||||
|
Vector3 inScale = model.bindPose[boneId].scale;
|
||||||
|
|
||||||
|
Vector3 outTranslation = anim.framePoses[frame][boneId].translation;
|
||||||
|
Quaternion outRotation = anim.framePoses[frame][boneId].rotation;
|
||||||
|
Vector3 outScale = anim.framePoses[frame][boneId].scale;
|
||||||
|
|
||||||
|
Vector3 invTranslation = Vector3RotateByQuaternion(Vector3Negate(inTranslation), QuaternionInvert(inRotation));
|
||||||
|
Quaternion invRotation = QuaternionInvert(inRotation);
|
||||||
|
Vector3 invScale = Vector3Divide((Vector3){ 1.0f, 1.0f, 1.0f }, inScale);
|
||||||
|
|
||||||
|
Vector3 boneTranslation = Vector3Add(
|
||||||
|
Vector3RotateByQuaternion(Vector3Multiply(outScale, invTranslation),
|
||||||
|
outRotation), outTranslation);
|
||||||
|
Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation);
|
||||||
|
Vector3 boneScale = Vector3Multiply(outScale, invScale);
|
||||||
|
|
||||||
|
Matrix boneMatrix = MatrixMultiply(MatrixMultiply(
|
||||||
|
QuaternionToMatrix(boneRotation),
|
||||||
|
MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)),
|
||||||
|
MatrixScale(boneScale.x, boneScale.y, boneScale.z));
|
||||||
|
|
||||||
|
model.meshes[i].boneMatrices[boneId] = boneMatrix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Unload animation array data
|
// Unload animation array data
|
||||||
void UnloadModelAnimations(ModelAnimation *animations, int animCount)
|
void UnloadModelAnimations(ModelAnimation *animations, int animCount)
|
||||||
{
|
{
|
||||||
|
|
@ -3631,6 +3786,30 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float
|
||||||
rlDisableWireMode();
|
rlDisableWireMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw a model points
|
||||||
|
void DrawModelPoints(Model model, Vector3 position, float scale, Color tint)
|
||||||
|
{
|
||||||
|
rlEnablePointMode();
|
||||||
|
rlDisableBackfaceCulling();
|
||||||
|
|
||||||
|
DrawModel(model, position, scale, tint);
|
||||||
|
|
||||||
|
rlEnableBackfaceCulling();
|
||||||
|
rlDisableWireMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a model points
|
||||||
|
void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||||
|
{
|
||||||
|
rlEnablePointMode();
|
||||||
|
rlDisableBackfaceCulling();
|
||||||
|
|
||||||
|
DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
|
||||||
|
|
||||||
|
rlEnableBackfaceCulling();
|
||||||
|
rlDisableWireMode();
|
||||||
|
}
|
||||||
|
|
||||||
// Draw a billboard
|
// Draw a billboard
|
||||||
void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint)
|
void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint)
|
||||||
{
|
{
|
||||||
|
|
@ -4049,130 +4228,236 @@ static void BuildPoseFromParentJoints(BoneInfo *bones, int boneCount, Transform
|
||||||
// - the mesh is automatically triangulated by tinyobj
|
// - the mesh is automatically triangulated by tinyobj
|
||||||
static Model LoadOBJ(const char *fileName)
|
static Model LoadOBJ(const char *fileName)
|
||||||
{
|
{
|
||||||
|
tinyobj_attrib_t objAttributes = { 0 };
|
||||||
|
tinyobj_shape_t* objShapes = NULL;
|
||||||
|
unsigned int objShapeCount = 0;
|
||||||
|
|
||||||
|
tinyobj_material_t* objMaterials = NULL;
|
||||||
|
unsigned int objMaterialCount = 0;
|
||||||
|
|
||||||
Model model = { 0 };
|
Model model = { 0 };
|
||||||
|
model.transform = MatrixIdentity();
|
||||||
|
|
||||||
tinyobj_attrib_t attrib = { 0 };
|
char* fileText = LoadFileText(fileName);
|
||||||
tinyobj_shape_t *meshes = NULL;
|
|
||||||
unsigned int meshCount = 0;
|
|
||||||
|
|
||||||
tinyobj_material_t *materials = NULL;
|
if (fileText == NULL)
|
||||||
unsigned int materialCount = 0;
|
|
||||||
|
|
||||||
char *fileText = LoadFileText(fileName);
|
|
||||||
|
|
||||||
if (fileText != NULL)
|
|
||||||
{
|
{
|
||||||
unsigned int dataSize = (unsigned int)strlen(fileText);
|
TRACELOG(LOG_ERROR, "MODEL Unable to read obj file %s", fileName);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
char currentDir[1024] = { 0 };
|
char currentDir[1024] = { 0 };
|
||||||
strcpy(currentDir, GetWorkingDirectory()); // Save current working directory
|
strcpy(currentDir, GetWorkingDirectory()); // Save current working directory
|
||||||
const char *workingDir = GetDirectoryPath(fileName); // Switch to OBJ directory for material path correctness
|
const char* workingDir = GetDirectoryPath(fileName); // Switch to OBJ directory for material path correctness
|
||||||
if (CHDIR(workingDir) != 0)
|
if (CHDIR(workingDir) != 0)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int dataSize = (unsigned int)strlen(fileText);
|
||||||
|
|
||||||
|
unsigned int flags = TINYOBJ_FLAG_TRIANGULATE;
|
||||||
|
int ret = tinyobj_parse_obj(&objAttributes, &objShapes, &objShapeCount, &objMaterials, &objMaterialCount, fileText, dataSize, flags);
|
||||||
|
|
||||||
|
if (ret != TINYOBJ_SUCCESS)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_ERROR, "MODEL Unable to read obj data %s", fileName);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnloadFileText(fileText);
|
||||||
|
|
||||||
|
unsigned int faceVertIndex = 0;
|
||||||
|
unsigned int nextShape = 1;
|
||||||
|
int lastMaterial = -1;
|
||||||
|
unsigned int meshIndex = 0;
|
||||||
|
|
||||||
|
// count meshes
|
||||||
|
unsigned int nextShapeEnd = objAttributes.num_face_num_verts;
|
||||||
|
|
||||||
|
// see how many verts till the next shape
|
||||||
|
|
||||||
|
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
|
||||||
|
|
||||||
|
// walk all the faces
|
||||||
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
||||||
|
{
|
||||||
|
if (faceVertIndex >= nextShapeEnd)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir);
|
// try to find the last vert in the next shape
|
||||||
|
nextShape++;
|
||||||
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
||||||
|
else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
|
||||||
|
meshIndex++;
|
||||||
|
}
|
||||||
|
else if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial)
|
||||||
|
{
|
||||||
|
meshIndex++;// if this is a new material, we need to allocate a new mesh
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int flags = TINYOBJ_FLAG_TRIANGULATE;
|
lastMaterial = objAttributes.material_ids[faceId];
|
||||||
int ret = tinyobj_parse_obj(&attrib, &meshes, &meshCount, &materials, &materialCount, fileText, dataSize, flags);
|
faceVertIndex += objAttributes.face_num_verts[faceId];
|
||||||
|
}
|
||||||
|
|
||||||
if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load OBJ data", fileName);
|
// allocate the base meshes and materials
|
||||||
else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes/%i materials", fileName, meshCount, materialCount);
|
model.meshCount = meshIndex + 1;
|
||||||
|
model.meshes = (Mesh*)MemAlloc(sizeof(Mesh) * model.meshCount);
|
||||||
|
|
||||||
// WARNING: We are not splitting meshes by materials (previous implementation)
|
if (objMaterialCount > 0)
|
||||||
// Depending on the provided OBJ that was not the best option and it just crashed
|
{
|
||||||
// so, implementation was simplified to prioritize parsed meshes
|
model.materialCount = objMaterialCount;
|
||||||
model.meshCount = meshCount;
|
model.materials = (Material*)MemAlloc(sizeof(Material) * objMaterialCount);
|
||||||
|
}
|
||||||
|
else // we must allocate at least one material
|
||||||
|
{
|
||||||
|
model.materialCount = 1;
|
||||||
|
model.materials = (Material*)MemAlloc(sizeof(Material) * 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Set number of materials available
|
model.meshMaterial = (int*)MemAlloc(sizeof(int) * model.meshCount);
|
||||||
// NOTE: There could be more materials available than meshes but it will be resolved at
|
|
||||||
// model.meshMaterial, just assigning the right material to corresponding mesh
|
// see how many verts are in each mesh
|
||||||
model.materialCount = materialCount;
|
unsigned int* localMeshVertexCounts = (unsigned int*)MemAlloc(sizeof(unsigned int) * model.meshCount);
|
||||||
if (model.materialCount == 0)
|
|
||||||
|
faceVertIndex = 0;
|
||||||
|
nextShapeEnd = objAttributes.num_face_num_verts;
|
||||||
|
lastMaterial = -1;
|
||||||
|
meshIndex = 0;
|
||||||
|
unsigned int localMeshVertexCount = 0;
|
||||||
|
|
||||||
|
nextShape = 1;
|
||||||
|
if (objShapeCount > 1)
|
||||||
|
nextShapeEnd = objShapes[nextShape].face_offset;
|
||||||
|
|
||||||
|
// walk all the faces
|
||||||
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
||||||
|
{
|
||||||
|
bool newMesh = false; // do we need a new mesh?
|
||||||
|
if (faceVertIndex >= nextShapeEnd)
|
||||||
{
|
{
|
||||||
model.materialCount = 1;
|
// try to find the last vert in the next shape
|
||||||
TRACELOG(LOG_INFO, "MODEL: No materials provided, setting one default material for all meshes");
|
nextShape++;
|
||||||
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
||||||
|
else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
|
||||||
|
|
||||||
|
newMesh = true;
|
||||||
}
|
}
|
||||||
else if (model.materialCount > 1 && model.meshCount > 1)
|
else if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial)
|
||||||
{
|
{
|
||||||
// TEMP warning about multiple materials, to be removed when proper splitting code is implemented
|
newMesh = true;
|
||||||
// any obj with multiple materials will need to have it's materials assigned by the user in code to work at this time
|
|
||||||
TRACELOG(LOG_INFO, "MODEL: OBJ has multiple materials, manual material assignment will be required.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init model meshes and materials
|
lastMaterial = objAttributes.material_ids[faceId];
|
||||||
model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh));
|
|
||||||
model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int)); // Material index assigned to each mesh
|
|
||||||
model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
|
|
||||||
|
|
||||||
// Process each provided mesh
|
if (newMesh)
|
||||||
for (int i = 0; i < model.meshCount; i++)
|
|
||||||
{
|
{
|
||||||
// WARNING: We need to calculate the mesh triangles manually using meshes[i].face_offset
|
localMeshVertexCounts[meshIndex] = localMeshVertexCount;
|
||||||
// because in case of triangulated quads, meshes[i].length actually report quads,
|
|
||||||
// despite the triangulation that is efectively considered on attrib.num_faces
|
|
||||||
unsigned int tris = 0;
|
|
||||||
if (i == model.meshCount - 1) tris = attrib.num_faces - meshes[i].face_offset;
|
|
||||||
else tris = meshes[i + 1].face_offset;
|
|
||||||
|
|
||||||
model.meshes[i].vertexCount = tris*3;
|
localMeshVertexCount = 0;
|
||||||
model.meshes[i].triangleCount = tris; // Face count (triangulated)
|
meshIndex++;
|
||||||
model.meshes[i].vertices = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
|
|
||||||
model.meshes[i].texcoords = (float *)RL_CALLOC(model.meshes[i].vertexCount*2, sizeof(float));
|
|
||||||
model.meshes[i].normals = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
|
|
||||||
model.meshMaterial[i] = 0; // By default, assign material 0 to each mesh
|
|
||||||
|
|
||||||
// Process all mesh faces
|
|
||||||
for (unsigned int face = 0, f = meshes[i].face_offset, v = 0, vt = 0, vn = 0; face < tris; face++, f++, v += 3, vt += 3, vn += 3)
|
|
||||||
{
|
|
||||||
// Get indices for the face
|
|
||||||
tinyobj_vertex_index_t idx0 = attrib.faces[f*3 + 0];
|
|
||||||
tinyobj_vertex_index_t idx1 = attrib.faces[f*3 + 1];
|
|
||||||
tinyobj_vertex_index_t idx2 = attrib.faces[f*3 + 2];
|
|
||||||
|
|
||||||
// Fill vertices buffer (float) using vertex index of the face
|
|
||||||
for (int n = 0; n < 3; n++) { model.meshes[i].vertices[v*3 + n] = attrib.vertices[idx0.v_idx*3 + n]; }
|
|
||||||
for (int n = 0; n < 3; n++) { model.meshes[i].vertices[(v + 1)*3 + n] = attrib.vertices[idx1.v_idx*3 + n]; }
|
|
||||||
for (int n = 0; n < 3; n++) { model.meshes[i].vertices[(v + 2)*3 + n] = attrib.vertices[idx2.v_idx*3 + n]; }
|
|
||||||
|
|
||||||
if (attrib.num_texcoords > 0)
|
|
||||||
{
|
|
||||||
// Fill texcoords buffer (float) using vertex index of the face
|
|
||||||
// NOTE: Y-coordinate must be flipped upside-down
|
|
||||||
model.meshes[i].texcoords[vt*2 + 0] = attrib.texcoords[idx0.vt_idx*2 + 0];
|
|
||||||
model.meshes[i].texcoords[vt*2 + 1] = 1.0f - attrib.texcoords[idx0.vt_idx*2 + 1];
|
|
||||||
|
|
||||||
model.meshes[i].texcoords[(vt + 1)*2 + 0] = attrib.texcoords[idx1.vt_idx*2 + 0];
|
|
||||||
model.meshes[i].texcoords[(vt + 1)*2 + 1] = 1.0f - attrib.texcoords[idx1.vt_idx*2 + 1];
|
|
||||||
|
|
||||||
model.meshes[i].texcoords[(vt + 2)*2 + 0] = attrib.texcoords[idx2.vt_idx*2 + 0];
|
|
||||||
model.meshes[i].texcoords[(vt + 2)*2 + 1] = 1.0f - attrib.texcoords[idx2.vt_idx*2 + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrib.num_normals > 0)
|
|
||||||
{
|
|
||||||
// Fill normals buffer (float) using vertex index of the face
|
|
||||||
for (int n = 0; n < 3; n++) { model.meshes[i].normals[vn*3 + n] = attrib.normals[idx0.vn_idx*3 + n]; }
|
|
||||||
for (int n = 0; n < 3; n++) { model.meshes[i].normals[(vn + 1)*3 + n] = attrib.normals[idx1.vn_idx*3 + n]; }
|
|
||||||
for (int n = 0; n < 3; n++) { model.meshes[i].normals[(vn + 2)*3 + n] = attrib.normals[idx2.vn_idx*3 + n]; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init model materials
|
faceVertIndex += objAttributes.face_num_verts[faceId];
|
||||||
if (materialCount > 0) ProcessMaterialsOBJ(model.materials, materials, materialCount);
|
localMeshVertexCount += objAttributes.face_num_verts[faceId];
|
||||||
else model.materials[0] = LoadMaterialDefault(); // Set default material for the mesh
|
}
|
||||||
|
localMeshVertexCounts[meshIndex] = localMeshVertexCount;
|
||||||
|
|
||||||
tinyobj_attrib_free(&attrib);
|
for (int i = 0; i < model.meshCount; i++)
|
||||||
tinyobj_shapes_free(meshes, model.meshCount);
|
{
|
||||||
tinyobj_materials_free(materials, materialCount);
|
// allocate the buffers for each mesh
|
||||||
|
unsigned int vertexCount = localMeshVertexCounts[i];
|
||||||
|
|
||||||
UnloadFileText(fileText);
|
model.meshes[i].vertexCount = vertexCount;
|
||||||
|
model.meshes[i].triangleCount = vertexCount / 3;
|
||||||
|
|
||||||
// Restore current working directory
|
model.meshes[i].vertices = (float*)MemAlloc(sizeof(float) * vertexCount * 3);
|
||||||
if (CHDIR(currentDir) != 0)
|
model.meshes[i].normals = (float*)MemAlloc(sizeof(float) * vertexCount * 3);
|
||||||
|
model.meshes[i].texcoords = (float*)MemAlloc(sizeof(float) * vertexCount * 2);
|
||||||
|
model.meshes[i].colors = (unsigned char*)MemAlloc(sizeof(unsigned char) * vertexCount * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemFree(localMeshVertexCounts);
|
||||||
|
localMeshVertexCounts = NULL;
|
||||||
|
|
||||||
|
// fill meshes
|
||||||
|
faceVertIndex = 0;
|
||||||
|
|
||||||
|
nextShapeEnd = objAttributes.num_face_num_verts;
|
||||||
|
|
||||||
|
// see how many verts till the next shape
|
||||||
|
nextShape = 1;
|
||||||
|
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
|
||||||
|
lastMaterial = -1;
|
||||||
|
meshIndex = 0;
|
||||||
|
localMeshVertexCount = 0;
|
||||||
|
|
||||||
|
// walk all the faces
|
||||||
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
||||||
|
{
|
||||||
|
bool newMesh = false; // do we need a new mesh?
|
||||||
|
if (faceVertIndex >= nextShapeEnd)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", currentDir);
|
// try to find the last vert in the next shape
|
||||||
|
nextShape++;
|
||||||
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
||||||
|
else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
|
||||||
|
newMesh = true;
|
||||||
}
|
}
|
||||||
|
// if this is a new material, we need to allocate a new mesh
|
||||||
|
if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial) newMesh = true;
|
||||||
|
lastMaterial = objAttributes.material_ids[faceId];
|
||||||
|
|
||||||
|
if (newMesh)
|
||||||
|
{
|
||||||
|
localMeshVertexCount = 0;
|
||||||
|
meshIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int matId = 0;
|
||||||
|
if (lastMaterial >= 0 && lastMaterial < (int)objMaterialCount)
|
||||||
|
matId = lastMaterial;
|
||||||
|
|
||||||
|
model.meshMaterial[meshIndex] = matId;
|
||||||
|
|
||||||
|
for (int f = 0; f < objAttributes.face_num_verts[faceId]; f++)
|
||||||
|
{
|
||||||
|
int vertIndex = objAttributes.faces[faceVertIndex].v_idx;
|
||||||
|
int normalIndex = objAttributes.faces[faceVertIndex].vn_idx;
|
||||||
|
int texcordIndex = objAttributes.faces[faceVertIndex].vt_idx;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
model.meshes[meshIndex].vertices[localMeshVertexCount * 3 + i] = objAttributes.vertices[vertIndex * 3 + i];
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
model.meshes[meshIndex].normals[localMeshVertexCount * 3 + i] = objAttributes.normals[normalIndex * 3 + i];
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + i] = objAttributes.texcoords[texcordIndex * 2 + i];
|
||||||
|
|
||||||
|
model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + 1] = 1.0f - model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + 1];
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
model.meshes[meshIndex].colors[localMeshVertexCount * 4 + i] = 255;
|
||||||
|
|
||||||
|
faceVertIndex++;
|
||||||
|
localMeshVertexCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objMaterialCount > 0) ProcessMaterialsOBJ(model.materials, objMaterials, objMaterialCount);
|
||||||
|
else model.materials[0] = LoadMaterialDefault(); // Set default material for the mesh
|
||||||
|
|
||||||
|
tinyobj_attrib_free(&objAttributes);
|
||||||
|
tinyobj_shapes_free(objShapes, objShapeCount);
|
||||||
|
tinyobj_materials_free(objMaterials, objMaterialCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < model.meshCount; i++)
|
||||||
|
UploadMesh(model.meshes + i, true);
|
||||||
|
|
||||||
|
// Restore current working directory
|
||||||
|
if (CHDIR(currentDir) != 0)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", currentDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
|
|
@ -4540,6 +4825,17 @@ static Model LoadIQM(const char *fileName)
|
||||||
|
|
||||||
BuildPoseFromParentJoints(model.bones, model.boneCount, model.bindPose);
|
BuildPoseFromParentJoints(model.bones, model.boneCount, model.bindPose);
|
||||||
|
|
||||||
|
for (int i = 0; i < model.meshCount; i++)
|
||||||
|
{
|
||||||
|
model.meshes[i].boneCount = model.boneCount;
|
||||||
|
model.meshes[i].boneMatrices = RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix));
|
||||||
|
|
||||||
|
for (int j = 0; j < model.meshes[i].boneCount; j++)
|
||||||
|
{
|
||||||
|
model.meshes[i].boneMatrices[j] = MatrixIdentity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UnloadFileData(fileData);
|
UnloadFileData(fileData);
|
||||||
|
|
||||||
RL_FREE(imesh);
|
RL_FREE(imesh);
|
||||||
|
|
@ -4948,17 +5244,19 @@ static Model LoadGLTF(const char *fileName)
|
||||||
***********************************************************************************************/
|
***********************************************************************************************/
|
||||||
|
|
||||||
// Macro to simplify attributes loading code
|
// Macro to simplify attributes loading code
|
||||||
#define LOAD_ATTRIBUTE(accesor, numComp, dataType, dstPtr) \
|
#define LOAD_ATTRIBUTE(accesor, numComp, srcType, dstPtr) LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, srcType)
|
||||||
|
|
||||||
|
#define LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, dstType) \
|
||||||
{ \
|
{ \
|
||||||
int n = 0; \
|
int n = 0; \
|
||||||
dataType *buffer = (dataType *)accesor->buffer_view->buffer->data + accesor->buffer_view->offset/sizeof(dataType) + accesor->offset/sizeof(dataType); \
|
srcType *buffer = (srcType *)accesor->buffer_view->buffer->data + accesor->buffer_view->offset/sizeof(srcType) + accesor->offset/sizeof(srcType); \
|
||||||
for (unsigned int k = 0; k < accesor->count; k++) \
|
for (unsigned int k = 0; k < accesor->count; k++) \
|
||||||
{\
|
{\
|
||||||
for (int l = 0; l < numComp; l++) \
|
for (int l = 0; l < numComp; l++) \
|
||||||
{\
|
{\
|
||||||
dstPtr[numComp*k + l] = buffer[n + l];\
|
dstPtr[numComp*k + l] = (dstType)buffer[n + l];\
|
||||||
}\
|
}\
|
||||||
n += (int)(accesor->stride/sizeof(dataType));\
|
n += (int)(accesor->stride/sizeof(srcType));\
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5399,8 +5697,6 @@ static Model LoadGLTF(const char *fileName)
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Attributes related to animations are processed separately
|
// NOTE: Attributes related to animations are processed separately
|
||||||
|
|
@ -5421,23 +5717,25 @@ static Model LoadGLTF(const char *fileName)
|
||||||
// Load unsigned short data type into mesh.indices
|
// Load unsigned short data type into mesh.indices
|
||||||
LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices)
|
LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices)
|
||||||
}
|
}
|
||||||
|
else if (attribute->component_type == cgltf_component_type_r_8u)
|
||||||
|
{
|
||||||
|
// Init raylib mesh indices to copy glTF attribute data
|
||||||
|
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count * sizeof(unsigned short));
|
||||||
|
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short)
|
||||||
|
|
||||||
|
}
|
||||||
else if (attribute->component_type == cgltf_component_type_r_32u)
|
else if (attribute->component_type == cgltf_component_type_r_32u)
|
||||||
{
|
{
|
||||||
// Init raylib mesh indices to copy glTF attribute data
|
// Init raylib mesh indices to copy glTF attribute data
|
||||||
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short));
|
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short));
|
||||||
|
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned int, model.meshes[meshIndex].indices, unsigned short);
|
||||||
// Load data into a temp buffer to be converted to raylib data type
|
|
||||||
unsigned int *temp = RL_MALLOC(attribute->count*sizeof(unsigned int));
|
|
||||||
LOAD_ATTRIBUTE(attribute, 1, unsigned int, temp);
|
|
||||||
|
|
||||||
// Convert data to raylib indices data type (unsigned short)
|
|
||||||
for (unsigned int d = 0; d < attribute->count; d++) model.meshes[meshIndex].indices[d] = (unsigned short)temp[d];
|
|
||||||
|
|
||||||
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);
|
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);
|
||||||
|
|
||||||
RL_FREE(temp);
|
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName);
|
else
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else model.meshes[meshIndex].triangleCount = model.meshes[meshIndex].vertexCount/3; // Unindexed mesh
|
else model.meshes[meshIndex].triangleCount = model.meshes[meshIndex].vertexCount/3; // Unindexed mesh
|
||||||
|
|
||||||
|
|
@ -5469,7 +5767,7 @@ static Model LoadGLTF(const char *fileName)
|
||||||
// - Only supports linear interpolation (default method in Blender when checked "Always Sample Animations" when exporting a GLTF file)
|
// - Only supports linear interpolation (default method in Blender when checked "Always Sample Animations" when exporting a GLTF file)
|
||||||
// - Only supports translation/rotation/scale animation channel.path, weights not considered (i.e. morph targets)
|
// - Only supports translation/rotation/scale animation channel.path, weights not considered (i.e. morph targets)
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
if (data->skins_count == 1)
|
if (data->skins_count > 0)
|
||||||
{
|
{
|
||||||
cgltf_skin skin = data->skins[0];
|
cgltf_skin skin = data->skins[0];
|
||||||
model.bones = LoadBoneInfoGLTF(skin, &model.boneCount);
|
model.bones = LoadBoneInfoGLTF(skin, &model.boneCount);
|
||||||
|
|
@ -5489,9 +5787,9 @@ static Model LoadGLTF(const char *fileName)
|
||||||
MatrixDecompose(worldMatrix, &(model.bindPose[i].translation), &(model.bindPose[i].rotation), &(model.bindPose[i].scale));
|
MatrixDecompose(worldMatrix, &(model.bindPose[i].translation), &(model.bindPose[i].rotation), &(model.bindPose[i].scale));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (data->skins_count > 1)
|
if (data->skins_count > 1)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_ERROR, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
|
TRACELOG(LOG_WARNING, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
meshIndex = 0;
|
meshIndex = 0;
|
||||||
|
|
@ -5623,6 +5921,15 @@ static Model LoadGLTF(const char *fileName)
|
||||||
memcpy(model.meshes[meshIndex].animNormals, model.meshes[meshIndex].normals, model.meshes[meshIndex].vertexCount*3*sizeof(float));
|
memcpy(model.meshes[meshIndex].animNormals, model.meshes[meshIndex].normals, model.meshes[meshIndex].vertexCount*3*sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bone Transform Matrices
|
||||||
|
model.meshes[meshIndex].boneCount = model.boneCount;
|
||||||
|
model.meshes[meshIndex].boneMatrices = RL_CALLOC(model.meshes[meshIndex].boneCount, sizeof(Matrix));
|
||||||
|
|
||||||
|
for (int j = 0; j < model.meshes[meshIndex].boneCount; j++)
|
||||||
|
{
|
||||||
|
model.meshes[meshIndex].boneMatrices[j] = MatrixIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
meshIndex++; // Move to next mesh
|
meshIndex++; // Move to next mesh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5803,7 +6110,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
|
||||||
|
|
||||||
if (result == cgltf_result_success)
|
if (result == cgltf_result_success)
|
||||||
{
|
{
|
||||||
if (data->skins_count == 1)
|
if (data->skins_count > 0)
|
||||||
{
|
{
|
||||||
cgltf_skin skin = data->skins[0];
|
cgltf_skin skin = data->skins[0];
|
||||||
*animCount = (int)data->animations_count;
|
*animCount = (int)data->animations_count;
|
||||||
|
|
@ -5938,7 +6245,11 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
|
||||||
RL_FREE(boneChannels);
|
RL_FREE(boneChannels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_ERROR, "MODEL: [%s] expected exactly one skin to load animation data from, but found %i", fileName, data->skins_count);
|
|
||||||
|
if (data->skins_count > 1)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "MODEL: [%s] expected exactly one skin to load animation data from, but found %i", fileName, data->skins_count);
|
||||||
|
}
|
||||||
|
|
||||||
cgltf_free(data);
|
cgltf_free(data);
|
||||||
}
|
}
|
||||||
|
|
@ -6390,6 +6701,13 @@ static Model LoadM3D(const char *fileName)
|
||||||
{
|
{
|
||||||
memcpy(model.meshes[i].animVertices, model.meshes[i].vertices, model.meshes[i].vertexCount*3*sizeof(float));
|
memcpy(model.meshes[i].animVertices, model.meshes[i].vertices, model.meshes[i].vertexCount*3*sizeof(float));
|
||||||
memcpy(model.meshes[i].animNormals, model.meshes[i].normals, model.meshes[i].vertexCount*3*sizeof(float));
|
memcpy(model.meshes[i].animNormals, model.meshes[i].normals, model.meshes[i].vertexCount*3*sizeof(float));
|
||||||
|
|
||||||
|
model.meshes[i].boneCount = model.boneCount;
|
||||||
|
model.meshes[i].boneMatrices = RL_CALLOC(model.meshes[i].boneCount, sizeof(Matrix));
|
||||||
|
for (j = 0; j < model.meshes[i].boneCount; j++)
|
||||||
|
{
|
||||||
|
model.meshes[i].boneMatrices[j] = MatrixIdentity();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -828,8 +828,8 @@ void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color)
|
||||||
{
|
{
|
||||||
if ((lineThick > rec.width) || (lineThick > rec.height))
|
if ((lineThick > rec.width) || (lineThick > rec.height))
|
||||||
{
|
{
|
||||||
if (rec.width > rec.height) lineThick = rec.height/2;
|
if (rec.width >= rec.height) lineThick = rec.height/2;
|
||||||
else if (rec.width < rec.height) lineThick = rec.width/2;
|
else if (rec.width <= rec.height) lineThick = rec.width/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When rec = { x, y, 8.0f, 6.0f } and lineThick = 2, the following
|
// When rec = { x, y, 8.0f, 6.0f } and lineThick = 2, the following
|
||||||
|
|
|
||||||
58
src/rtext.c
58
src/rtext.c
|
|
@ -124,6 +124,7 @@
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Global variables
|
// Global variables
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
extern bool isGpuReady;
|
||||||
#if defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Default font provided by raylib
|
// Default font provided by raylib
|
||||||
// NOTE: Default font is loaded on InitWindow() and disposed on CloseWindow() [module: core]
|
// NOTE: Default font is loaded on InitWindow() and disposed on CloseWindow() [module: core]
|
||||||
|
|
@ -252,15 +253,15 @@ extern void LoadFontDefault(void)
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultFont.texture = LoadTextureFromImage(imFont);
|
if (isGpuReady) defaultFont.texture = LoadTextureFromImage(imFont);
|
||||||
|
|
||||||
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, glyphCount
|
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, glyphCount
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Allocate space for our characters info data
|
// Allocate space for our characters info data
|
||||||
// NOTE: This memory must be freed at end! --> Done by CloseWindow()
|
// NOTE: This memory must be freed at end! --> Done by CloseWindow()
|
||||||
defaultFont.glyphs = (GlyphInfo *)RL_MALLOC(defaultFont.glyphCount*sizeof(GlyphInfo));
|
defaultFont.glyphs = (GlyphInfo *)RL_CALLOC(defaultFont.glyphCount, sizeof(GlyphInfo));
|
||||||
defaultFont.recs = (Rectangle *)RL_MALLOC(defaultFont.glyphCount*sizeof(Rectangle));
|
defaultFont.recs = (Rectangle *)RL_CALLOC(defaultFont.glyphCount, sizeof(Rectangle));
|
||||||
|
|
||||||
int currentLine = 0;
|
int currentLine = 0;
|
||||||
int currentPosX = charsDivisor;
|
int currentPosX = charsDivisor;
|
||||||
|
|
@ -308,7 +309,7 @@ extern void LoadFontDefault(void)
|
||||||
extern void UnloadFontDefault(void)
|
extern void UnloadFontDefault(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < defaultFont.glyphCount; i++) UnloadImage(defaultFont.glyphs[i].image);
|
for (int i = 0; i < defaultFont.glyphCount; i++) UnloadImage(defaultFont.glyphs[i].image);
|
||||||
UnloadTexture(defaultFont.texture);
|
if (isGpuReady) UnloadTexture(defaultFont.texture);
|
||||||
RL_FREE(defaultFont.glyphs);
|
RL_FREE(defaultFont.glyphs);
|
||||||
RL_FREE(defaultFont.recs);
|
RL_FREE(defaultFont.recs);
|
||||||
}
|
}
|
||||||
|
|
@ -362,11 +363,14 @@ Font LoadFont(const char *fileName)
|
||||||
UnloadImage(image);
|
UnloadImage(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font.texture.id == 0) TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName);
|
if (isGpuReady)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); // By default, we set point filter (the best performance)
|
if (font.texture.id == 0) TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName);
|
||||||
TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", FONT_TTF_DEFAULT_SIZE, FONT_TTF_DEFAULT_NUMCHARS);
|
else
|
||||||
|
{
|
||||||
|
SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); // By default, we set point filter (the best performance)
|
||||||
|
TRACELOG(LOG_INFO, "FONT: Data loaded successfully (%i pixel size | %i glyphs)", FONT_TTF_DEFAULT_SIZE, FONT_TTF_DEFAULT_NUMCHARS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
|
|
@ -487,7 +491,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set font with all data parsed from image
|
// Set font with all data parsed from image
|
||||||
font.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
|
if (isGpuReady) font.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
|
||||||
font.glyphCount = index;
|
font.glyphCount = index;
|
||||||
font.glyphPadding = 0;
|
font.glyphPadding = 0;
|
||||||
|
|
||||||
|
|
@ -556,7 +560,7 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
|
||||||
font.glyphPadding = FONT_TTF_DEFAULT_CHARS_PADDING;
|
font.glyphPadding = FONT_TTF_DEFAULT_CHARS_PADDING;
|
||||||
|
|
||||||
Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, font.glyphPadding, 0);
|
Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, font.glyphPadding, 0);
|
||||||
font.texture = LoadTextureFromImage(atlas);
|
if (isGpuReady) font.texture = LoadTextureFromImage(atlas);
|
||||||
|
|
||||||
// Update glyphs[i].image to use alpha, required to be used on ImageDrawText()
|
// Update glyphs[i].image to use alpha, required to be used on ImageDrawText()
|
||||||
for (int i = 0; i < font.glyphCount; i++)
|
for (int i = 0; i < font.glyphCount; i++)
|
||||||
|
|
@ -577,17 +581,16 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a font is ready
|
// Check if a font is valid (font data loaded)
|
||||||
bool IsFontReady(Font font)
|
// WARNING: GPU texture not checked
|
||||||
|
bool IsFontValid(Font font)
|
||||||
{
|
{
|
||||||
return ((font.texture.id > 0) && // Validate OpenGL id fot font texture atlas
|
return ((font.baseSize > 0) && // Validate font size
|
||||||
(font.baseSize > 0) && // Validate font size
|
|
||||||
(font.glyphCount > 0) && // Validate font contains some glyph
|
(font.glyphCount > 0) && // Validate font contains some glyph
|
||||||
(font.recs != NULL) && // Validate font recs defining glyphs on texture atlas
|
(font.recs != NULL) && // Validate font recs defining glyphs on texture atlas
|
||||||
(font.glyphs != NULL)); // Validate glyph data is loaded
|
(font.glyphs != NULL)); // Validate glyph data is loaded
|
||||||
|
|
||||||
// NOTE: Further validations could be done to verify if recs count and glyphs count
|
// NOTE: Further validations could be done to verify if recs and glyphs contain valid data (glyphs values, metrics...)
|
||||||
// match glyphCount and to verify that data contained is valid (glyphs values, metrics...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load font data for further use
|
// Load font data for further use
|
||||||
|
|
@ -674,6 +677,8 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
||||||
stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
|
stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
|
||||||
chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor);
|
chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor);
|
||||||
|
|
||||||
|
if (chh > fontSize) TRACELOG(LOG_WARNING, "FONT: Character [0x%08x] size is bigger than expected font size", ch);
|
||||||
|
|
||||||
// Load characters images
|
// Load characters images
|
||||||
chars[i].image.width = chw;
|
chars[i].image.width = chw;
|
||||||
chars[i].image.height = chh;
|
chars[i].image.height = chh;
|
||||||
|
|
@ -946,7 +951,7 @@ void UnloadFont(Font font)
|
||||||
if (font.texture.id != GetFontDefault().texture.id)
|
if (font.texture.id != GetFontDefault().texture.id)
|
||||||
{
|
{
|
||||||
UnloadFontData(font.glyphs, font.glyphCount);
|
UnloadFontData(font.glyphs, font.glyphCount);
|
||||||
UnloadTexture(font.texture);
|
if (isGpuReady) UnloadTexture(font.texture);
|
||||||
RL_FREE(font.recs);
|
RL_FREE(font.recs);
|
||||||
|
|
||||||
TRACELOGD("FONT: Unloaded font data from RAM and VRAM");
|
TRACELOGD("FONT: Unloaded font data from RAM and VRAM");
|
||||||
|
|
@ -1066,7 +1071,7 @@ bool ExportFontAsCode(Font font, const char *fileName)
|
||||||
byteCount += sprintf(txtData + byteCount, " Image imFont = { fontImageData_%s, %i, %i, 1, %i };\n\n", styleName, image.width, image.height, image.format);
|
byteCount += sprintf(txtData + byteCount, " Image imFont = { fontImageData_%s, %i, %i, 1, %i };\n\n", styleName, image.width, image.height, image.format);
|
||||||
#endif
|
#endif
|
||||||
byteCount += sprintf(txtData + byteCount, " // Load texture from image\n");
|
byteCount += sprintf(txtData + byteCount, " // Load texture from image\n");
|
||||||
byteCount += sprintf(txtData + byteCount, " font.texture = LoadTextureFromImage(imFont);\n");
|
byteCount += sprintf(txtData + byteCount, " if (isGpuReady) font.texture = LoadTextureFromImage(imFont);\n");
|
||||||
#if defined(SUPPORT_COMPRESSED_FONT_ATLAS)
|
#if defined(SUPPORT_COMPRESSED_FONT_ATLAS)
|
||||||
byteCount += sprintf(txtData + byteCount, " UnloadImage(imFont); // Uncompressed data can be unloaded from memory\n\n");
|
byteCount += sprintf(txtData + byteCount, " UnloadImage(imFont); // Uncompressed data can be unloaded from memory\n\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1277,7 +1282,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
|
||||||
{
|
{
|
||||||
Vector2 textSize = { 0 };
|
Vector2 textSize = { 0 };
|
||||||
|
|
||||||
if ((font.texture.id == 0) || (text == NULL)) return textSize; // Security check
|
if ((isGpuReady && (font.texture.id == 0)) || (text == NULL)) return textSize; // Security check
|
||||||
|
|
||||||
int size = TextLength(text); // Get size in bytes of text
|
int size = TextLength(text); // Get size in bytes of text
|
||||||
int tempByteCounter = 0; // Used to count longer text line num chars
|
int tempByteCounter = 0; // Used to count longer text line num chars
|
||||||
|
|
@ -1296,15 +1301,15 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
|
||||||
{
|
{
|
||||||
byteCounter++;
|
byteCounter++;
|
||||||
|
|
||||||
int next = 0;
|
int codepointByteCount = 0;
|
||||||
letter = GetCodepointNext(&text[i], &next);
|
letter = GetCodepointNext(&text[i], &codepointByteCount);
|
||||||
index = GetGlyphIndex(font, letter);
|
index = GetGlyphIndex(font, letter);
|
||||||
|
|
||||||
i += next;
|
i += codepointByteCount;
|
||||||
|
|
||||||
if (letter != '\n')
|
if (letter != '\n')
|
||||||
{
|
{
|
||||||
if (font.glyphs[index].advanceX != 0) textWidth += font.glyphs[index].advanceX;
|
if (font.glyphs[index].advanceX > 0) textWidth += font.glyphs[index].advanceX;
|
||||||
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX);
|
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1924,7 +1929,8 @@ int GetCodepointCount(const char *text)
|
||||||
const char *CodepointToUTF8(int codepoint, int *utf8Size)
|
const char *CodepointToUTF8(int codepoint, int *utf8Size)
|
||||||
{
|
{
|
||||||
static char utf8[6] = { 0 };
|
static char utf8[6] = { 0 };
|
||||||
int size = 0; // Byte size of codepoint
|
memset(utf8, 0, 6); // Clear static array
|
||||||
|
int size = 0; // Byte size of codepoint
|
||||||
|
|
||||||
if (codepoint <= 0x7f)
|
if (codepoint <= 0x7f)
|
||||||
{
|
{
|
||||||
|
|
@ -2257,7 +2263,7 @@ static Font LoadBMFont(const char *fileName)
|
||||||
|
|
||||||
RL_FREE(imFonts);
|
RL_FREE(imFonts);
|
||||||
|
|
||||||
font.texture = LoadTextureFromImage(fullFont);
|
if (isGpuReady) font.texture = LoadTextureFromImage(fullFont);
|
||||||
|
|
||||||
// Fill font characters info data
|
// Fill font characters info data
|
||||||
font.baseSize = fontSize;
|
font.baseSize = fontSize;
|
||||||
|
|
@ -2299,7 +2305,7 @@ static Font LoadBMFont(const char *fileName)
|
||||||
UnloadImage(fullFont);
|
UnloadImage(fullFont);
|
||||||
UnloadFileText(fileText);
|
UnloadFileText(fileText);
|
||||||
|
|
||||||
if (font.texture.id == 0)
|
if (isGpuReady && (font.texture.id == 0))
|
||||||
{
|
{
|
||||||
UnloadFont(font);
|
UnloadFont(font);
|
||||||
font = GetFontDefault();
|
font = GetFontDefault();
|
||||||
|
|
|
||||||
183
src/rtextures.c
183
src/rtextures.c
|
|
@ -225,14 +225,6 @@
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SUPPORT_FILEFORMAT_SVG)
|
|
||||||
#define NANOSVG_IMPLEMENTATION // Expands implementation
|
|
||||||
#include "external/nanosvg.h"
|
|
||||||
|
|
||||||
#define NANOSVGRAST_IMPLEMENTATION
|
|
||||||
#include "external/nanosvgrast.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -335,84 +327,6 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load an image from a SVG file or string with custom size
|
|
||||||
Image LoadImageSvg(const char *fileNameOrString, int width, int height)
|
|
||||||
{
|
|
||||||
Image image = { 0 };
|
|
||||||
|
|
||||||
#if defined(SUPPORT_FILEFORMAT_SVG)
|
|
||||||
bool isSvgStringValid = false;
|
|
||||||
|
|
||||||
// Validate fileName or string
|
|
||||||
if (fileNameOrString != NULL)
|
|
||||||
{
|
|
||||||
int dataSize = 0;
|
|
||||||
unsigned char *fileData = NULL;
|
|
||||||
|
|
||||||
if (FileExists(fileNameOrString))
|
|
||||||
{
|
|
||||||
fileData = LoadFileData(fileNameOrString, &dataSize);
|
|
||||||
isSvgStringValid = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Validate fileData as valid SVG string data
|
|
||||||
//<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2484" viewBox="0 0 192.756 191.488">
|
|
||||||
if ((fileNameOrString != NULL) &&
|
|
||||||
(fileNameOrString[0] == '<') &&
|
|
||||||
(fileNameOrString[1] == 's') &&
|
|
||||||
(fileNameOrString[2] == 'v') &&
|
|
||||||
(fileNameOrString[3] == 'g'))
|
|
||||||
{
|
|
||||||
fileData = (unsigned char *)fileNameOrString;
|
|
||||||
isSvgStringValid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSvgStringValid)
|
|
||||||
{
|
|
||||||
struct NSVGimage *svgImage = nsvgParse((char *)fileData, "px", 96.0f);
|
|
||||||
|
|
||||||
unsigned char *img = RL_MALLOC(width*height*4);
|
|
||||||
|
|
||||||
// Calculate scales for both the width and the height
|
|
||||||
const float scaleWidth = width/svgImage->width;
|
|
||||||
const float scaleHeight = height/svgImage->height;
|
|
||||||
|
|
||||||
// Set the largest of the 2 scales to be the scale to use
|
|
||||||
const float scale = (scaleHeight > scaleWidth)? scaleWidth : scaleHeight;
|
|
||||||
|
|
||||||
int offsetX = 0;
|
|
||||||
int offsetY = 0;
|
|
||||||
|
|
||||||
if (scaleHeight > scaleWidth) offsetY = (height - svgImage->height*scale)/2;
|
|
||||||
else offsetX = (width - svgImage->width*scale)/2;
|
|
||||||
|
|
||||||
// Rasterize
|
|
||||||
struct NSVGrasterizer *rast = nsvgCreateRasterizer();
|
|
||||||
nsvgRasterize(rast, svgImage, (int)offsetX, (int)offsetY, scale, img, width, height, width*4);
|
|
||||||
|
|
||||||
// Populate image struct with all data
|
|
||||||
image.data = img;
|
|
||||||
image.width = width;
|
|
||||||
image.height = height;
|
|
||||||
image.mipmaps = 1;
|
|
||||||
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
|
||||||
|
|
||||||
// Free used memory
|
|
||||||
nsvgDelete(svgImage);
|
|
||||||
nsvgDeleteRasterizer(rast);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSvgStringValid && (fileData != (unsigned char *)fileNameOrString)) UnloadFileData(fileData);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
TRACELOG(LOG_WARNING, "SVG image support not enabled, image can not be loaded");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load animated image data
|
// Load animated image data
|
||||||
// - Image.data buffer includes all frames: [image#0][image#1][image#2][...]
|
// - Image.data buffer includes all frames: [image#0][image#1][image#2][...]
|
||||||
// - Number of frames is returned through 'frames' parameter
|
// - Number of frames is returned through 'frames' parameter
|
||||||
|
|
@ -592,44 +506,14 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|
||||||
if (fileData != NULL)
|
if (fileData != NULL)
|
||||||
{
|
{
|
||||||
qoi_desc desc = { 0 };
|
qoi_desc desc = { 0 };
|
||||||
image.data = qoi_decode(fileData, dataSize, &desc, 4);
|
image.data = qoi_decode(fileData, dataSize, &desc, (int) fileData[12]);
|
||||||
image.width = desc.width;
|
image.width = desc.width;
|
||||||
image.height = desc.height;
|
image.height = desc.height;
|
||||||
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
image.format = desc.channels == 4 ? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8;
|
||||||
image.mipmaps = 1;
|
image.mipmaps = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(SUPPORT_FILEFORMAT_SVG)
|
|
||||||
else if ((strcmp(fileType, ".svg") == 0) || (strcmp(fileType, ".SVG") == 0))
|
|
||||||
{
|
|
||||||
// Validate fileData as valid SVG string data
|
|
||||||
//<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2484" viewBox="0 0 192.756 191.488">
|
|
||||||
if ((fileData != NULL) &&
|
|
||||||
(fileData[0] == '<') &&
|
|
||||||
(fileData[1] == 's') &&
|
|
||||||
(fileData[2] == 'v') &&
|
|
||||||
(fileData[3] == 'g'))
|
|
||||||
{
|
|
||||||
struct NSVGimage *svgImage = nsvgParse((char *)fileData, "px", 96.0f);
|
|
||||||
unsigned char *img = RL_MALLOC(svgImage->width*svgImage->height*4);
|
|
||||||
|
|
||||||
// Rasterize
|
|
||||||
struct NSVGrasterizer *rast = nsvgCreateRasterizer();
|
|
||||||
nsvgRasterize(rast, svgImage, 0, 0, 1.0f, img, svgImage->width, svgImage->height, svgImage->width*4);
|
|
||||||
|
|
||||||
// Populate image struct with all data
|
|
||||||
image.data = img;
|
|
||||||
image.width = svgImage->width;
|
|
||||||
image.height = svgImage->height;
|
|
||||||
image.mipmaps = 1;
|
|
||||||
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
|
||||||
|
|
||||||
nsvgDelete(svgImage);
|
|
||||||
nsvgDeleteRasterizer(rast);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if defined(SUPPORT_FILEFORMAT_DDS)
|
#if defined(SUPPORT_FILEFORMAT_DDS)
|
||||||
else if ((strcmp(fileType, ".dds") == 0) || (strcmp(fileType, ".DDS") == 0))
|
else if ((strcmp(fileType, ".dds") == 0) || (strcmp(fileType, ".DDS") == 0))
|
||||||
{
|
{
|
||||||
|
|
@ -716,15 +600,15 @@ Image LoadImageFromScreen(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if an image is ready
|
// Check if an image is ready
|
||||||
bool IsImageReady(Image image)
|
bool IsImageValid(Image image)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if ((image.data != NULL) && // Validate pixel data available
|
if ((image.data != NULL) && // Validate pixel data available
|
||||||
(image.width > 0) &&
|
(image.width > 0) && // Validate image width
|
||||||
(image.height > 0) && // Validate image size
|
(image.height > 0) && // Validate image height
|
||||||
(image.format > 0) && // Validate image format
|
(image.format > 0) && // Validate image format
|
||||||
(image.mipmaps > 0)) result = true; // Validate image mipmaps (at least 1 for basic mipmap level)
|
(image.mipmaps > 0)) result = true; // Validate image mipmaps (at least 1 for basic mipmap level)
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -1123,7 +1007,7 @@ Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float
|
||||||
// Apply aspect ratio compensation to wider side
|
// Apply aspect ratio compensation to wider side
|
||||||
if (width > height) nx *= aspectRatio;
|
if (width > height) nx *= aspectRatio;
|
||||||
else ny /= aspectRatio;
|
else ny /= aspectRatio;
|
||||||
|
|
||||||
// Basic perlin noise implementation (not used)
|
// Basic perlin noise implementation (not used)
|
||||||
//float p = (stb_perlin_noise3(nx, ny, 0.0f, 0, 0, 0);
|
//float p = (stb_perlin_noise3(nx, ny, 0.0f, 0, 0, 0);
|
||||||
|
|
||||||
|
|
@ -4085,13 +3969,21 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
|
||||||
// [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend()
|
// [-] GetPixelColor(): Get Vector4 instead of Color, easier for ColorAlphaBlend()
|
||||||
// [ ] Support f32bit channels drawing
|
// [ ] Support f32bit channels drawing
|
||||||
|
|
||||||
// TODO: Support PIXELFORMAT_UNCOMPRESSED_R32, PIXELFORMAT_UNCOMPRESSED_R32G32B32, PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 and 16-bit equivalents
|
// TODO: Support PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 and PIXELFORMAT_UNCOMPRESSED_R1616B16A16
|
||||||
|
|
||||||
Color colSrc, colDst, blend;
|
Color colSrc, colDst, blend;
|
||||||
bool blendRequired = true;
|
bool blendRequired = true;
|
||||||
|
|
||||||
// Fast path: Avoid blend if source has no alpha to blend
|
// Fast path: Avoid blend if source has no alpha to blend
|
||||||
if ((tint.a == 255) && ((srcPtr->format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) || (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R8G8B8) || (srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R5G6B5))) blendRequired = false;
|
if ((tint.a == 255) &&
|
||||||
|
((srcPtr->format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) ||
|
||||||
|
(srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R5G6B5) ||
|
||||||
|
(srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R8G8B8) ||
|
||||||
|
(srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R32) ||
|
||||||
|
(srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R32G32B32) ||
|
||||||
|
(srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R16) ||
|
||||||
|
(srcPtr->format == PIXELFORMAT_UNCOMPRESSED_R16G16B16)))
|
||||||
|
blendRequired = false;
|
||||||
|
|
||||||
int strideDst = GetPixelDataSize(dst->width, 1, dst->format);
|
int strideDst = GetPixelDataSize(dst->width, 1, dst->format);
|
||||||
int bytesPerPixelDst = strideDst/(dst->width);
|
int bytesPerPixelDst = strideDst/(dst->width);
|
||||||
|
|
@ -4340,16 +4232,16 @@ RenderTexture2D LoadRenderTexture(int width, int height)
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a texture is ready
|
// Check if a texture is valid (loaded in GPU)
|
||||||
bool IsTextureReady(Texture2D texture)
|
bool IsTextureValid(Texture2D texture)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
// TODO: Validate maximum texture size supported by GPU?
|
// TODO: Validate maximum texture size supported by GPU
|
||||||
|
|
||||||
if ((texture.id > 0) && // Validate OpenGL id
|
if ((texture.id > 0) && // Validate OpenGL id (texture uplaoded to GPU)
|
||||||
(texture.width > 0) &&
|
(texture.width > 0) && // Validate texture width
|
||||||
(texture.height > 0) && // Validate texture size
|
(texture.height > 0) && // Validate texture height
|
||||||
(texture.format > 0) && // Validate texture pixel format
|
(texture.format > 0) && // Validate texture pixel format
|
||||||
(texture.mipmaps > 0)) result = true; // Validate texture mipmaps (at least 1 for basic mipmap level)
|
(texture.mipmaps > 0)) result = true; // Validate texture mipmaps (at least 1 for basic mipmap level)
|
||||||
|
|
||||||
|
|
@ -4367,14 +4259,14 @@ void UnloadTexture(Texture2D texture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a render texture is ready
|
// Check if a render texture is valid (loaded in GPU)
|
||||||
bool IsRenderTextureReady(RenderTexture2D target)
|
bool IsRenderTextureValid(RenderTexture2D target)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if ((target.id > 0) && // Validate OpenGL id
|
if ((target.id > 0) && // Validate OpenGL id (loaded on GPU)
|
||||||
IsTextureReady(target.depth) && // Validate FBO depth texture/renderbuffer
|
IsTextureValid(target.depth) && // Validate FBO depth texture/renderbuffer attachment
|
||||||
IsTextureReady(target.texture)) result = true; // Validate FBO texture
|
IsTextureValid(target.texture)) result = true; // Validate FBO texture attachment
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -4566,6 +4458,9 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
|
||||||
if (source.width < 0) { flipX = true; source.width *= -1; }
|
if (source.width < 0) { flipX = true; source.width *= -1; }
|
||||||
if (source.height < 0) source.y -= source.height;
|
if (source.height < 0) source.y -= source.height;
|
||||||
|
|
||||||
|
if (dest.width < 0) dest.width *= -1;
|
||||||
|
if (dest.height < 0) dest.height *= -1;
|
||||||
|
|
||||||
Vector2 topLeft = { 0 };
|
Vector2 topLeft = { 0 };
|
||||||
Vector2 topRight = { 0 };
|
Vector2 topRight = { 0 };
|
||||||
Vector2 bottomLeft = { 0 };
|
Vector2 bottomLeft = { 0 };
|
||||||
|
|
@ -5183,6 +5078,22 @@ Color ColorAlphaBlend(Color dst, Color src, Color tint)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get color lerp interpolation between two colors, factor [0.0f..1.0f]
|
||||||
|
Color ColorLerp(Color color1, Color color2, float factor)
|
||||||
|
{
|
||||||
|
Color color = { 0 };
|
||||||
|
|
||||||
|
if (factor < 0.0f) factor = 0.0f;
|
||||||
|
else if (factor > 1.0f) factor = 1.0f;
|
||||||
|
|
||||||
|
color.r = (unsigned char)((1.0f - factor)*color1.r + factor*color2.r);
|
||||||
|
color.g = (unsigned char)((1.0f - factor)*color1.g + factor*color2.g);
|
||||||
|
color.b = (unsigned char)((1.0f - factor)*color1.b + factor*color2.b);
|
||||||
|
color.a = (unsigned char)((1.0f - factor)*color1.a + factor*color2.a);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
// Get a Color struct from hexadecimal value
|
// Get a Color struct from hexadecimal value
|
||||||
Color GetColor(unsigned int hexValue)
|
Color GetColor(unsigned int hexValue)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ void SetSaveFileDataCallback(SaveFileDataCallback callback) { saveFileData = cal
|
||||||
void SetLoadFileTextCallback(LoadFileTextCallback callback) { loadFileText = callback; } // Set custom file text loader
|
void SetLoadFileTextCallback(LoadFileTextCallback callback) { loadFileText = callback; } // Set custom file text loader
|
||||||
void SetSaveFileTextCallback(SaveFileTextCallback callback) { saveFileText = callback; } // Set custom file text saver
|
void SetSaveFileTextCallback(SaveFileTextCallback callback) { saveFileText = callback; } // Set custom file text saver
|
||||||
|
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
static AAssetManager *assetManager = NULL; // Android assets manager pointer
|
static AAssetManager *assetManager = NULL; // Android assets manager pointer
|
||||||
static const char *internalDataPath = NULL; // Android internal data path
|
static const char *internalDataPath = NULL; // Android internal data path
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user