Merge branch 'master' of https://github.com/raysan5/raylib into pure
This commit is contained in:
commit
fc96f333a4
|
|
@ -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 |
|
||||||
|
|
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -549,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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -415,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
|
||||||
|
|
||||||
|
|
@ -776,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
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ int main(void)
|
||||||
// Update model animation
|
// Update model animation
|
||||||
ModelAnimation anim = modelAnimations[animIndex];
|
ModelAnimation anim = modelAnimations[animIndex];
|
||||||
animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
|
animCurrentFrame = (animCurrentFrame + 1)%anim.frameCount;
|
||||||
UpdateModelAnimationBoneMatrices(characterModel, anim, animCurrentFrame);
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 5.6 KiB |
|
|
@ -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 |
|
|
@ -3763,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -4691,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",
|
||||||
|
|
@ -5186,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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -6815,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)",
|
||||||
|
|
@ -6908,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -8372,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -8394,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -8989,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -10281,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -10968,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -11343,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -11387,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -11685,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": [
|
||||||
{
|
{
|
||||||
|
|
@ -11874,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": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3589,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"}
|
||||||
|
|
@ -4190,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",
|
||||||
|
|
@ -4550,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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -5339,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)",
|
||||||
|
|
@ -5393,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"}
|
||||||
|
|
@ -6158,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"}
|
||||||
|
|
@ -6174,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"}
|
||||||
|
|
@ -6505,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"}
|
||||||
|
|
@ -7185,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"}
|
||||||
|
|
@ -7539,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"}
|
||||||
|
|
@ -7758,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"}
|
||||||
|
|
@ -7790,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"}
|
||||||
|
|
@ -7980,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"}
|
||||||
|
|
@ -8106,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
|
|
@ -675,7 +675,7 @@
|
||||||
<Param type="unsigned int" name="frames" desc="" />
|
<Param type="unsigned int" name="frames" desc="" />
|
||||||
</Callback>
|
</Callback>
|
||||||
</Callbacks>
|
</Callbacks>
|
||||||
<Functions count="578">
|
<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="" />
|
||||||
|
|
@ -871,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">
|
||||||
|
|
@ -1126,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>
|
||||||
|
|
@ -1269,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>
|
||||||
|
|
@ -1699,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="" />
|
||||||
|
|
@ -1724,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)">
|
||||||
|
|
@ -2109,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)">
|
||||||
|
|
@ -2273,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">
|
||||||
|
|
@ -2613,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)">
|
||||||
|
|
@ -2794,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)">
|
||||||
|
|
@ -2896,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">
|
||||||
|
|
@ -2908,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">
|
||||||
|
|
@ -2988,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">
|
||||||
|
|
@ -3039,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">
|
||||||
|
|
|
||||||
|
|
@ -293,8 +293,6 @@ 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}"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
397
src/build.zig
397
src/build.zig
|
|
@ -1,397 +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 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 => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
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 = 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");
|
|
||||||
|
|
||||||
setDesktopPlatform(raylib, options.platform);
|
|
||||||
},
|
|
||||||
.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");
|
|
||||||
}
|
|
||||||
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 = 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: PlatformBackend = .glfw,
|
|
||||||
shared: bool = false,
|
|
||||||
linux_display_backend: LinuxDisplayBackend = .Both,
|
|
||||||
opengl_version: OpenglVersion = .auto,
|
|
||||||
/// config should be a list of cflags, eg, "-DSUPPORT_CUSTOM_FRAME_CONTROL"
|
|
||||||
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 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 defaults = Options{};
|
|
||||||
const options = Options{
|
|
||||||
.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,
|
|
||||||
.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);
|
|
||||||
}
|
|
||||||
|
|
@ -180,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
|
||||||
|
|
|
||||||
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
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));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -704,7 +704,6 @@ void PollInputEvents(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1234,7 +1234,6 @@ void PollInputEvents(void)
|
||||||
glfwSetWindowShouldClose(platform.handle, GLFW_FALSE);
|
glfwSetWindowShouldClose(platform.handle, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,6 @@ 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__)
|
||||||
|
|
@ -870,9 +869,8 @@ void PollInputEvents(void)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
CORE.Window.resizedLastFrame = false;
|
CORE.Window.resizedLastFrame = false;
|
||||||
|
|
||||||
|
|
||||||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||||
#define RGFW_HOLD_MOUSE (1L<<2)
|
#define RGFW_HOLD_MOUSE (1L<<2)
|
||||||
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 };
|
||||||
|
|
@ -883,10 +881,8 @@ void PollInputEvents(void)
|
||||||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
@ -1196,7 +1192,6 @@ void PollInputEvents(void)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -1253,7 +1248,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);
|
||||||
|
|
|
||||||
|
|
@ -1609,7 +1609,6 @@ int InitPlatform(void)
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// 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");
|
||||||
|
|
|
||||||
|
|
@ -1480,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
|
||||||
|
|
|
||||||
29
src/raylib.h
29
src/raylib.h
|
|
@ -1044,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
|
||||||
|
|
@ -1144,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
|
||||||
|
|
@ -1211,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
|
||||||
|
|
@ -1312,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
|
||||||
|
|
@ -1404,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
|
||||||
|
|
@ -1453,7 +1456,7 @@ RLAPI Font LoadFont(const char *fileName);
|
||||||
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 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)
|
||||||
|
|
@ -1543,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)
|
||||||
|
|
||||||
|
|
@ -1586,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
|
||||||
|
|
@ -1624,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
|
||||||
|
|
@ -1654,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
|
||||||
|
|
@ -1671,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
|
||||||
|
|
|
||||||
265
src/rcore.c
265
src/rcore.c
|
|
@ -1342,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),
|
||||||
|
|
@ -2577,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
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
50
src/rlgl.h
50
src/rlgl.h
|
|
@ -347,7 +347,6 @@
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS
|
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS
|
||||||
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
|
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
|
||||||
|
|
@ -357,7 +356,6 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -2474,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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -1259,7 +1274,6 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS] = 0; // Vertex buffer: boneWeights
|
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS] = 0; // Vertex buffer: boneWeights
|
||||||
#endif
|
#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();
|
||||||
rlEnableVertexArray(mesh->vaoId);
|
rlEnableVertexArray(mesh->vaoId);
|
||||||
|
|
@ -1348,7 +1362,7 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
|
||||||
if (mesh->boneIds != NULL)
|
if (mesh->boneIds != NULL)
|
||||||
{
|
{
|
||||||
// Enable vertex attribute: boneIds (shader-location = 6)
|
// 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);
|
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);
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, 4, RL_UNSIGNED_BYTE, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS);
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS);
|
||||||
|
|
@ -1364,7 +1378,7 @@ void UploadMesh(Mesh *mesh, bool dynamic)
|
||||||
|
|
||||||
if (mesh->boneWeights != NULL)
|
if (mesh->boneWeights != NULL)
|
||||||
{
|
{
|
||||||
// Enable vertex attribute: boneWeights (shader-location = 7)
|
// Enable vertex attribute: boneWeights (shader-location = 8)
|
||||||
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS] = rlLoadVertexBuffer(mesh->boneWeights, mesh->vertexCount*4*sizeof(float), dynamic);
|
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);
|
rlSetVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, 4, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS);
|
rlEnableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS);
|
||||||
|
|
@ -2098,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)
|
||||||
|
|
@ -2185,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5229,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));\
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5680,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
|
||||||
|
|
@ -5702,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
|
||||||
|
|
||||||
|
|
@ -5750,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);
|
||||||
|
|
@ -5770,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;
|
||||||
|
|
@ -6093,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;
|
||||||
|
|
@ -6228,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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
22
src/rtext.c
22
src/rtext.c
|
|
@ -581,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 for 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
|
||||||
|
|
@ -1302,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
|
||||||
|
|
@ -1930,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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
164
src/rtextures.c
164
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;
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -4988,8 +4880,6 @@ Vector3 ColorToHSV(Color color)
|
||||||
return hsv;
|
return hsv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Get a Color from HSV values
|
// Get a Color from HSV values
|
||||||
// Implementation reference: https://en.wikipedia.org/wiki/HSL_and_HSV#Alternative_HSV_conversion
|
// Implementation reference: https://en.wikipedia.org/wiki/HSL_and_HSV#Alternative_HSV_conversion
|
||||||
// NOTE: Color->HSV->Color conversion will not yield exactly the same color due to rounding errors
|
// NOTE: Color->HSV->Color conversion will not yield exactly the same color due to rounding errors
|
||||||
|
|
|
||||||
|
|
@ -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