diff --git a/build.zig b/build.zig
index 501d7a229..409c57ab5 100644
--- a/build.zig
+++ b/build.zig
@@ -153,18 +153,14 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
try raylib_flags_arr.appendSlice(&config_h_flags);
}
- const raylib = if (options.shared)
- b.addSharedLibrary(.{
- .name = "raylib",
+ const raylib = b.addLibrary(.{
+ .name = "raylib",
+ .linkage = if (options.shared) .dynamic else .static,
+ .root_module = b.createModule(.{
.target = target,
.optimize = optimize,
- })
- else
- b.addStaticLibrary(.{
- .name = "raylib",
- .target = target,
- .optimize = optimize,
- });
+ }),
+ });
raylib.linkLibC();
// No GLFW required on PLATFORM_DRM
@@ -550,10 +546,13 @@ fn addExamples(
if (std.mem.eql(u8, "core_loading_thread", name) and target.result.os.tag == .windows) continue;
if (target.result.os.tag == .emscripten) {
- const exe_lib = b.addStaticLibrary(.{
+ const exe_lib = b.addLibrary(.{
.name = name,
- .target = target,
- .optimize = optimize,
+ .linkage = .static,
+ .root_module = b.createModule(.{
+ .target = target,
+ .optimize = optimize,
+ }),
});
exe_lib.addCSourceFile(.{
.file = b.path(path),
@@ -633,8 +632,10 @@ fn addExamples(
} else {
const exe = b.addExecutable(.{
.name = name,
- .target = target,
- .optimize = optimize,
+ .root_module = b.createModule(.{
+ .target = target,
+ .optimize = optimize,
+ }),
});
exe.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
exe.linkLibC();
diff --git a/cmake/LibraryConfigurations.cmake b/cmake/LibraryConfigurations.cmake
index 00dda033a..e4655500e 100644
--- a/cmake/LibraryConfigurations.cmake
+++ b/cmake/LibraryConfigurations.cmake
@@ -101,10 +101,37 @@ elseif ("${PLATFORM}" MATCHES "DRM")
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread m dl)
elseif ("${PLATFORM}" MATCHES "SDL")
- find_package(SDL2 REQUIRED)
- set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
- set(LIBS_PRIVATE SDL2::SDL2)
+ # First, check if SDL is included as a subdirectory
+ if(TARGET SDL3::SDL3)
+ message(STATUS "Using SDL3 from subdirectory")
+ set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
+ set(LIBS_PRIVATE SDL3::SDL3)
+ add_compile_definitions(USING_SDL3_PROJECT)
+ elseif(TARGET SDL2::SDL2)
+ message(STATUS "Using SDL2 from subdirectory")
+ set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
+ set(LIBS_PRIVATE SDL2::SDL2)
+ add_compile_definitions(USING_SDL2_PROJECT)
+ else()
+ # No SDL added via add_subdirectory(), try find_package()
+ message(STATUS "No SDL target from subdirectory, searching via find_package()...")
+ # First try SDL3
+ find_package(SDL3 QUIET)
+ if(SDL3_FOUND)
+ message(STATUS "Found SDL3 via find_package()")
+ set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
+ set(LIBS_PRIVATE SDL3::SDL3)
+ add_compile_definitions(USING_SDL3_PACKAGE)
+ else()
+ # Fallback to SDL2
+ find_package(SDL2 REQUIRED)
+ message(STATUS "Found SDL2 via find_package()")
+ set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
+ set(LIBS_PRIVATE SDL2::SDL2)
+ add_compile_definitions(USING_SDL2_PACKAGE)
+ endif()
+ endif()
endif ()
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
diff --git a/examples/Makefile b/examples/Makefile
index 32a3a75ab..b5b6ef2bc 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -548,7 +548,8 @@ SHAPES = \
shapes/shapes_rectangle_scaling \
shapes/shapes_splines_drawing \
shapes/shapes_top_down_lights \
- shapes/shapes_digital_clock
+ shapes/shapes_digital_clock \
+ shapes/shapes_double_pendulum
TEXTURES = \
textures/textures_background_scrolling \
diff --git a/examples/Makefile.Web b/examples/Makefile.Web
index 35ae70a18..ee5564599 100644
--- a/examples/Makefile.Web
+++ b/examples/Makefile.Web
@@ -430,7 +430,8 @@ SHAPES = \
shapes/shapes_rectangle_scaling \
shapes/shapes_splines_drawing \
shapes/shapes_top_down_lights \
- shapes/shapes_digital_clock
+ shapes/shapes_digital_clock \
+ shapes/shapes_double_pendulum
TEXTURES = \
textures/textures_background_scrolling \
@@ -731,6 +732,9 @@ shapes/shapes_top_down_lights: shapes/shapes_top_down_lights.c
shapes/shapes_rectangle_advanced: shapes/shapes_rectangle_advanced.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+shapes/shapes_double_pendulum: shapes/shapes_double_pendulum.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
+
# Compile TEXTURES examples
textures/textures_background_scrolling: textures/textures_background_scrolling.c
diff --git a/examples/README.md b/examples/README.md
index 7553ad113..e075facbe 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -86,38 +86,39 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| 52 | [shapes_rectangle_advanced](shapes/shapes_rectangle_advanced.c) |
| ⭐️⭐️⭐️⭐️ | 5.5 | 5.5 | [Everton Jr.](https://github.com/evertonse) |
| 53 | [shapes_splines_drawing](shapes/shapes_splines_drawing.c) |
| ⭐️⭐️⭐️☆ | 5.0 | 5.0 | [Ray](https://github.com/raysan5) |
| 54 | [shapes_digital_clock](shapes/shapes_digital_clock.c) |
| ⭐️⭐️☆☆ | 5.5 | 5.5 | [Hamza RAHAL](https://github.com/rhmz-rhl) |
+| 55 | [shapes_double_pendulum](shapes/shapes_double_pendulum.c) |
| ⭐️⭐️☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) |
### category: textures
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/textures.c) modul
| ## | example | image | difficulty
level | version
created | last version
updated | original
developer |
|----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
-| 55 | [textures_logo_raylib](textures/textures_logo_raylib.c) |
| ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
-| 56 | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
-| 57 | [textures_image_drawing](textures/textures_image_drawing.c) |
| ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
-| 58 | [textures_image_generation](textures/textures_image_generation.c) |
| ⭐️⭐️☆☆ | 1.8 | 1.8 | [Wilhem Barbier](https://github.com/nounoursheureux) |
-| 59 | [textures_image_loading](textures/textures_image_loading.c) |
| ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
-| 60 | [textures_image_processing](textures/textures_image_processing.c) |
| ⭐️⭐️⭐️☆ | 1.4 | 3.5 | [Ray](https://github.com/raysan5) |
-| 61 | [textures_image_text](textures/textures_image_text.c) |
| ⭐️⭐️☆☆ | 1.8 | 4.0 | [Ray](https://github.com/raysan5) |
-| 62 | [textures_to_image](textures/textures_to_image.c) |
| ⭐️☆☆☆ | 1.3 | 4.0 | [Ray](https://github.com/raysan5) |
-| 63 | [textures_raw_data](textures/textures_raw_data.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
-| 64 | [textures_particles_blending](textures/textures_particles_blending.c) |
| ⭐️☆☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
-| 65 | [textures_npatch_drawing](textures/textures_npatch_drawing.c) |
| ⭐️⭐️⭐️☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) |
-| 66 | [textures_background_scrolling](textures/textures_background_scrolling.c) |
| ⭐️☆☆☆ | 2.0 | 2.5 | [Ray](https://github.com/raysan5) |
-| 67 | [textures_sprite_anim](textures/textures_sprite_anim.c) |
| ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
-| 68 | [textures_sprite_button](textures/textures_sprite_button.c) |
| ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
-| 69 | [textures_sprite_explosion](textures/textures_sprite_explosion.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
-| 70 | [textures_bunnymark](textures/textures_bunnymark.c) |
| ⭐️⭐️⭐️☆ | 1.6 | 2.5 | [Ray](https://github.com/raysan5) |
-| 71 | [textures_mouse_painting](textures/textures_mouse_painting.c) |
| ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
-| 72 | [textures_blend_modes](textures/textures_blend_modes.c) |
| ⭐️☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) |
-| 73 | [textures_draw_tiled](textures/textures_draw_tiled.c) |
| ⭐️⭐️⭐️☆ | 3.0 | 4.2 | [Vlad Adrian](https://github.com/demizdor) |
-| 74 | [textures_polygon](textures/textures_polygon.c) |
| ⭐️☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
-| 75 | [textures_fog_of_war](textures/textures_fog_of_war.c) |
| ⭐️⭐️⭐️☆ | 4.2 | 4.2 | [Ray](https://github.com/raysan5) |
-| 76 | [textures_gif_player](textures/textures_gif_player.c) |
| ⭐️⭐️⭐️☆ | 4.2 | 4.2 | [Ray](https://github.com/raysan5) |
-| 77 | [textures_image_kernel](textures/textures_image_kernel.c) |
| ⭐️⭐️⭐️⭐️ | 1.3 | 1.3 | [Karim Salem](https://github.com/kimo-s) |
-| 78 | [textures_image_channel](textures/textures_image_channel.c) |
| ⭐️⭐️☆☆ | 5.1-dev | 5.1-dev | [Bruno Cabral](https://github.com/brccabral) |
-| 79 | [textures_image_rotate](textures/textures_image_rotate.c) |
| ⭐️⭐️☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
-| 80 | [textures_textured_curve](textures/textures_textured_curve.c) |
| ⭐️⭐️⭐️☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
+| 56 | [textures_logo_raylib](textures/textures_logo_raylib.c) |
| ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
+| 57 | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
+| 58 | [textures_image_drawing](textures/textures_image_drawing.c) |
| ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
+| 59 | [textures_image_generation](textures/textures_image_generation.c) |
| ⭐️⭐️☆☆ | 1.8 | 1.8 | [Wilhem Barbier](https://github.com/nounoursheureux) |
+| 60 | [textures_image_loading](textures/textures_image_loading.c) |
| ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
+| 61 | [textures_image_processing](textures/textures_image_processing.c) |
| ⭐️⭐️⭐️☆ | 1.4 | 3.5 | [Ray](https://github.com/raysan5) |
+| 62 | [textures_image_text](textures/textures_image_text.c) |
| ⭐️⭐️☆☆ | 1.8 | 4.0 | [Ray](https://github.com/raysan5) |
+| 63 | [textures_to_image](textures/textures_to_image.c) |
| ⭐️☆☆☆ | 1.3 | 4.0 | [Ray](https://github.com/raysan5) |
+| 64 | [textures_raw_data](textures/textures_raw_data.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
+| 65 | [textures_particles_blending](textures/textures_particles_blending.c) |
| ⭐️☆☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
+| 66 | [textures_npatch_drawing](textures/textures_npatch_drawing.c) |
| ⭐️⭐️⭐️☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) |
+| 67 | [textures_background_scrolling](textures/textures_background_scrolling.c) |
| ⭐️☆☆☆ | 2.0 | 2.5 | [Ray](https://github.com/raysan5) |
+| 68 | [textures_sprite_anim](textures/textures_sprite_anim.c) |
| ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
+| 69 | [textures_sprite_button](textures/textures_sprite_button.c) |
| ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
+| 70 | [textures_sprite_explosion](textures/textures_sprite_explosion.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
+| 71 | [textures_bunnymark](textures/textures_bunnymark.c) |
| ⭐️⭐️⭐️☆ | 1.6 | 2.5 | [Ray](https://github.com/raysan5) |
+| 72 | [textures_mouse_painting](textures/textures_mouse_painting.c) |
| ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
+| 73 | [textures_blend_modes](textures/textures_blend_modes.c) |
| ⭐️☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) |
+| 74 | [textures_draw_tiled](textures/textures_draw_tiled.c) |
| ⭐️⭐️⭐️☆ | 3.0 | 4.2 | [Vlad Adrian](https://github.com/demizdor) |
+| 75 | [textures_polygon](textures/textures_polygon.c) |
| ⭐️☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
+| 76 | [textures_fog_of_war](textures/textures_fog_of_war.c) |
| ⭐️⭐️⭐️☆ | 4.2 | 4.2 | [Ray](https://github.com/raysan5) |
+| 77 | [textures_gif_player](textures/textures_gif_player.c) |
| ⭐️⭐️⭐️☆ | 4.2 | 4.2 | [Ray](https://github.com/raysan5) |
+| 78 | [textures_image_kernel](textures/textures_image_kernel.c) |
| ⭐️⭐️⭐️⭐️ | 1.3 | 1.3 | [Karim Salem](https://github.com/kimo-s) |
+| 79 | [textures_image_channel](textures/textures_image_channel.c) |
| ⭐️⭐️☆☆ | 5.1-dev | 5.1-dev | [Bruno Cabral](https://github.com/brccabral) |
+| 80 | [textures_image_rotate](textures/textures_image_rotate.c) |
| ⭐️⭐️☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
+| 81 | [textures_textured_curve](textures/textures_textured_curve.c) |
| ⭐️⭐️⭐️☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
### category: text
@@ -125,18 +126,18 @@ Examples using raylib text functionality, including sprite fonts loading/generat
| ## | example | image | difficulty
level | version
created | last version
updated | original
developer |
|----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
-| 81 | [text_raylib_fonts](text/text_raylib_fonts.c) |
| ⭐️☆☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
-| 82 | [text_font_spritefont](text/text_font_spritefont.c) |
| ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
-| 83 | [text_font_filters](text/text_font_filters.c) |
| ⭐️⭐️☆☆ | 1.3 | 4.2 | [Ray](https://github.com/raysan5) |
-| 84 | [text_font_loading](text/text_font_loading.c) |
| ⭐️☆☆☆ | 1.4 | 3.0 | [Ray](https://github.com/raysan5) |
-| 85 | [text_font_sdf](text/text_font_sdf.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 4.0 | [Ray](https://github.com/raysan5) |
-| 86 | [text_format_text](text/text_format_text.c) |
| ⭐️☆☆☆ | 1.1 | 3.0 | [Ray](https://github.com/raysan5) |
-| 87 | [text_input_box](text/text_input_box.c) |
| ⭐️⭐️☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
-| 88 | [text_writing_anim](text/text_writing_anim.c) |
| ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
-| 89 | [text_rectangle_bounds](text/text_rectangle_bounds.c) |
| ⭐️⭐️⭐️⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
-| 90 | [text_unicode](text/text_unicode.c) |
| ⭐️⭐️⭐️⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
-| 91 | [text_draw_3d](text/text_draw_3d.c) |
| ⭐️⭐️⭐️⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
-| 92 | [text_codepoints_loading](text/text_codepoints_loading.c) |
| ⭐️⭐️⭐️☆ | 4.2 | 4.2 | [Ray](https://github.com/raysan5) |
+| 82 | [text_raylib_fonts](text/text_raylib_fonts.c) |
| ⭐️☆☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
+| 83 | [text_font_spritefont](text/text_font_spritefont.c) |
| ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
+| 84 | [text_font_filters](text/text_font_filters.c) |
| ⭐️⭐️☆☆ | 1.3 | 4.2 | [Ray](https://github.com/raysan5) |
+| 85 | [text_font_loading](text/text_font_loading.c) |
| ⭐️☆☆☆ | 1.4 | 3.0 | [Ray](https://github.com/raysan5) |
+| 86 | [text_font_sdf](text/text_font_sdf.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 4.0 | [Ray](https://github.com/raysan5) |
+| 87 | [text_format_text](text/text_format_text.c) |
| ⭐️☆☆☆ | 1.1 | 3.0 | [Ray](https://github.com/raysan5) |
+| 88 | [text_input_box](text/text_input_box.c) |
| ⭐️⭐️☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
+| 89 | [text_writing_anim](text/text_writing_anim.c) |
| ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
+| 90 | [text_rectangle_bounds](text/text_rectangle_bounds.c) |
| ⭐️⭐️⭐️⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
+| 91 | [text_unicode](text/text_unicode.c) |
| ⭐️⭐️⭐️⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
+| 92 | [text_draw_3d](text/text_draw_3d.c) |
| ⭐️⭐️⭐️⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
+| 93 | [text_codepoints_loading](text/text_codepoints_loading.c) |
| ⭐️⭐️⭐️☆ | 4.2 | 4.2 | [Ray](https://github.com/raysan5) |
### category: models
@@ -144,29 +145,29 @@ Examples using raylib models functionality, including models loading/generation
| ## | example | image | difficulty
level | version
created | last version
updated | original
developer |
|----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
-| 93 | [models_animation](models/models_animation.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.5 | [Culacant](https://github.com/culacant) |
-| 94 | [models_billboard](models/models_billboard.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
-| 95 | [models_box_collisions](models/models_box_collisions.c) |
| ⭐️☆☆☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
-| 96 | [models_cubicmap](models/models_cubicmap.c) |
| ⭐️⭐️☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
-| 97 | [models_first_person_maze](models/models_first_person_maze.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
-| 98 | [models_geometric_shapes](models/models_geometric_shapes.c) |
| ⭐️☆☆☆ | 1.0 | 3.5 | [Ray](https://github.com/raysan5) |
-| 99 | [models_mesh_generation](models/models_mesh_generation.c) |
| ⭐️⭐️☆☆ | 1.8 | 4.0 | [Ray](https://github.com/raysan5) |
-| 100 | [models_mesh_picking](models/models_mesh_picking.c) |
| ⭐️⭐️⭐️☆ | 1.7 | 4.0 | [Joel Davis](https://github.com/joeld42) |
-| 101 | [models_loading](models/models_loading.c) |
| ⭐️☆☆☆ | 2.0 | 4.2 | [Ray](https://github.com/raysan5) |
-| 102 | [models_loading_gltf](models/models_loading_gltf.c) |
| ⭐️☆☆☆ | 3.7 | 4.2 | [Ray](https://github.com/raysan5) |
-| 103 | [models_loading_vox](models/models_loading_vox.c) |
| ⭐️☆☆☆ | 4.0 | 4.0 | [Johann Nadalutti](https://github.com/procfxgen) |
-| 104 | [models_loading_m3d](models/models_loading_m3d.c) |
| ⭐️⭐️☆☆ | 4.5 | 4.5 | [bzt](https://bztsrc.gitlab.io/model3d) |
-| 105 | [models_orthographic_projection](models/models_orthographic_projection.c) |
| ⭐️☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) |
-| 106 | [models_point_rendering](models/models_point_rendering.c) |
| ⭐️⭐️⭐️☆ | 5.0 | 5.0 | [Reese Gallagher](https://github.com/satchelfrost) |
-| 107 | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) |
| ⭐️⭐️⭐️⭐️ | 2.5 | 4.0 | [Ray](https://github.com/raysan5) |
-| 108 | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) |
| ⭐️⭐️☆☆ | 1.8 | 4.0 | [Berni](https://github.com/Berni8k) |
-| 109 | [models_waving_cubes](models/models_waving_cubes.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Codecat](https://github.com/codecat) |
-| 110 | [models_heightmap](models/models_heightmap.c) |
| ⭐️☆☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
-| 111 | [models_skybox](models/models_skybox.c) |
| ⭐️⭐️☆☆ | 1.8 | 4.0 | [Ray](https://github.com/raysan5) |
-| 112 | [models_draw_cube_texture](models/models_draw_cube_texture.c) |
| ⭐️⭐️☆☆ | 4.5 | 4.5 | [Ray](https://github.com/raysan5) |
-| 113 | [models_gpu_skinning](models/models_gpu_skinning.c) |
| ⭐️⭐️⭐️☆ | 4.5 | 4.5 | [Daniel Holden](https://github.com/orangeduck) |
-| 114 | [models_bone_socket](models/models_bone_socket.c) |
| ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
-| 115 | [models_tesseract_view](models/models_tesseract_view.c) |
| ⭐️⭐️☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) |
+| 94 | [models_animation](models/models_animation.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.5 | [Culacant](https://github.com/culacant) |
+| 95 | [models_billboard](models/models_billboard.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
+| 96 | [models_box_collisions](models/models_box_collisions.c) |
| ⭐️☆☆☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
+| 97 | [models_cubicmap](models/models_cubicmap.c) |
| ⭐️⭐️☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
+| 98 | [models_first_person_maze](models/models_first_person_maze.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
+| 99 | [models_geometric_shapes](models/models_geometric_shapes.c) |
| ⭐️☆☆☆ | 1.0 | 3.5 | [Ray](https://github.com/raysan5) |
+| 100 | [models_mesh_generation](models/models_mesh_generation.c) |
| ⭐️⭐️☆☆ | 1.8 | 4.0 | [Ray](https://github.com/raysan5) |
+| 101 | [models_mesh_picking](models/models_mesh_picking.c) |
| ⭐️⭐️⭐️☆ | 1.7 | 4.0 | [Joel Davis](https://github.com/joeld42) |
+| 102 | [models_loading](models/models_loading.c) |
| ⭐️☆☆☆ | 2.0 | 4.2 | [Ray](https://github.com/raysan5) |
+| 103 | [models_loading_gltf](models/models_loading_gltf.c) |
| ⭐️☆☆☆ | 3.7 | 4.2 | [Ray](https://github.com/raysan5) |
+| 104 | [models_loading_vox](models/models_loading_vox.c) |
| ⭐️☆☆☆ | 4.0 | 4.0 | [Johann Nadalutti](https://github.com/procfxgen) |
+| 105 | [models_loading_m3d](models/models_loading_m3d.c) |
| ⭐️⭐️☆☆ | 4.5 | 4.5 | [bzt](https://bztsrc.gitlab.io/model3d) |
+| 106 | [models_orthographic_projection](models/models_orthographic_projection.c) |
| ⭐️☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) |
+| 107 | [models_point_rendering](models/models_point_rendering.c) |
| ⭐️⭐️⭐️☆ | 5.0 | 5.0 | [Reese Gallagher](https://github.com/satchelfrost) |
+| 108 | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) |
| ⭐️⭐️⭐️⭐️ | 2.5 | 4.0 | [Ray](https://github.com/raysan5) |
+| 109 | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) |
| ⭐️⭐️☆☆ | 1.8 | 4.0 | [Berni](https://github.com/Berni8k) |
+| 110 | [models_waving_cubes](models/models_waving_cubes.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Codecat](https://github.com/codecat) |
+| 111 | [models_heightmap](models/models_heightmap.c) |
| ⭐️☆☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
+| 112 | [models_skybox](models/models_skybox.c) |
| ⭐️⭐️☆☆ | 1.8 | 4.0 | [Ray](https://github.com/raysan5) |
+| 113 | [models_draw_cube_texture](models/models_draw_cube_texture.c) |
| ⭐️⭐️☆☆ | 4.5 | 4.5 | [Ray](https://github.com/raysan5) |
+| 114 | [models_gpu_skinning](models/models_gpu_skinning.c) |
| ⭐️⭐️⭐️☆ | 4.5 | 4.5 | [Daniel Holden](https://github.com/orangeduck) |
+| 115 | [models_bone_socket](models/models_bone_socket.c) |
| ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
+| 116 | [models_tesseract_view](models/models_tesseract_view.c) |
| ⭐️⭐️☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) |
### category: shaders
@@ -174,34 +175,34 @@ Examples using raylib shaders functionality, including shaders loading, paramete
| ## | example | image | difficulty
level | version
created | last version
updated | original
developer |
|----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
-| 116 | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) |
| ⭐️⭐️⭐️⭐️ | 3.0 | 4.2 | [Chris Camacho](https://github.com/chriscamacho) |
-| 117 | [shaders_model_shader](shaders/shaders_model_shader.c) |
| ⭐️⭐️☆☆ | 1.3 | 3.7 | [Ray](https://github.com/raysan5) |
-| 118 | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) |
| ⭐️⭐️☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
-| 119 | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) |
| ⭐️⭐️☆☆ | 1.3 | 4.0 | [Ray](https://github.com/raysan5) |
-| 120 | [shaders_postprocessing](shaders/shaders_postprocessing.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 4.0 | [Ray](https://github.com/raysan5) |
-| 121 | [shaders_palette_switch](shaders/shaders_palette_switch.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) |
-| 122 | [shaders_raymarching](shaders/shaders_raymarching.c) |
| ⭐️⭐️⭐️⭐️ | 2.0 | 4.2 | [Ray](https://github.com/raysan5) |
-| 123 | [shaders_texture_drawing](shaders/shaders_texture_drawing.c) |
| ⭐️⭐️☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/ciessielski) |
-| 124 | [shaders_texture_outline](shaders/shaders_texture_outline.c) |
| ⭐️⭐️⭐️☆ | 4.0 | 4.0 | [Samuel Skiff](https://github.com/GoldenThumbs) |
-| 125 | [shaders_texture_waves](shaders/shaders_texture_waves.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) |
-| 126 | [shaders_julia_set](shaders/shaders_julia_set.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 4.0 | [Josh Colclough](https://github.com/joshcol9232) |
-| 127 | [shaders_eratosthenes](shaders/shaders_eratosthenes.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 4.0 | [ProfJski](https://github.com/ProfJski) |
-| 128 | [shaders_fog](shaders/shaders_fog.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
-| 129 | [shaders_simple_mask](shaders/shaders_simple_mask.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
-| 130 | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) |
| ⭐️⭐️⭐️☆ | 3.0 | 3.5 | [Ray](https://github.com/raysan5) |
-| 131 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) |
| ⭐️⭐️⭐️⭐️ | 3.7 | 4.2 | [seanpringle](https://github.com/seanpringle) |
-| 132 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) |
| ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
-| 133 | [shaders_spotlight](shaders/shaders_spotlight.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
-| 134 | [shaders_deferred_render](shaders/shaders_deferred_render.c) |
| ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
-| 135 | [shaders_hybrid_render](shaders/shaders_hybrid_render.c) |
| ⭐️⭐️⭐️⭐️ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
-| 136 | [shaders_texture_tiling](shaders/shaders_texture_tiling.c) |
| ⭐️⭐️☆☆ | 4.5 | 4.5 | [Luis Almeida](https://github.com/luis605) |
-| 137 | [shaders_shadowmap](shaders/shaders_shadowmap.c) |
| ⭐️⭐️⭐️⭐️ | 5.0 | 5.0 | [TheManTheMythTheGameDev](https://github.com/TheManTheMythTheGameDev) |
-| 138 | [shaders_vertex_displacement](shaders/shaders_vertex_displacement.c) |
| ⭐️⭐️⭐️☆ | 5.0 | 4.5 | [Alex ZH](https://github.com/ZzzhHe) |
-| 139 | [shaders_write_depth](shaders/shaders_write_depth.c) |
| ⭐️⭐️☆☆ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
-| 140 | [shaders_basic_pbr](shaders/shaders_basic_pbr.c) |
| ⭐️⭐️⭐️⭐️ | 5.0 | 5.1-dev | [Afan OLOVCIC](https://github.com/_DevDad) |
-| 141 | [shaders_lightmap](shaders/shaders_lightmap.c) |
| ⭐️⭐️⭐️☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
-| 142 | [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) |
| ⭐️⭐️⭐️☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) |
-| 143 | [shaders_view_depth](shaders/shaders_view_depth.c) |
| ⭐️⭐️⭐️☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) |
+| 117 | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) |
| ⭐️⭐️⭐️⭐️ | 3.0 | 4.2 | [Chris Camacho](https://github.com/chriscamacho) |
+| 118 | [shaders_model_shader](shaders/shaders_model_shader.c) |
| ⭐️⭐️☆☆ | 1.3 | 3.7 | [Ray](https://github.com/raysan5) |
+| 119 | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) |
| ⭐️⭐️☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
+| 120 | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) |
| ⭐️⭐️☆☆ | 1.3 | 4.0 | [Ray](https://github.com/raysan5) |
+| 121 | [shaders_postprocessing](shaders/shaders_postprocessing.c) |
| ⭐️⭐️⭐️☆ | 1.3 | 4.0 | [Ray](https://github.com/raysan5) |
+| 122 | [shaders_palette_switch](shaders/shaders_palette_switch.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) |
+| 123 | [shaders_raymarching](shaders/shaders_raymarching.c) |
| ⭐️⭐️⭐️⭐️ | 2.0 | 4.2 | [Ray](https://github.com/raysan5) |
+| 124 | [shaders_texture_drawing](shaders/shaders_texture_drawing.c) |
| ⭐️⭐️☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/ciessielski) |
+| 125 | [shaders_texture_outline](shaders/shaders_texture_outline.c) |
| ⭐️⭐️⭐️☆ | 4.0 | 4.0 | [Samuel Skiff](https://github.com/GoldenThumbs) |
+| 126 | [shaders_texture_waves](shaders/shaders_texture_waves.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) |
+| 127 | [shaders_julia_set](shaders/shaders_julia_set.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 4.0 | [Josh Colclough](https://github.com/joshcol9232) |
+| 128 | [shaders_eratosthenes](shaders/shaders_eratosthenes.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 4.0 | [ProfJski](https://github.com/ProfJski) |
+| 129 | [shaders_fog](shaders/shaders_fog.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
+| 130 | [shaders_simple_mask](shaders/shaders_simple_mask.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
+| 131 | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) |
| ⭐️⭐️⭐️☆ | 3.0 | 3.5 | [Ray](https://github.com/raysan5) |
+| 132 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) |
| ⭐️⭐️⭐️⭐️ | 3.7 | 4.2 | [seanpringle](https://github.com/seanpringle) |
+| 133 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) |
| ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
+| 134 | [shaders_spotlight](shaders/shaders_spotlight.c) |
| ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/chriscamacho) |
+| 135 | [shaders_deferred_render](shaders/shaders_deferred_render.c) |
| ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
+| 136 | [shaders_hybrid_render](shaders/shaders_hybrid_render.c) |
| ⭐️⭐️⭐️⭐️ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
+| 137 | [shaders_texture_tiling](shaders/shaders_texture_tiling.c) |
| ⭐️⭐️☆☆ | 4.5 | 4.5 | [Luis Almeida](https://github.com/luis605) |
+| 138 | [shaders_shadowmap](shaders/shaders_shadowmap.c) |
| ⭐️⭐️⭐️⭐️ | 5.0 | 5.0 | [TheManTheMythTheGameDev](https://github.com/TheManTheMythTheGameDev) |
+| 139 | [shaders_vertex_displacement](shaders/shaders_vertex_displacement.c) |
| ⭐️⭐️⭐️☆ | 5.0 | 4.5 | [Alex ZH](https://github.com/ZzzhHe) |
+| 140 | [shaders_write_depth](shaders/shaders_write_depth.c) |
| ⭐️⭐️☆☆ | 4.2 | 4.2 | [Buğra Alptekin Sarı](https://github.com/BugraAlptekinSari) |
+| 141 | [shaders_basic_pbr](shaders/shaders_basic_pbr.c) |
| ⭐️⭐️⭐️⭐️ | 5.0 | 5.1-dev | [Afan OLOVCIC](https://github.com/_DevDad) |
+| 142 | [shaders_lightmap](shaders/shaders_lightmap.c) |
| ⭐️⭐️⭐️☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
+| 143 | [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) |
| ⭐️⭐️⭐️☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) |
+| 144 | [shaders_view_depth](shaders/shaders_view_depth.c) |
| ⭐️⭐️⭐️☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) |
### category: audio
@@ -209,26 +210,26 @@ Examples using raylib audio functionality, including sound/music loading and pla
| ## | example | image | difficulty
level | version
created | last version
updated | original
developer |
|----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
-| 144 | [audio_module_playing](audio/audio_module_playing.c) |
| ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
-| 145 | [audio_music_stream](audio/audio_music_stream.c) |
| ⭐️☆☆☆ | 1.3 | 4.2 | [Ray](https://github.com/raysan5) |
-| 146 | [audio_raw_stream](audio/audio_raw_stream.c) |
| ⭐️⭐️⭐️☆ | 1.6 | 4.2 | [Ray](https://github.com/raysan5) |
-| 147 | [audio_sound_loading](audio/audio_sound_loading.c) |
| ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
-| 148 | [audio_mixed_processor](audio/audio_mixed_processor.c) |
| ⭐️⭐️⭐️⭐️ | 4.2 | 4.2 | [hkc](https://github.com/hatkidchan) |
-| 149 | [audio_stream_effects](audio/audio_stream_effects.c) |
| ⭐️⭐️⭐️⭐️ | 4.2 | 5.0 | [Ray](https://github.com/raysan5) |
-| 150 [audio_sound_multi](audio/audio_sound_multi.c) |
| ⭐️⭐️☆☆ | 4.6 | 4.6 | [Jeffery Myers](https://github.com/JeffM2501) |
-| 151 | [audio_sound_positioning](audio/audio_sound_positioning.c) |
| ⭐️⭐️☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
+| 145 | [audio_module_playing](audio/audio_module_playing.c) |
| ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
+| 146 | [audio_music_stream](audio/audio_music_stream.c) |
| ⭐️☆☆☆ | 1.3 | 4.2 | [Ray](https://github.com/raysan5) |
+| 147 | [audio_raw_stream](audio/audio_raw_stream.c) |
| ⭐️⭐️⭐️☆ | 1.6 | 4.2 | [Ray](https://github.com/raysan5) |
+| 148 | [audio_sound_loading](audio/audio_sound_loading.c) |
| ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
+| 149 | [audio_mixed_processor](audio/audio_mixed_processor.c) |
| ⭐️⭐️⭐️⭐️ | 4.2 | 4.2 | [hkc](https://github.com/hatkidchan) |
+| 150 | [audio_stream_effects](audio/audio_stream_effects.c) |
| ⭐️⭐️⭐️⭐️ | 4.2 | 5.0 | [Ray](https://github.com/raysan5) |
+| 151 [audio_sound_multi](audio/audio_sound_multi.c) |
| ⭐️⭐️☆☆ | 4.6 | 4.6 | [Jeffery Myers](https://github.com/JeffM2501) |
+| 152 | [audio_sound_positioning](audio/audio_sound_positioning.c) |
| ⭐️⭐️☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
### category: others
-Ex150amples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries.
+Ex151amples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries.
| ## | example | image | difficulty
level | version
created | last version
updated | original
developer |
|----|----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
-| 152 | [rlgl_standalone](others/rlgl_standalone.c) |
| ⭐️⭐️⭐️⭐️ | 1.6 | 4.0 | [Ray](https://github.com/raysan5) |
-| 153 | [rlgl_compute_shader](others/rlgl_compute_shader.c) |
| ⭐️⭐️⭐️⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
-| 154 | [easings_testbed](others/easings_testbed.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
-| 155 | [raylib_opengl_interop](others/raylib_opengl_interop.c) |
| ⭐️⭐️⭐️⭐️ | 3.8 | 4.0 | [Stephan Soller](https://github.com/arkanis) |
-| 156 | [embedded_files_loading](others/embedded_files_loading.c) |
| ⭐️⭐️☆☆ | 3.0 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
-| 157 | [raymath_vector_angle](others/raymath_vector_angle.c) |
| ⭐️⭐️☆☆ | 1.0 | 4.6 | [Ray](https://github.com/raysan5) |
+| 153 | [rlgl_standalone](others/rlgl_standalone.c) |
| ⭐️⭐️⭐️⭐️ | 1.6 | 4.0 | [Ray](https://github.com/raysan5) |
+| 154 | [rlgl_compute_shader](others/rlgl_compute_shader.c) |
| ⭐️⭐️⭐️⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
+| 155 | [easings_testbed](others/easings_testbed.c) |
| ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
+| 156 | [raylib_opengl_interop](others/raylib_opengl_interop.c) |
| ⭐️⭐️⭐️⭐️ | 3.8 | 4.0 | [Stephan Soller](https://github.com/arkanis) |
+| 157 | [embedded_files_loading](others/embedded_files_loading.c) |
| ⭐️⭐️☆☆ | 3.0 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
+| 158 | [raymath_vector_angle](others/raymath_vector_angle.c) |
| ⭐️⭐️☆☆ | 1.0 | 4.6 | [Ray](https://github.com/raysan5) |
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!
diff --git a/examples/shapes/shapes_double_pendulum.c b/examples/shapes/shapes_double_pendulum.c
new file mode 100644
index 000000000..85ca4af66
--- /dev/null
+++ b/examples/shapes/shapes_double_pendulum.c
@@ -0,0 +1,182 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - Double Pendulum
+*
+* Example complexity rating: [★★☆☆] 2/4
+*
+* Example originally created with raylib 5.5, last time updated with raylib 5.5
+*
+* Example contributed by JoeCheong (@Joecheong2006) and reviewed by Ramon Santamaria (@raysan5)
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2025 JoeCheong (@Joecheong2006)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include // Required for: sin(), cos(), PI
+
+//----------------------------------------------------------------------------------
+// Macro Helpers
+//----------------------------------------------------------------------------------
+#define SCREEN_WIDTH 800
+#define SCREEN_HEIGHT 450
+
+#define CENTER_X SCREEN_WIDTH * 0.5
+#define CENTER_Y SCREEN_HEIGHT * 0.5 - 100
+
+// Constant for Simulation
+#define SIMULATION_STEPS 30
+#define G 9.81
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+static Vector2 CalculatePendulumEndPoint(float l, float theta);
+static Vector2 CalculateDoublePendulumEndPoint(float l1, float theta1, float l2, float theta2);
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ SetConfigFlags(FLAG_WINDOW_HIGHDPI);
+ InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [shapes] example - Double Pendulum");
+
+ // Simulation Paramters
+ //--------------------------------------------------------------------------------------
+ float l1 = 15, m1 = 0.2, theta1 = DEG2RAD * 170, w1 = 0;
+ float l2 = 15, m2 = 0.1, theta2 = DEG2RAD * 0, w2 = 0;
+ float lengthScaler = 0.1;
+ float totalM = m1 + m2;
+
+ Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
+ previousPosition.x += CENTER_X;
+ previousPosition.y += CENTER_Y;
+
+ // Scale length
+ float L1 = l1 * lengthScaler;
+ float L2 = l2 * lengthScaler;
+
+ // Draw Parameters
+ //--------------------------------------------------------------------------------------
+ int lineThick = 20, trailThick = 2;
+ float fateAlpha = 0.01;
+
+ // Create Framebuffer
+ //--------------------------------------------------------------------------------------
+ RenderTexture2D target = LoadRenderTexture(SCREEN_WIDTH, SCREEN_HEIGHT);
+ SetTextureFilter(target.texture, TEXTURE_FILTER_BILINEAR);
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ float dt = GetFrameTime();
+ float step = dt / SIMULATION_STEPS, step2 = step * step;
+
+ // Update Physics - larger steps = better approximation
+ //----------------------------------------------------------------------------------
+ for (int i = 0; i < SIMULATION_STEPS; ++i)
+ {
+ float delta = theta1 - theta2;
+ float sinD = sin(delta), cosD = cos(delta), cos2D = cos(2 * delta);
+ float ww1 = w1 * w1, ww2 = w2 * w2;
+
+ // Calculate a1
+ float a1 = (-G * (2 * m1 + m2) * sin(theta1)
+ - m2 * G * sin(theta1 - 2 * theta2)
+ - 2 * sinD * m2 * (ww2 * L2 + ww1 * L1 * cosD))
+ / (L1 * (2 * m1 + m2 - m2 * cos2D));
+
+ // Calculate a2
+ float a2 = (2 * sinD * (ww1 * L1 * totalM
+ + G * totalM * cos(theta1)
+ + ww2 * L2 * m2 * cosD))
+ / (L2 * (2 * m1 + m2 - m2 * cos2D));
+
+ // Update thetas
+ theta1 += w1 * step + 0.5 * a1 * step2;
+ theta2 += w2 * step + 0.5 * a2 * step2;
+
+ // Update omegas
+ w1 += a1 * step;
+ w2 += a2 * step;
+ }
+ //----------------------------------------------------------------------------------
+
+ // Calculate position
+ Vector2 currentPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
+ currentPosition.x += CENTER_X;
+ currentPosition.y += CENTER_Y;
+
+ // Draw to framebuffer
+ //----------------------------------------------------------------------------------
+ BeginTextureMode(target);
+
+ // Draw a transparent rectangle - smaller alpha = longer trails
+ DrawRectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, Fade(BLACK, fateAlpha));
+
+ // Draw trail
+ DrawCircleV(previousPosition, trailThick, RED);
+ DrawLineEx(previousPosition, currentPosition, trailThick * 2, RED);
+
+ EndTextureMode();
+ //----------------------------------------------------------------------------------
+
+ // Update previous position
+ previousPosition = currentPosition;
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(BLACK);
+
+ // Draw Trails Texture
+ DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height },
+ (Vector2){ 0, 0 }, WHITE);
+
+ // Draw Double Pendulum
+ DrawRectanglePro((Rectangle){ CENTER_X, CENTER_Y, 10 * l1, lineThick },
+ (Vector2){0, lineThick * 0.5}, 90 - RAD2DEG * theta1, RAYWHITE);
+
+ Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
+ DrawRectanglePro((Rectangle){ CENTER_X + endpoint1.x, CENTER_Y + endpoint1.y, 10 * l2, lineThick },
+ (Vector2){0, lineThick * 0.5}, 90 - RAD2DEG * theta2, RAYWHITE);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ UnloadRenderTexture(target);
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+}
+
+// Calculate Pendulum End Point
+static Vector2 CalculatePendulumEndPoint(float l, float theta)
+{
+ return (Vector2){ 10 * l * sin(theta), 10 * l * cos(theta) };
+}
+
+// Calculate Double Pendulum End Point
+static Vector2 CalculateDoublePendulumEndPoint(float l1, float theta1, float l2, float theta2)
+{
+ Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
+ Vector2 endpoint2 = CalculatePendulumEndPoint(l2, theta2);
+ return (Vector2){ endpoint1.x + endpoint2.x, endpoint1.y + endpoint2.y };
+}
diff --git a/examples/shapes/shapes_double_pendulum.png b/examples/shapes/shapes_double_pendulum.png
new file mode 100644
index 000000000..bee7c6a5e
Binary files /dev/null and b/examples/shapes/shapes_double_pendulum.png differ
diff --git a/src/external/rl_gputex.h b/src/external/rl_gputex.h
index 4043a9239..07ff773a5 100644
--- a/src/external/rl_gputex.h
+++ b/src/external/rl_gputex.h
@@ -1,6 +1,6 @@
/**********************************************************************************************
*
-* rl_gputex v1.0 - GPU compressed textures loading and saving
+* rl_gputex v1.1 - GPU compressed textures loading and saving
*
* DESCRIPTION:
*
@@ -10,8 +10,11 @@
* Note that some file formats (DDS, PVR, KTX) also support uncompressed data storage.
* In those cases data is loaded uncompressed and format is returned.
*
+* FIXME: This library still depends on Raylib due to the following reasons:
+* - rl_save_ktx_to_memory() requires rlGetGlTextureFormats() from rlgl.h
+* though this is not a problem, if you don't need KTX support
+*
* TODO:
-* - Implement raylib function: rlGetGlTextureFormats(), required by rl_save_ktx_to_memory()
* - Review rl_load_ktx_from_memory() to support KTX v2.2 specs
*
* CONFIGURATION:
@@ -23,10 +26,43 @@
* #define RL_GPUTEX_SUPPORT_ASTC
* Define desired file formats to be supported
*
+* #define RL_GPUTEX_SHOW_LOG_INFO
+* Define, if you wish to see warnings generated by the library
+* This will include unless you provide your own RL_GPUTEX_LOG
+* #define RL_GPUTEX_LOG
+* Define, if you wish to provide your own warning function
+* Make sure that this macro puts newline character '\n' at the end
+*
+* #define RL_GPUTEX_MALLOC
+* #define RL_GPUTEX_FREE
+* Define those macros in order to provide your own libc-compliant allocator;
+* not doing so will include
+* If you're providing any of those, you must provide ALL of them,
+* otherwise the code will (most likely) crash...
+*
+* #define RL_GPUTEX_NULL
+* Define in order to provide your own libc-compliant NULL pointer;
+* not doing so will include
+*
+* #define RL_GPUTEX_MEMCPY
+* Define in order to provide your own libc-compliant 'memcpy' function;
+* not doing so will include
+*
+* #define RLGPUTEXAPI
+* Define to compiler-specific intrinsic, if you wish to export public functions
+* There is no need to do so when statically linking
+*
+* VERSIONS HISTORY:
+* 1.1 (15-Jul-2025) Several minor fixes related to specific image formats; some work has been done
+* in order to decouple the library from Raylib by introducing few new macros; library still
+* requires Raylib in order to function properly
+*
+* 1.0 (17-Sep-2022) First version has been created by migrating part of compressed-texture-loading
+* functionality from Raylib src/rtextures.c into self-contained library
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2013-2022 Ramon Santamaria (@raysan5)
+* Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -48,10 +84,41 @@
#ifndef RL_GPUTEX_H
#define RL_GPUTEX_H
-#ifndef RLAPI
- #define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
+#ifndef RLGPUTEXAPI
+ #define RLGPUTEXAPI // Functions defined as 'extern' by default (implicit specifiers)
#endif
+// Texture pixel formats
+// NOTE: Support depends on OpenGL version
+// WARNING: Enum values aligned with raylib/rlgl equivalent PixelFormat/rlPixelFormat enum,
+// to avoid value mapping between the 3 libraries format values
+typedef enum {
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G6B5, // 16 bpp
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8, // 24 bpp
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, // 32 bpp
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16, // 16 bpp (1 channel - half float)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - half float)
+ RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - half float)
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT3_RGBA, // 8 bpp
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT5_RGBA, // 8 bpp
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC1_RGB, // 4 bpp
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_RGB, // 4 bpp
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGB, // 4 bpp
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGBA, // 4 bpp
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
+ RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA // 2 bpp
+} rlGpuTexPixelFormat;
+
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
@@ -60,13 +127,13 @@ extern "C" { // Prevents name mangling of functions
#endif
// Load image data from memory data files
-RLAPI void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
-RLAPI void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
-RLAPI void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
-RLAPI void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
-RLAPI void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
+RLGPUTEXAPI void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
+RLGPUTEXAPI void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
+RLGPUTEXAPI void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
+RLGPUTEXAPI void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
+RLGPUTEXAPI void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
-RLAPI int rl_save_ktx_to_memory(const char *fileName, void *data, int width, int height, int format, int mipmaps); // Save image data as KTX file
+RLGPUTEXAPI int rl_save_ktx_to_memory(const char *fileName, void *data, int width, int height, int format, int mipmaps); // Save image data as KTX file
#if defined(__cplusplus)
}
@@ -83,13 +150,47 @@ RLAPI int rl_save_ktx_to_memory(const char *fileName, void *data, int width, int
#if defined(RL_GPUTEX_IMPLEMENTATION)
-// Simple log system to avoid RPNG_LOG() calls if required
+#if defined(RL_GPUTEX_SHOW_LOG_INFO) && !defined(RL_GPUTEX_LOG)
+ #include // Required for: printf()
+#endif
+#if !defined(RL_GPUTEX_MALLOC) || !defined(RL_GPUTEX_NULL)
+ #include // Required for: NULL, malloc(), calloc(), free()
+#endif
+#if !defined(RL_GPUTEX_MEMCPY)
+ #include // Required for: memcpy()
+#endif
+
+#if defined(RL_GPUTEX_MALLOC) || defined(RL_GPUTEX_FREE)
+ #if !defined(RL_GPUTEX_MALLOC) || !defined(RL_GPUTEX_FREE)
+ #warning "RL_GPUTEX_MALLOC and RL_GPUTEX_FREE allocation functions are required to be provided"
+ #endif
+#endif
+#if !defined(RL_GPUTEX_MALLOC)
+ #define RL_GPUTEX_MALLOC(sz) malloc(sz)
+ #define RL_GPUTEX_FREE(ptr) free(ptr)
+#endif
+
+#if !defined(RL_GPUTEX_NULL)
+ #define RL_GPUTEX_NULL NULL
+#endif
+#if !defined(RL_GPUTEX_MEMCPY)
+ #define RL_GPUTEX_MEMCPY(dest, src, num) memcpy(dest, src, num)
+#endif
+
+// Simple warning logging system to avoid LOG() calls if required
// NOTE: Avoiding those calls, also avoids const strings memory usage
-#define RL_GPUTEX_SHOW_LOG_INFO
-#if defined(RL_GPUTEX_SHOW_LOG_INFO) && !defined(LOG)
-#define LOG(...) printf(__VA_ARGS__)
+// WARN: This macro expects that newline character is added automatically
+// in order to match the functionality of Raylib's TRACELOG()
+#if defined(RL_GPUTEX_SHOW_LOG_INFO)
+ #if !defined(RL_GPUTEX_LOG)
+ #define RL_GPUTEX_LOG(...) (void)(printf("RL_GPUTEX: WARNING: " __VA_ARGS__), printf("\n"))
+ #endif
#else
-#define LOG(...)
+ #if defined(RL_GPUTEX_LOG)
+ // Undefine it first in order to supress warnings about macro redefinition
+ #undef RL_GPUTEX_LOG
+ #endif
+ #define RL_GPUTEX_LOG(...)
#endif
//----------------------------------------------------------------------------------
@@ -98,6 +199,9 @@ RLAPI int rl_save_ktx_to_memory(const char *fileName, void *data, int width, int
// Get pixel data size in bytes for certain pixel format
static int get_pixel_data_size(int width, int height, int format);
+// Get OpenGL internal formats and data type from rlGpuTexPixelFormat
+void get_gl_texture_formats(int format, unsigned int *gl_internal_format, unsigned int *gl_format, unsigned int *gl_type);
+
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
@@ -105,8 +209,8 @@ static int get_pixel_data_size(int width, int height, int format);
// Loading DDS from memory image data (compressed or uncompressed)
void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
- void *image_data = NULL; // Image data pointer
- int image_pixel_size = 0; // Image pixel size
+ void *image_data = RL_GPUTEX_NULL; // Image data pointer
+ int image_pixel_size = 0; // Image pixel size
unsigned char *file_data_ptr = (unsigned char *)file_data;
@@ -153,7 +257,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
unsigned int reserved2;
} dds_header;
- if (file_data_ptr != NULL)
+ if (file_data_ptr != RL_GPUTEX_NULL)
{
// Verify the type of file
unsigned char *dds_header_id = file_data_ptr;
@@ -161,7 +265,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
if ((dds_header_id[0] != 'D') || (dds_header_id[1] != 'D') || (dds_header_id[2] != 'S') || (dds_header_id[3] != ' '))
{
- LOG("WARNING: IMAGE: DDS file data not valid");
+ RL_GPUTEX_LOG("DDS file data not valid");
}
else
{
@@ -172,8 +276,8 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
*width = header->width;
*height = header->height;
- if (*width % 4 != 0) LOG("WARNING: IMAGE: DDS file width must be multiple of 4. Image will not display correctly");
- if (*height % 4 != 0) LOG("WARNING: IMAGE: DDS file height must be multiple of 4. Image will not display correctly");
+ if (*width % 4 != 0) RL_GPUTEX_LOG("DDS file width must be multiple of 4. Image will not display correctly");
+ if (*height % 4 != 0) RL_GPUTEX_LOG("DDS file height must be multiple of 4. Image will not display correctly");
image_pixel_size = header->width*header->height;
@@ -186,11 +290,11 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
{
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_GPUTEX_MALLOC(data_size);
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
- *format = PIXELFORMAT_UNCOMPRESSED_R5G6B5;
+ *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G6B5;
}
else if (header->ddspf.flags == 0x41) // With alpha channel
{
@@ -198,9 +302,9 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
{
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_GPUTEX_MALLOC(data_size);
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
unsigned char alpha = 0;
@@ -212,15 +316,15 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
((unsigned short *)image_data)[i] += alpha;
}
- *format = PIXELFORMAT_UNCOMPRESSED_R5G5B5A1;
+ *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1;
}
else if (header->ddspf.a_bit_mask == 0xf000) // 4bit alpha
{
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_GPUTEX_MALLOC(data_size);
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
unsigned char alpha = 0;
@@ -232,7 +336,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
((unsigned short *)image_data)[i] += alpha;
}
- *format = PIXELFORMAT_UNCOMPRESSED_R4G4B4A4;
+ *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4;
}
}
}
@@ -240,19 +344,19 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
{
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_GPUTEX_MALLOC(data_size);
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
- *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
+ *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8;
}
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);
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
- image_data = RL_MALLOC(data_size);
+ image_data = RL_GPUTEX_MALLOC(data_size);
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
unsigned char blue = 0;
@@ -266,7 +370,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
((unsigned char *)image_data)[i + 2] = blue;
}
- *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
+ *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
}
else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed
{
@@ -276,19 +380,19 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
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_GPUTEX_MALLOC(data_size*sizeof(unsigned char));
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
switch (header->ddspf.fourcc)
{
case FOURCC_DXT1:
{
- if (header->ddspf.flags == 0x04) *format = PIXELFORMAT_COMPRESSED_DXT1_RGB;
- else *format = PIXELFORMAT_COMPRESSED_DXT1_RGBA;
+ if (header->ddspf.flags == 0x04) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGB;
+ else *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGBA;
} break;
- case FOURCC_DXT3: *format = PIXELFORMAT_COMPRESSED_DXT3_RGBA; break;
- case FOURCC_DXT5: *format = PIXELFORMAT_COMPRESSED_DXT5_RGBA; break;
+ case FOURCC_DXT3: *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT3_RGBA; break;
+ case FOURCC_DXT5: *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT5_RGBA; break;
default: break;
}
}
@@ -305,7 +409,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
// PKM is a much simpler file format used mainly to contain a single ETC1/ETC2 compressed image (no mipmaps)
void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
- void *image_data = NULL; // Image data pointer
+ void *image_data = RL_GPUTEX_NULL; // Image data pointer
unsigned char *file_data_ptr = (unsigned char *)file_data;
@@ -336,13 +440,13 @@ void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_
// NOTE: The extended width and height are the widths rounded up to a multiple of 4.
// NOTE: ETC is always 4bit per pixel (64 bit for each 4x4 block of pixels)
- if (file_data_ptr != NULL)
+ if (file_data_ptr != RL_GPUTEX_NULL)
{
pkm_header *header = (pkm_header *)file_data_ptr;
if ((header->id[0] != 'P') || (header->id[1] != 'K') || (header->id[2] != 'M') || (header->id[3] != ' '))
{
- LOG("WARNING: IMAGE: PKM file data not valid");
+ RL_GPUTEX_LOG("PKM file data not valid");
}
else
{
@@ -362,13 +466,13 @@ void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_
int data_size = (*width)*(*height)*bpp/8; // Total data size in bytes
- image_data = RL_MALLOC(data_size*sizeof(unsigned char));
+ image_data = RL_GPUTEX_MALLOC(data_size*sizeof(unsigned char));
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
- if (header->format == 0) *format = PIXELFORMAT_COMPRESSED_ETC1_RGB;
- else if (header->format == 1) *format = PIXELFORMAT_COMPRESSED_ETC2_RGB;
- else if (header->format == 3) *format = PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA;
+ if (header->format == 0) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC1_RGB;
+ else if (header->format == 1) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_RGB;
+ else if (header->format == 3) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA;
}
}
@@ -381,7 +485,7 @@ void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_
// TODO: Review KTX loading, many things changed!
void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
- void *image_data = NULL; // Image data pointer
+ void *image_data = RL_GPUTEX_NULL; // Image data pointer
unsigned char *file_data_ptr = (unsigned char *)file_data;
@@ -419,14 +523,14 @@ void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_
// NOTE: Before start of every mipmap data block, we have: unsigned int data_size
- if (file_data_ptr != NULL)
+ if (file_data_ptr != RL_GPUTEX_NULL)
{
ktx_header *header = (ktx_header *)file_data_ptr;
if ((header->id[1] != 'K') || (header->id[2] != 'T') || (header->id[3] != 'X') ||
(header->id[4] != ' ') || (header->id[5] != '1') || (header->id[6] != '1'))
{
- LOG("WARNING: IMAGE: KTX file data not valid");
+ RL_GPUTEX_LOG("KTX file data not valid");
}
else
{
@@ -441,13 +545,13 @@ void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_
int data_size = ((int *)file_data_ptr)[0];
file_data_ptr += sizeof(int);
- image_data = RL_MALLOC(data_size*sizeof(unsigned char));
+ image_data = RL_GPUTEX_MALLOC(data_size*sizeof(unsigned char));
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
- if (header->gl_internal_format == 0x8D64) *format = PIXELFORMAT_COMPRESSED_ETC1_RGB;
- else if (header->gl_internal_format == 0x9274) *format = PIXELFORMAT_COMPRESSED_ETC2_RGB;
- else if (header->gl_internal_format == 0x9278) *format = PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA;
+ if (header->gl_internal_format == 0x8D64) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC1_RGB;
+ else if (header->gl_internal_format == 0x9274) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_RGB;
+ else if (header->gl_internal_format == 0x9278) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA;
// TODO: Support uncompressed data formats? Right now it returns format = 0!
}
@@ -463,9 +567,9 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
{
// KTX file Header (64 bytes)
// v1.1 - https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
- // v2.0 - http://github.khronos.org/KTX-Specification/ - Final specs by 2021-04-18
+ // v2.0 - https://github.khronos.org/KTX-Specification/ktxspec.v2.html
typedef struct {
- char id[12]; // Identifier: "«KTX 11»\r\n\x1A\n" // KTX 2.0: "«KTX 22»\r\n\x1A\n"
+ char id[12]; // Identifier: "«KTX 11»\r\n\x1A\n" // KTX 2.0: "«KTX 20»\r\n\x1A\n"
unsigned int endianness; // Little endian: 0x01 0x02 0x03 0x04
unsigned int gl_type; // For compressed textures, glType must equal 0
unsigned int gl_type_size; // For compressed texture data, usually 1
@@ -482,6 +586,17 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
// KTX 2.0: UInt32 supercompressionScheme - 0 (None), 1 (Crunch CRN), 2 (Zlib DEFLATE)...
// KTX 2.0 defines additional header elements...
} ktx_header;
+
+ Byte[12] identifier
+ UInt32 vkFormat
+ UInt32 typeSize
+ UInt32 pixelWidth
+ UInt32 pixelHeight
+ UInt32 pixelDepth
+ UInt32 layerCount
+ UInt32 faceCount
+ UInt32 levelCount
+ UInt32 supercompressionScheme
// Calculate file data_size required
int data_size = sizeof(ktx_header);
@@ -492,7 +607,7 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
w /= 2; h /= 2;
}
- unsigned char *file_data = RL_CALLOC(data_size, 1);
+ unsigned char *file_data = RL_GPUTEX_MALLOC(data_size);
unsigned char *file_data_ptr = file_data;
ktx_header header = { 0 };
@@ -504,7 +619,7 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
const char ktx_identifier[12] = { 0xAB, 'K', 'T', 'X', ' ', '1', '1', 0xBB, '\r', '\n', 0x1A, '\n' };
// Get the image header
- memcpy(header.id, ktx_identifier, 12); // KTX 1.1 signature
+ RL_GPUTEX_MEMCPY(header.id, ktx_identifier, 12); // KTX 1.1 signature
header.endianness = 0;
header.gl_type = 0; // Obtained from format
header.gl_type_size = 1;
@@ -518,16 +633,18 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
header.faces = 1;
header.mipmap_levels = mipmaps; // If it was 0, it means mipmaps should be generated on loading (not for compressed formats)
header.key_value_data_size = 0; // No extra data after the header
-
- rlGetGlTextureFormats(format, &header.gl_internal_format, &header.gl_format, &header.gl_type); // rlgl module function
- header.gl_base_internal_format = header.gl_format; // KTX 1.1 only
+
+ // TODO: WARNING: Function dependant on rlgl library!
+ rlGetGlTextureFormats(format, &header.gl_internal_format, &header.gl_format, &header.gl_type); // rlgl module function
+
+ header.gl_base_internal_format = header.gl_format; // TODO: WARNING: KTX 1.1 only
// NOTE: We can save into a .ktx all PixelFormats supported by raylib, including compressed formats like DXT, ETC or ASTC
- if (header.gl_format == -1) LOG("WARNING: IMAGE: GL format not supported for KTX export (%i)", header.gl_format);
+ if (header.gl_format == -1) RL_GPUTEX_LOG("RL_GPUTEX: GL format not supported for KTX export (%i)", header.gl_format);
else
{
- memcpy(file_data_ptr, &header, sizeof(ktx_header));
+ RL_GPUTEX_MEMCPY(file_data_ptr, &header, sizeof(ktx_header));
file_data_ptr += sizeof(ktx_header);
int temp_width = width;
@@ -539,8 +656,8 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
{
unsigned int data_size = get_pixel_data_size(temp_width, temp_height, format);
- memcpy(file_data_ptr, &data_size, sizeof(unsigned int));
- memcpy(file_data_ptr + 4, (unsigned char *)data + data_offset, data_size);
+ RL_GPUTEX_MEMCPY(file_data_ptr, &data_size, sizeof(unsigned int));
+ RL_GPUTEX_MEMCPY(file_data_ptr + 4, (unsigned char *)data + data_offset, data_size);
temp_width /= 2;
temp_height /= 2;
@@ -553,20 +670,22 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
int success = false;
FILE *file = fopen(file_name, "wb");
- if (file != NULL)
+ if (file != RL_GPUTEX_NULL)
{
unsigned int count = (unsigned int)fwrite(file_data, sizeof(unsigned char), data_size, file);
- if (count == 0) LOG("WARNING: FILEIO: [%s] Failed to write file", file_name);
- else if (count != data_size) LOG("WARNING: FILEIO: [%s] File partially written", file_name);
- else LOG("INFO: FILEIO: [%s] File saved successfully", file_name);
+ if (count == 0) RL_GPUTEX_LOG("FILEIO: [%s] Failed to write file", file_name);
+ else if (count != data_size) RL_GPUTEX_LOG("FILEIO: [%s] File partially written", file_name);
+ else (void)0; // WARN: this branch is handled by Raylib, since rl_gputex only prints warnings
int result = fclose(file);
- if (result == 0) success = true;
- }
- else LOG("WARNING: FILEIO: [%s] Failed to open file", file_name);
+ if (result != 0) RL_GPUTEX_LOG("FILEIO: [%s] Failed to close file", file_name);
- RL_FREE(file_data); // Free file data buffer
+ if (result == 0 && count == data_size) success = true;
+ }
+ else RL_GPUTEX_LOG("FILEIO: [%s] Failed to open file", file_name);
+
+ RL_GPUTEX_FREE(file_data); // Free file data buffer
// If all data has been written correctly to file, success = 1
return success;
@@ -578,7 +697,7 @@ int rl_save_ktx(const char *file_name, void *data, int width, int height, int fo
// NOTE: PVR v2 not supported, use PVR v3 instead
void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
- void *image_data = NULL; // Image data pointer
+ void *image_data = RL_GPUTEX_NULL; // Image data pointer
unsigned char *file_data_ptr = (unsigned char *)file_data;
@@ -636,7 +755,7 @@ void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_
} PVRMetadata;
#endif
- if (file_data_ptr != NULL)
+ if (file_data_ptr != RL_GPUTEX_NULL)
{
// Check PVR image version
unsigned char pvr_version = file_data_ptr[0];
@@ -648,7 +767,7 @@ void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_
if ((header->id[0] != 'P') || (header->id[1] != 'V') || (header->id[2] != 'R') || (header->id[3] != 3))
{
- LOG("WARNING: IMAGE: PVR file data not valid");
+ RL_GPUTEX_LOG("PVR file data not valid");
}
else
{
@@ -659,24 +778,24 @@ void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_
*mips = header->num_mipmaps;
// Check data format
- if (((header->channels[0] == 'l') && (header->channels[1] == 0)) && (header->channel_depth[0] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
- else if (((header->channels[0] == 'l') && (header->channels[1] == 'a')) && ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8))) *format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA;
+ if (((header->channels[0] == 'l') && (header->channels[1] == 0)) && (header->channel_depth[0] == 8)) *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
+ else if (((header->channels[0] == 'l') && (header->channels[1] == 'a')) && ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8))) *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA;
else if ((header->channels[0] == 'r') && (header->channels[1] == 'g') && (header->channels[2] == 'b'))
{
if (header->channels[3] == 'a')
{
- if ((header->channel_depth[0] == 5) && (header->channel_depth[1] == 5) && (header->channel_depth[2] == 5) && (header->channel_depth[3] == 1)) *format = PIXELFORMAT_UNCOMPRESSED_R5G5B5A1;
- else if ((header->channel_depth[0] == 4) && (header->channel_depth[1] == 4) && (header->channel_depth[2] == 4) && (header->channel_depth[3] == 4)) *format = PIXELFORMAT_UNCOMPRESSED_R4G4B4A4;
- else if ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8) && (header->channel_depth[2] == 8) && (header->channel_depth[3] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
+ if ((header->channel_depth[0] == 5) && (header->channel_depth[1] == 5) && (header->channel_depth[2] == 5) && (header->channel_depth[3] == 1)) *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1;
+ else if ((header->channel_depth[0] == 4) && (header->channel_depth[1] == 4) && (header->channel_depth[2] == 4) && (header->channel_depth[3] == 4)) *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4;
+ else if ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8) && (header->channel_depth[2] == 8) && (header->channel_depth[3] == 8)) *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
}
else if (header->channels[3] == 0)
{
- if ((header->channel_depth[0] == 5) && (header->channel_depth[1] == 6) && (header->channel_depth[2] == 5)) *format = PIXELFORMAT_UNCOMPRESSED_R5G6B5;
- else if ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8) && (header->channel_depth[2] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
+ if ((header->channel_depth[0] == 5) && (header->channel_depth[1] == 6) && (header->channel_depth[2] == 5)) *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G6B5;
+ else if ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8) && (header->channel_depth[2] == 8)) *format = RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8;
}
}
- else if (header->channels[0] == 2) *format = PIXELFORMAT_COMPRESSED_PVRT_RGB;
- else if (header->channels[0] == 3) *format = PIXELFORMAT_COMPRESSED_PVRT_RGBA;
+ else if (header->channels[0] == 2) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGB;
+ else if (header->channels[0] == 3) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGBA;
file_data_ptr += header->metadata_size; // Skip meta data header
@@ -684,25 +803,25 @@ void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_
int bpp = 0;
switch (*format)
{
- case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
- case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
- case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
- case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
- case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
- case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
- case PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
- case PIXELFORMAT_COMPRESSED_PVRT_RGB:
- case PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G6B5:
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGB:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
default: break;
}
int data_size = (*width)*(*height)*bpp/8; // Total data size in bytes
- image_data = RL_MALLOC(data_size*sizeof(unsigned char));
+ image_data = RL_GPUTEX_MALLOC(data_size*sizeof(unsigned char));
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
}
}
- else if (pvr_version == 52) LOG("INFO: IMAGE: PVRv2 format not supported, update your files to PVRv3");
+ else if (pvr_version == 52) RL_GPUTEX_LOG("PVRv2 format not supported, update your files to PVRv3");
}
return image_data;
@@ -713,7 +832,7 @@ void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_
// Load ASTC compressed image data (ASTC compression)
void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
{
- void *image_data = NULL; // Image data pointer
+ void *image_data = RL_GPUTEX_NULL; // Image data pointer
unsigned char *file_data_ptr = (unsigned char *)file_data;
@@ -736,13 +855,13 @@ void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file
unsigned char length[3]; // void *Z-size (1 for 2D images)
} astc_header;
- if (file_data_ptr != NULL)
+ if (file_data_ptr != RL_GPUTEX_NULL)
{
astc_header *header = (astc_header *)file_data_ptr;
if ((header->id[3] != 0x5c) || (header->id[2] != 0xa1) || (header->id[1] != 0xab) || (header->id[0] != 0x13))
{
- LOG("WARNING: IMAGE: ASTC file data not valid");
+ RL_GPUTEX_LOG("ASTC file data not valid");
}
else
{
@@ -761,14 +880,14 @@ void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file
{
int data_size = (*width)*(*height)*bpp/8; // Data size in bytes
- image_data = RL_MALLOC(data_size*sizeof(unsigned char));
+ image_data = RL_GPUTEX_MALLOC(data_size*sizeof(unsigned char));
- memcpy(image_data, file_data_ptr, data_size);
+ RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
- if (bpp == 8) *format = PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA;
- else if (bpp == 2) *format = PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA;
+ if (bpp == 8) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA;
+ else if (bpp == 2) *format = RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA;
}
- else LOG("WARNING: IMAGE: ASTC block size configuration not supported");
+ else RL_GPUTEX_LOG("ASTC block size configuration not supported");
}
}
@@ -787,27 +906,27 @@ static int get_pixel_data_size(int width, int height, int format)
switch (format)
{
- case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
- case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
- case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
- case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
- case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
- case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
- case PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
- case PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break;
- case PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break;
- case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break;
- case PIXELFORMAT_COMPRESSED_DXT1_RGB:
- case PIXELFORMAT_COMPRESSED_DXT1_RGBA:
- case PIXELFORMAT_COMPRESSED_ETC1_RGB:
- case PIXELFORMAT_COMPRESSED_ETC2_RGB:
- case PIXELFORMAT_COMPRESSED_PVRT_RGB:
- case PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
- case PIXELFORMAT_COMPRESSED_DXT3_RGBA:
- case PIXELFORMAT_COMPRESSED_DXT5_RGBA:
- case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
- case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
- case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G6B5:
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break;
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGB:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGBA:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC1_RGB:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_RGB:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGB:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT3_RGBA:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT5_RGBA:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
default: break;
}
@@ -817,10 +936,555 @@ static int get_pixel_data_size(int width, int height, int format)
// if texture is smaller, minimum dataSize is 8 or 16
if ((width < 4) && (height < 4))
{
- if ((format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < PIXELFORMAT_COMPRESSED_DXT3_RGBA)) data_size = 8;
- else if ((format >= PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) data_size = 16;
+ if ((format >= RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT3_RGBA)) data_size = 8;
+ else if ((format >= RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) data_size = 16;
}
return data_size;
}
+
+// Get OpenGL internal formats and data type from rlGpuTexPixelFormat
+void get_gl_texture_formats(int format, unsigned int *gl_internal_format, unsigned int *gl_format, unsigned int *gl_type)
+{
+ // KTX 1.1 uses OpenGL formats on header info but KTX 2.0 uses Vulkan texture formats,
+ // if this library is being improved to support KTX 2.0, it requires those formats to be provided -> View list at the end!
+
+ /*
+ *glInternalFormat = 0;
+ *glFormat = 0;
+ *glType = 0;
+
+ switch (format)
+ {
+ #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_ES2)
+ // NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *gl_internal_format = GL_LUMINANCE; *gl_format = GL_LUMINANCE; *gl_type = GL_UNSIGNED_BYTE; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *gl_internal_format = GL_LUMINANCE_ALPHA; *gl_format = GL_LUMINANCE_ALPHA; *gl_type = GL_UNSIGNED_BYTE; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G6B5: *gl_internal_format = GL_RGB; *gl_format = GL_RGB; *gl_type = GL_UNSIGNED_SHORT_5_6_5; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8: *gl_internal_format = GL_RGB; *gl_format = GL_RGB; *gl_type = GL_UNSIGNED_BYTE; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: *gl_internal_format = GL_RGBA; *gl_format = GL_RGBA; *gl_type = GL_UNSIGNED_SHORT_5_5_5_1; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *gl_internal_format = GL_RGBA; *gl_format = GL_RGBA; *gl_type = GL_UNSIGNED_SHORT_4_4_4_4; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *gl_internal_format = GL_RGBA; *gl_format = GL_RGBA; *gl_type = GL_UNSIGNED_BYTE; break;
+ #if !defined(GRAPHICS_API_OPENGL_11)
+ #if defined(GRAPHICS_API_OPENGL_ES3)
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32: *gl_internal_format = GL_R32F_EXT; *gl_format = GL_RED_EXT; *gl_type = GL_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32: *gl_internal_format = GL_RGB32F_EXT; *gl_format = GL_RGB; *gl_type = GL_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: *gl_internal_format = GL_RGBA32F_EXT; *gl_format = GL_RGBA; *gl_type = GL_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16: *gl_internal_format = GL_R16F_EXT; *gl_format = GL_RED_EXT; *gl_type = GL_HALF_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16: *gl_internal_format = GL_RGB16F_EXT; *gl_format = GL_RGB; *gl_type = GL_HALF_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: *gl_internal_format = GL_RGBA16F_EXT; *gl_format = GL_RGBA; *gl_type = GL_HALF_FLOAT; break;
+ #else
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32: *gl_internal_format = GL_LUMINANCE; *gl_format = GL_LUMINANCE; *gl_type = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32: *gl_internal_format = GL_RGB; *gl_format = GL_RGB; *gl_type = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: *gl_internal_format = GL_RGBA; *gl_format = GL_RGBA; *gl_type = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
+ #if defined(GRAPHICS_API_OPENGL_21)
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16: *gl_internal_format = GL_LUMINANCE; *gl_format = GL_LUMINANCE; *gl_type = GL_HALF_FLOAT_ARB; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16: *gl_internal_format = GL_RGB; *gl_format = GL_RGB; *gl_type = GL_HALF_FLOAT_ARB; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: *gl_internal_format = GL_RGBA; *gl_format = GL_RGBA; *gl_type = GL_HALF_FLOAT_ARB; break;
+ #else // defined(GRAPHICS_API_OPENGL_ES2)
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16: *gl_internal_format = GL_LUMINANCE; *gl_format = GL_LUMINANCE; *gl_type = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16: *gl_internal_format = GL_RGB; *gl_format = GL_RGB; *gl_type = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: *gl_internal_format = GL_RGBA; *gl_format = GL_RGBA; *gl_type = GL_HALF_FLOAT_OES; break; // NOTE: Requires extension OES_texture_half_float
+ #endif
+ #endif
+ #endif
+ #elif defined(GRAPHICS_API_OPENGL_33)
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *gl_internal_format = GL_R8; *gl_format = GL_RED; *gl_type = GL_UNSIGNED_BYTE; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *gl_internal_format = GL_RG8; *gl_format = GL_RG; *gl_type = GL_UNSIGNED_BYTE; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G6B5: *gl_internal_format = GL_RGB565; *gl_format = GL_RGB; *gl_type = GL_UNSIGNED_SHORT_5_6_5; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8: *gl_internal_format = GL_RGB8; *gl_format = GL_RGB; *gl_type = GL_UNSIGNED_BYTE; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: *gl_internal_format = GL_RGB5_A1; *gl_format = GL_RGBA; *gl_type = GL_UNSIGNED_SHORT_5_5_5_1; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *gl_internal_format = GL_RGBA4; *gl_format = GL_RGBA; *gl_type = GL_UNSIGNED_SHORT_4_4_4_4; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *gl_internal_format = GL_RGBA8; *gl_format = GL_RGBA; *gl_type = GL_UNSIGNED_BYTE; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32: *gl_internal_format = GL_R32F; *gl_format = GL_RED; *gl_type = GL_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32: *gl_internal_format = GL_RGB32F; *gl_format = GL_RGB; *gl_type = GL_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: *gl_internal_format = GL_RGBA32F; *gl_format = GL_RGBA; *gl_type = GL_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16: *gl_internal_format = GL_R16F; *gl_format = GL_RED; *gl_type = GL_HALF_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16: *gl_internal_format = GL_RGB16F; *gl_format = GL_RGB; *gl_type = GL_HALF_FLOAT; break;
+ case RL_GPUTEX_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: *gl_internal_format = GL_RGBA16F; *gl_format = GL_RGBA; *gl_type = GL_HALF_FLOAT; break;
+ #endif
+ #if !defined(GRAPHICS_API_OPENGL_11)
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGB: *gl_internal_format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break;
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT1_RGBA: *gl_internal_format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT3_RGBA: *gl_internal_format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_DXT5_RGBA: *gl_internal_format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC1_RGB: *gl_internal_format = GL_ETC1_RGB8_OES; break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_RGB: *gl_internal_format = GL_COMPRESSED_RGB8_ETC2; break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: *gl_internal_format = GL_COMPRESSED_RGBA8_ETC2_EAC; break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGB: *gl_internal_format = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; break; // NOTE: Requires PowerVR GPU
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_PVRT_RGBA: *gl_internal_format = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; break; // NOTE: Requires PowerVR GPU
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: *gl_internal_format = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
+ case RL_GPUTEX_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: *gl_internal_format = GL_COMPRESSED_RGBA_ASTC_8x8_KHR; break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
+ #endif
+ default: RL_GPUTEX_LOG("GPUTEX: Current format not supported (%i)", format); break;
+ }
+ */
+}
#endif // RL_GPUTEX_IMPLEMENTATION
+
+/*
+// Vulkan texture formats
+typedef enum VkFormat {
+ // Provided by VK_VERSION_1_0
+ VK_FORMAT_UNDEFINED = 0,
+ VK_FORMAT_R4G4_UNORM_PACK8 = 1,
+ VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
+ VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
+ VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
+ VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
+ VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
+ VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
+ VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
+ VK_FORMAT_R8_UNORM = 9,
+ VK_FORMAT_R8_SNORM = 10,
+ VK_FORMAT_R8_USCALED = 11,
+ VK_FORMAT_R8_SSCALED = 12,
+ VK_FORMAT_R8_UINT = 13,
+ VK_FORMAT_R8_SINT = 14,
+ VK_FORMAT_R8_SRGB = 15,
+ VK_FORMAT_R8G8_UNORM = 16,
+ VK_FORMAT_R8G8_SNORM = 17,
+ VK_FORMAT_R8G8_USCALED = 18,
+ VK_FORMAT_R8G8_SSCALED = 19,
+ VK_FORMAT_R8G8_UINT = 20,
+ VK_FORMAT_R8G8_SINT = 21,
+ VK_FORMAT_R8G8_SRGB = 22,
+ VK_FORMAT_R8G8B8_UNORM = 23,
+ VK_FORMAT_R8G8B8_SNORM = 24,
+ VK_FORMAT_R8G8B8_USCALED = 25,
+ VK_FORMAT_R8G8B8_SSCALED = 26,
+ VK_FORMAT_R8G8B8_UINT = 27,
+ VK_FORMAT_R8G8B8_SINT = 28,
+ VK_FORMAT_R8G8B8_SRGB = 29,
+ VK_FORMAT_B8G8R8_UNORM = 30,
+ VK_FORMAT_B8G8R8_SNORM = 31,
+ VK_FORMAT_B8G8R8_USCALED = 32,
+ VK_FORMAT_B8G8R8_SSCALED = 33,
+ VK_FORMAT_B8G8R8_UINT = 34,
+ VK_FORMAT_B8G8R8_SINT = 35,
+ VK_FORMAT_B8G8R8_SRGB = 36,
+ VK_FORMAT_R8G8B8A8_UNORM = 37,
+ VK_FORMAT_R8G8B8A8_SNORM = 38,
+ VK_FORMAT_R8G8B8A8_USCALED = 39,
+ VK_FORMAT_R8G8B8A8_SSCALED = 40,
+ VK_FORMAT_R8G8B8A8_UINT = 41,
+ VK_FORMAT_R8G8B8A8_SINT = 42,
+ VK_FORMAT_R8G8B8A8_SRGB = 43,
+ VK_FORMAT_B8G8R8A8_UNORM = 44,
+ VK_FORMAT_B8G8R8A8_SNORM = 45,
+ VK_FORMAT_B8G8R8A8_USCALED = 46,
+ VK_FORMAT_B8G8R8A8_SSCALED = 47,
+ VK_FORMAT_B8G8R8A8_UINT = 48,
+ VK_FORMAT_B8G8R8A8_SINT = 49,
+ VK_FORMAT_B8G8R8A8_SRGB = 50,
+ VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
+ VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
+ VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
+ VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
+ VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
+ VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
+ VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
+ VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
+ VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
+ VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
+ VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
+ VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
+ VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
+ VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
+ VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
+ VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
+ VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
+ VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
+ VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
+ VK_FORMAT_R16_UNORM = 70,
+ VK_FORMAT_R16_SNORM = 71,
+ VK_FORMAT_R16_USCALED = 72,
+ VK_FORMAT_R16_SSCALED = 73,
+ VK_FORMAT_R16_UINT = 74,
+ VK_FORMAT_R16_SINT = 75,
+ VK_FORMAT_R16_SFLOAT = 76,
+ VK_FORMAT_R16G16_UNORM = 77,
+ VK_FORMAT_R16G16_SNORM = 78,
+ VK_FORMAT_R16G16_USCALED = 79,
+ VK_FORMAT_R16G16_SSCALED = 80,
+ VK_FORMAT_R16G16_UINT = 81,
+ VK_FORMAT_R16G16_SINT = 82,
+ VK_FORMAT_R16G16_SFLOAT = 83,
+ VK_FORMAT_R16G16B16_UNORM = 84,
+ VK_FORMAT_R16G16B16_SNORM = 85,
+ VK_FORMAT_R16G16B16_USCALED = 86,
+ VK_FORMAT_R16G16B16_SSCALED = 87,
+ VK_FORMAT_R16G16B16_UINT = 88,
+ VK_FORMAT_R16G16B16_SINT = 89,
+ VK_FORMAT_R16G16B16_SFLOAT = 90,
+ VK_FORMAT_R16G16B16A16_UNORM = 91,
+ VK_FORMAT_R16G16B16A16_SNORM = 92,
+ VK_FORMAT_R16G16B16A16_USCALED = 93,
+ VK_FORMAT_R16G16B16A16_SSCALED = 94,
+ VK_FORMAT_R16G16B16A16_UINT = 95,
+ VK_FORMAT_R16G16B16A16_SINT = 96,
+ VK_FORMAT_R16G16B16A16_SFLOAT = 97,
+ VK_FORMAT_R32_UINT = 98,
+ VK_FORMAT_R32_SINT = 99,
+ VK_FORMAT_R32_SFLOAT = 100,
+ VK_FORMAT_R32G32_UINT = 101,
+ VK_FORMAT_R32G32_SINT = 102,
+ VK_FORMAT_R32G32_SFLOAT = 103,
+ VK_FORMAT_R32G32B32_UINT = 104,
+ VK_FORMAT_R32G32B32_SINT = 105,
+ VK_FORMAT_R32G32B32_SFLOAT = 106,
+ VK_FORMAT_R32G32B32A32_UINT = 107,
+ VK_FORMAT_R32G32B32A32_SINT = 108,
+ VK_FORMAT_R32G32B32A32_SFLOAT = 109,
+ VK_FORMAT_R64_UINT = 110,
+ VK_FORMAT_R64_SINT = 111,
+ VK_FORMAT_R64_SFLOAT = 112,
+ VK_FORMAT_R64G64_UINT = 113,
+ VK_FORMAT_R64G64_SINT = 114,
+ VK_FORMAT_R64G64_SFLOAT = 115,
+ VK_FORMAT_R64G64B64_UINT = 116,
+ VK_FORMAT_R64G64B64_SINT = 117,
+ VK_FORMAT_R64G64B64_SFLOAT = 118,
+ VK_FORMAT_R64G64B64A64_UINT = 119,
+ VK_FORMAT_R64G64B64A64_SINT = 120,
+ VK_FORMAT_R64G64B64A64_SFLOAT = 121,
+ VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
+ VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
+ VK_FORMAT_D16_UNORM = 124,
+ VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
+ VK_FORMAT_D32_SFLOAT = 126,
+ VK_FORMAT_S8_UINT = 127,
+ VK_FORMAT_D16_UNORM_S8_UINT = 128,
+ VK_FORMAT_D24_UNORM_S8_UINT = 129,
+ VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
+ VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
+ VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
+ VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
+ VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
+ VK_FORMAT_BC2_UNORM_BLOCK = 135,
+ VK_FORMAT_BC2_SRGB_BLOCK = 136,
+ VK_FORMAT_BC3_UNORM_BLOCK = 137,
+ VK_FORMAT_BC3_SRGB_BLOCK = 138,
+ VK_FORMAT_BC4_UNORM_BLOCK = 139,
+ VK_FORMAT_BC4_SNORM_BLOCK = 140,
+ VK_FORMAT_BC5_UNORM_BLOCK = 141,
+ VK_FORMAT_BC5_SNORM_BLOCK = 142,
+ VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
+ VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
+ VK_FORMAT_BC7_UNORM_BLOCK = 145,
+ VK_FORMAT_BC7_SRGB_BLOCK = 146,
+ VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
+ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
+ VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
+ VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
+ VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
+ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
+ VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
+ VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
+ VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
+ VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
+ VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
+ VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
+ VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
+ VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
+ VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
+ VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
+ VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
+ VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
+ VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
+ VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
+ VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
+ VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
+ VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
+ VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
+ VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
+ VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
+ VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
+ VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
+ VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
+ VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
+ VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
+ VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
+ VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
+ VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
+ VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
+ VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
+ VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
+ VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032,
+ // Provided by VK_VERSION_1_1
+ VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012,
+ // Provided by VK_VERSION_1_3
+ VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013,
+ // Provided by VK_VERSION_1_4
+ VK_FORMAT_A1B5G5R5_UNORM_PACK16 = 1000470000,
+ // Provided by VK_VERSION_1_4
+ VK_FORMAT_A8_UNORM = 1000470001,
+ // Provided by VK_IMG_format_pvrtc
+ VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000,
+ // Provided by VK_IMG_format_pvrtc
+ VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001,
+ // Provided by VK_IMG_format_pvrtc
+ VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002,
+ // Provided by VK_IMG_format_pvrtc
+ VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003,
+ // Provided by VK_IMG_format_pvrtc
+ VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004,
+ // Provided by VK_IMG_format_pvrtc
+ VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005,
+ // Provided by VK_IMG_format_pvrtc
+ VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006,
+ // Provided by VK_IMG_format_pvrtc
+ VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007,
+ // Provided by VK_ARM_tensors
+ VK_FORMAT_R8_BOOL_ARM = 1000460000,
+ // Provided by VK_NV_optical_flow
+ VK_FORMAT_R16G16_SFIXED5_NV = 1000464000,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R10X6_UINT_PACK16_ARM = 1000609000,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R10X6G10X6_UINT_2PACK16_ARM = 1000609001,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R10X6G10X6B10X6A10X6_UINT_4PACK16_ARM = 1000609002,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R12X4_UINT_PACK16_ARM = 1000609003,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R12X4G12X4_UINT_2PACK16_ARM = 1000609004,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R12X4G12X4B12X4A12X4_UINT_4PACK16_ARM = 1000609005,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R14X2_UINT_PACK16_ARM = 1000609006,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R14X2G14X2_UINT_2PACK16_ARM = 1000609007,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R14X2G14X2B14X2A14X2_UINT_4PACK16_ARM = 1000609008,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R14X2_UNORM_PACK16_ARM = 1000609009,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R14X2G14X2_UNORM_2PACK16_ARM = 1000609010,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_R14X2G14X2B14X2A14X2_UNORM_4PACK16_ARM = 1000609011,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_G14X2_B14X2R14X2_2PLANE_420_UNORM_3PACK16_ARM = 1000609012,
+ // Provided by VK_ARM_format_pack
+ VK_FORMAT_G14X2_B14X2R14X2_2PLANE_422_UNORM_3PACK16_ARM = 1000609013,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK,
+ // Provided by VK_EXT_texture_compression_astc_hdr
+ VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_R10X6_UNORM_PACK16_KHR = VK_FORMAT_R10X6_UNORM_PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR = VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR = VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_R12X4_UNORM_PACK16_KHR = VK_FORMAT_R12X4_UNORM_PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR = VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR = VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G16B16G16R16_422_UNORM_KHR = VK_FORMAT_G16B16G16R16_422_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_B16G16R16G16_422_UNORM_KHR = VK_FORMAT_B16G16R16G16_422_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
+ // Provided by VK_KHR_sampler_ycbcr_conversion
+ VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
+ // Provided by VK_EXT_ycbcr_2plane_444_formats
+ VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
+ // Provided by VK_EXT_ycbcr_2plane_444_formats
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
+ // Provided by VK_EXT_ycbcr_2plane_444_formats
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16,
+ // Provided by VK_EXT_ycbcr_2plane_444_formats
+ VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM,
+ // Provided by VK_EXT_4444_formats
+ VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16,
+ // Provided by VK_EXT_4444_formats
+ VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16,
+ // Provided by VK_NV_optical_flow
+ // VK_FORMAT_R16G16_S10_5_NV is a deprecated alias
+ VK_FORMAT_R16G16_S10_5_NV = VK_FORMAT_R16G16_SFIXED5_NV,
+ // Provided by VK_KHR_maintenance5
+ VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR = VK_FORMAT_A1B5G5R5_UNORM_PACK16,
+ // Provided by VK_KHR_maintenance5
+ VK_FORMAT_A8_UNORM_KHR = VK_FORMAT_A8_UNORM,
+} VkFormat;
+*/
\ No newline at end of file
diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c
index 038e1c649..d701691a1 100644
--- a/src/platforms/rcore_desktop_glfw.c
+++ b/src/platforms/rcore_desktop_glfw.c
@@ -1862,8 +1862,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
// to work properly with our implementation (IsKeyDown/IsKeyUp checks)
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
- else if(action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1;
- else if(action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
+ else if (action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1;
+ else if (action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
// WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys
if (((key == KEY_CAPS_LOCK) && ((mods & GLFW_MOD_CAPS_LOCK) > 0)) ||
diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c
index 59f286307..374acd72b 100644
--- a/src/platforms/rcore_desktop_sdl.c
+++ b/src/platforms/rcore_desktop_sdl.c
@@ -52,13 +52,27 @@
#ifndef SDL_ENABLE_OLD_NAMES
#define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily
#endif
-#include "SDL.h" // SDL base library (window/rendered, input, timing... functionality)
+// SDL base library (window/rendered, input, timing... functionality)
+#ifdef USING_SDL3_PROJECT
+ #include "SDL3/SDL.h"
+#elif USING_SDL2_PROJECT
+ #include "SDL2/SDL.h"
+#else
+ #include "SDL.h"
+#endif
#if defined(GRAPHICS_API_OPENGL_ES2)
// It seems it does not need to be included to work
//#include "SDL_opengles2.h"
#else
- #include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
+ // SDL OpenGL functionality (if required, instead of internal renderer)
+ #ifdef USING_SDL3_PROJECT
+ #include "SDL3/SDL_opengl.h"
+ #elif USING_SDL2_PROJECT
+ #include "SDL2/SDL_opengl.h"
+ #else
+ #include "SDL_opengl.h"
+ #endif
#endif
//----------------------------------------------------------------------------------
@@ -238,8 +252,7 @@ static const int CursorsLUT[] = {
//SDL_SYSTEM_CURSOR_WAITARROW, // No equivalent implemented on MouseCursor enum on raylib.h
};
-
-// SDL3 Migration Layer made to avoid `ifdefs` inside functions when we can.
+// SDL3 Migration Layer made to avoid 'ifdefs' inside functions when we can.
#if defined(PLATFORM_DESKTOP_SDL3)
// SDL3 Migration:
@@ -290,13 +303,13 @@ int SDL_GetNumVideoDisplays(void)
int monitorCount = 0;
SDL_DisplayID *displays = SDL_GetDisplays(&monitorCount);
- // Safe because If `mem` is NULL, SDL_free does nothing
+ // Safe because If 'mem' is NULL, SDL_free does nothing
SDL_free(displays);
return monitorCount;
}
-// SLD3 Migration: To emulate SDL2 this function should return `SDL_DISABLE` or `SDL_ENABLE`
+// SLD3 Migration: To emulate SDL2 this function should return 'SDL_DISABLE' or 'SDL_ENABLE'
// representing the *processing state* of the event before this function makes any changes to it
Uint8 SDL_EventState(Uint32 type, int state)
{
@@ -567,7 +580,7 @@ void SetWindowState(unsigned int flags)
if (flags & FLAG_WINDOW_UNFOCUSED)
{
// NOTE: To be able to implement this part it seems that we should
- // do it ourselves, via `Windows.h`, `X11/Xlib.h` or even `Cocoa.h`
+ // do it ourselves, via 'windows.h', 'X11/Xlib.h' or even 'Cocoa.h'
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL");
}
if (flags & FLAG_WINDOW_TOPMOST)
@@ -1155,13 +1168,13 @@ Image GetClipboardImage(void)
image = LoadImageFromMemory(imageExtensions[i], fileData, dataSize);
if (IsImageValid(image))
{
- TRACELOG(LOG_INFO, "Clipboard image: Got image from clipboard as a `%s` successfully", imageExtensions[i]);
+ TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]);
return image;
}
}
}
- if (!IsImageValid(image)) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data. Error: %s", SDL_GetError());
+ if (!IsImageValid(image)) TRACELOG(LOG_WARNING, "Clipboard: Couldn't get clipboard data. ERROR: %s", SDL_GetError());
#endif
return image;
diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c
index 06d3b5d5a..a3051f485 100644
--- a/src/platforms/rcore_drm.c
+++ b/src/platforms/rcore_drm.c
@@ -48,11 +48,11 @@
*
**********************************************************************************************/
-#include // POSIX file control definitions - open(), creat(), fcntl()
-#include // POSIX standard function definitions - read(), close(), STDIN_FILENO
-#include // POSIX terminal control definitions - tcgetattr(), tcsetattr()
-#include // POSIX threads management (inputs reading)
-#include // POSIX directory browsing
+#include // POSIX file control definitions - open(), creat(), fcntl()
+#include // POSIX standard function definitions - read(), close(), STDIN_FILENO
+#include // POSIX terminal control definitions - tcgetattr(), tcsetattr()
+#include // POSIX threads management (inputs reading)
+#include // POSIX directory browsing
#include // Required for: ioctl() - UNIX System call for device-specific input/output operations
#include // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
@@ -71,6 +71,14 @@
#include "EGL/egl.h" // Native platform windowing system interface
#include "EGL/eglext.h" // EGL extensions
+// NOTE: DRM cache enables triple buffered DRM caching
+#if defined(SUPPORT_DRM_CACHE)
+ #include // Required for: drmHandleEvent() poll
+ #include // Required for: EBUSY, EAGAIN
+
+ #define MAX_DRM_CACHED_BUFFERS 3
+#endif // SUPPORT_DRM_CACHE
+
#ifndef EGL_OPENGL_ES3_BIT
#define EGL_OPENGL_ES3_BIT 0x40
#endif
@@ -78,18 +86,16 @@
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event number
+#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event number
-#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events
+#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events
-// So actually the biggest key is KEY_CNT but we only really map the keys up to
-// KEY_ALS_TOGGLE
+// Actually biggest key is KEY_CNT but we only really map the keys up to KEY_ALS_TOGGLE
#define KEYMAP_SIZE KEY_ALS_TOGGLE
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
-
typedef struct {
// Display data
int fd; // File descriptor for /dev/dri/...
@@ -129,6 +135,18 @@ typedef struct {
int gamepadCount; // The number of gamepads registered
} PlatformData;
+#if defined(SUPPORT_DRM_CACHE)
+typedef struct {
+ struct gbm_bo *bo; // Graphics buffer object
+ uint32_t fbId; // DRM framebuffer ID
+} FramebufferCache;
+
+static FramebufferCache fbCache[MAX_DRM_CACHED_BUFFERS] = { 0 };
+static volatile int fbCacheCount = 0;
+static volatile bool pendingFlip = false;
+static bool crtcSet = false;
+#endif // SUPPORT_DRM_CACHE
+
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
@@ -551,6 +569,212 @@ void DisableCursor(void)
CORE.Input.Mouse.cursorHidden = true;
}
+#if defined(SUPPORT_DRM_CACHE)
+
+// Destroy cached framebuffer callback, set by gbm_bo_set_user_data()
+static void DestroyFrameBufferCallback(struct gbm_bo *bo, void *data)
+{
+ uint32_t fbId = (uintptr_t)data;
+
+ // Remove from cache
+ for (int i = 0; i < fbCacheCount; i++)
+ {
+ if (fbCache[i].bo == bo)
+ {
+ TRACELOG(LOG_INFO, "DISPLAY: DRM: Framebuffer removed [%u]", (uintptr_t)fbId);
+ drmModeRmFB(platform.fd, fbCache[i].fbId); // Release DRM FB
+
+ // Shift remaining entries
+ for (int j = i; j < fbCacheCount - 1; j++) fbCache[j] = fbCache[j + 1];
+
+ fbCacheCount--;
+ break;
+ }
+ }
+}
+
+// Create or retrieve cached DRM FB for BO
+static uint32_t GetOrCreateFbForBo(struct gbm_bo *bo)
+{
+ // Try to find existing cache entry
+ for (int i = 0; i < fbCacheCount; i++)
+ {
+ if (fbCache[i].bo == bo) return fbCache[i].fbId;
+ }
+
+ // Create new entry if cache not full
+ if (fbCacheCount >= MAX_DRM_CACHED_BUFFERS) return 0; // FB cache full
+
+ uint32_t handle = gbm_bo_get_handle(bo).u32;
+ uint32_t stride = gbm_bo_get_stride(bo);
+ uint32_t width = gbm_bo_get_width(bo);
+ uint32_t height = gbm_bo_get_height(bo);
+
+ uint32_t fbId = 0;
+ if (drmModeAddFB(platform.fd, width, height, 24, 32, stride, handle, &fbId)) return 0;
+
+ // Store in cache
+ fbCache[fbCacheCount] = (FramebufferCache){ .bo = bo, .fbId = fbId };
+ fbCacheCount++;
+
+ // Set destroy callback to auto-cleanup
+ gbm_bo_set_user_data(bo, (void *)(uintptr_t)fbId, DestroyFrameBufferCallback);
+
+ TRACELOG(LOG_INFO, "DISPLAY: DRM: Added new buffer object [%u]" , (uintptr_t)fbId);
+
+ return fbId;
+}
+
+// Renders a blank frame to allocate initial buffers
+// TODO: WARNING: Platform layers do not include OpenGL code!
+void RenderBlankFrame()
+{
+ glClearColor(0, 0, 0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(platform.device, platform.surface);
+ glFinish(); // Ensure the buffer is processed
+}
+
+// Initialize with first buffer only
+int InitSwapScreenBuffer()
+{
+ if (!platform.gbmSurface || (platform.fd < 0))
+ {
+ TRACELOG(LOG_ERROR, "DISPLAY: DRM: Swap buffers can not be initialized");
+ return -1;
+ }
+
+ // Render a blank frame to allocate buffers
+ RenderBlankFrame();
+
+ // Get first buffer
+ struct gbm_bo *bo = gbm_surface_lock_front_buffer(platform.gbmSurface);
+ if (!bo)
+ {
+ TRACELOG(LOG_ERROR, "DISPLAY: DRM: Failed to lock initial swap buffer");
+ return -1;
+ }
+
+ // Create FB for first buffer
+ uint32_t fbId = GetOrCreateFbForBo(bo);
+ if (!fbId)
+ {
+ gbm_surface_release_buffer(platform.gbmSurface, bo);
+ return -1;
+ }
+
+ // Initial CRTC setup
+ if (drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, fbId, 0, 0, &platform.connector->connector_id, 1, &platform.connector->modes[platform.modeIndex]))
+ {
+ TRACELOG(LOG_ERROR, "DISPLAY: DRM: Failed to initialize CRTC setup. ERROR: %s", strerror(errno));
+ gbm_surface_release_buffer(platform.gbmSurface, bo);
+ return -1;
+ }
+
+ // Keep first buffer locked until flipped
+ platform.prevBO = bo;
+ crtcSet = true;
+
+ return 0;
+}
+
+// Static page flip handler
+// NOTE: Called once the drmModePageFlip() finished from the drmHandleEvent() context
+static void PageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
+{
+ // Unused inputs
+ (void)fd;
+ (void)frame;
+ (void)sec;
+ (void)usec;
+
+ pendingFlip = false;
+ struct gbm_bo *boToRelease = (struct gbm_bo *)data;
+
+ // Buffers are released after the flip completes (via page_flip_handler), ensuring they're no longer in use
+ // Prevents the GPU from writing to a buffer being scanned out
+ if (boToRelease) gbm_surface_release_buffer(platform.gbmSurface, boToRelease);
+}
+
+// Swap implementation with proper caching
+void SwapScreenBuffer()
+{
+ if (!crtcSet || !platform.gbmSurface) return;
+
+ static int loopCnt = 0;
+ static int errCnt[5] = {0};
+ loopCnt++;
+
+ // Call this only, if pendingFlip is not set
+ eglSwapBuffers(platform.device, platform.surface);
+
+ // Process pending events non-blocking
+ drmEventContext evctx = {
+ .version = DRM_EVENT_CONTEXT_VERSION,
+ .page_flip_handler = PageFlipHandler
+ };
+
+ struct pollfd pfd = { .fd = platform.fd, .events = POLLIN };
+
+ // Polling for event for 0ms
+ while (poll(&pfd, 1, 0) > 0) drmHandleEvent(platform.fd, &evctx);
+
+ // Skip if previous flip pending
+ if (pendingFlip)
+ {
+ errCnt[0]++; // Skip frame: flip pending
+ return;
+ }
+
+ // Get new front buffer
+ struct gbm_bo *nextBO = gbm_surface_lock_front_buffer(platform.gbmSurface);
+ if (!nextBO) // Failed to lock front buffer
+ {
+ errCnt[1]++;
+ return;
+ }
+
+ // Get FB ID (creates new one if needed)
+ uint32_t fbId = GetOrCreateFbForBo(nextBO);
+ if (!fbId)
+ {
+ gbm_surface_release_buffer(platform.gbmSurface, nextBO);
+ errCnt[2]++;
+ return;
+ }
+
+ // Attempt page flip
+ // NOTE: rmModePageFlip() schedules a buffer-flip for the next vblank and then notifies us about it.
+ // It takes a CRTC-id, fb-id and an arbitrary data-pointer and then schedules the page-flip.
+ // This is fully asynchronous and when the page-flip happens, the DRM-fd will become readable and we can call drmHandleEvent().
+ // This will read all vblank/page-flip events and call our modeset_page_flip_event() callback with the data-pointer that we passed to drmModePageFlip().
+ // We simply call modeset_draw_dev() then so the next frame is rendered... returns immediately.
+ if (drmModePageFlip(platform.fd, platform.crtc->crtc_id, fbId, DRM_MODE_PAGE_FLIP_EVENT, platform.prevBO))
+ {
+ if (errno == EBUSY) errCnt[3]++; // Display busy - skip flip
+ else errCnt[4]++; // Page flip failed
+
+ gbm_surface_release_buffer(platform.gbmSurface, nextBO);
+ return;
+ }
+
+ // Success: update state
+ pendingFlip = true;
+ platform.prevBO = nextBO;
+
+/*
+ // Some benchmarking code
+ if (loopCnt >= 600)
+ {
+ TRACELOG(LOG_INFO, "DRM: Error counters: %d, %d, %d, %d, %d, %d", errCnt[0], errCnt[1], errCnt[2], errCnt[3], errCnt[4], loopCnt);
+ for (int i = 0; i < 5; i++) errCnt[i] = 0;
+ loopCnt = 0;
+ }
+*/
+}
+
+#else // !SUPPORT_DRM_CACHE
+
// Swap back buffer with front buffer (screen drawing)
void SwapScreenBuffer(void)
{
@@ -580,6 +804,7 @@ void SwapScreenBuffer(void)
platform.prevBO = bo;
}
+#endif // SUPPORT_DRM_CACHE
//----------------------------------------------------------------------------------
// Module Functions Definition: Misc
@@ -1083,9 +1308,21 @@ int InitPlatform(void)
CORE.Storage.basePath = GetWorkingDirectory();
//----------------------------------------------------------------------------
+#if defined(SUPPORT_DRM_CACHE)
+ if (InitSwapScreenBuffer() == 0)
+ {
+ TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");
+ return 0;
+ }
+ else
+ {
+ TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized failed");
+ return -1;
+ }
+#else // !SUPPORT_DRM_CACHE
TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");
-
return 0;
+#endif
}
// Close platform
diff --git a/src/raudio.c b/src/raudio.c
index ba1fba081..3301d7009 100644
--- a/src/raudio.c
+++ b/src/raudio.c
@@ -1547,7 +1547,8 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
music.looping = true; // Looping enabled by default
musicLoaded = true;
}
- else {
+ else
+ {
drwav_uninit(ctxWav);
RL_FREE(ctxWav);
}
diff --git a/src/rcore.c b/src/rcore.c
index e97ef357c..c0af6654a 100644
--- a/src/rcore.c
+++ b/src/rcore.c
@@ -539,7 +539,7 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
#pragma message ("WARNING: Getting image from the clipboard might not work without SUPPORT_FILEFORMAT_PNG or SUPPORT_FILEFORMAT_JPG")
#endif
- // Not needed because `rtexture.c` will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
+ // Not needed because 'rtexture.c' will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
// #if !defined(STBI_REQUIRED)
// #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
// #endif
diff --git a/src/rlgl.h b/src/rlgl.h
index b6703c923..2adf1753d 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -710,6 +710,7 @@ RLAPI void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha,
RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states)
RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures)
RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
+RLAPI void *rlGetProcAddress(const char *procName); // Get OpenGL procedure address
RLAPI int rlGetVersion(void); // Get current OpenGL version
RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width
RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width
@@ -1041,10 +1042,15 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
// Types and Structures Definition
//----------------------------------------------------------------------------------
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+
+typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc)
+
typedef struct rlglData {
rlRenderBatch *currentBatch; // Current render batch
rlRenderBatch defaultBatch; // Default internal render batch
+ rlglLoadProc loader; // OpenGL function loader
+
struct {
int vertexCounter; // Current active render batch vertex counter (generic, used for all batches)
float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*())
@@ -1114,8 +1120,6 @@ typedef struct rlglData {
} ExtSupported; // Extensions supported flags
} rlglData;
-typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc)
-
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
//----------------------------------------------------------------------------------
@@ -2567,6 +2571,8 @@ void rlLoadExtensions(void *loader)
TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION));
TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
+ RLGL.loader = (rlglLoadProc)loader;
+
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: Anisotropy levels capability is an extension
#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
@@ -2625,6 +2631,11 @@ void rlLoadExtensions(void *loader)
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
}
+// Get OpenGL procedure address
+void *rlGetProcAddress(const char *procName) {
+ return RLGL.loader(procName);
+}
+
// Get current OpenGL version
int rlGetVersion(void)
{
diff --git a/src/rmodels.c b/src/rmodels.c
index ac6f4c594..0dc7572f1 100644
--- a/src/rmodels.c
+++ b/src/rmodels.c
@@ -4292,7 +4292,7 @@ static Model LoadOBJ(const char *fileName)
if (fileText == NULL)
{
- TRACELOG(LOG_ERROR, "MODEL: [%s] Unable to read obj file", fileName);
+ TRACELOG(LOG_WARNING, "MODEL: [%s] Unable to read obj file", fileName);
return model;
}
@@ -4308,7 +4308,7 @@ static Model LoadOBJ(const char *fileName)
if (ret != TINYOBJ_SUCCESS)
{
- TRACELOG(LOG_ERROR, "MODEL: Unable to read obj data %s", fileName);
+ TRACELOG(LOG_WARNING, "MODEL: Unable to read obj data %s", fileName);
return model;
}
diff --git a/src/rtextures.c b/src/rtextures.c
index 771702306..b798caed6 100644
--- a/src/rtextures.c
+++ b/src/rtextures.c
@@ -169,10 +169,13 @@
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
+ #define RL_GPUTEX_MALLOC RL_MALLOC
+ #define RL_GPUTEX_FREE RL_FREE
+ #define RL_GPUTEX_LOG(...) TRACELOG(LOG_WARNING, "IMAGE: " __VA_ARGS__)
+ #define RL_GPUTEX_SHOW_LOG_INFO
#define RL_GPUTEX_IMPLEMENTATION
#include "external/rl_gputex.h" // Required for: rl_load_xxx_from_memory()
// NOTE: Used to read compressed textures data (multiple formats support)
-
#if defined(__GNUC__) // GCC and Clang
#pragma GCC diagnostic pop
#endif