Merge branch 'master' of github.com:raysan5/raylib

This commit is contained in:
Jeffery Myers 2024-10-15 13:25:43 -07:00
commit 0ba02eb1bf
40 changed files with 921 additions and 5431 deletions

View File

@ -31,7 +31,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.0** | [Go](https://golang.org) | Zlib | | [raylib-go](https://github.com/gen2brain/raylib-go) | **5.0** | [Go](https://golang.org) | Zlib |
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib | | [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
| [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** | | [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** |
| [h-raylib](https://github.com/Anut-py/h-raylib) | **5.1-dev** | [Haskell](https://haskell.org) | Apache-2.0 | | [h-raylib](https://github.com/Anut-py/h-raylib) | **5.5-dev** | [Haskell](https://haskell.org) | Apache-2.0 |
| [raylib-hx](https://github.com/foreignsasquatch/raylib-hx) | 4.2 | [Haxe](https://haxe.org) | Zlib | | [raylib-hx](https://github.com/foreignsasquatch/raylib-hx) | 4.2 | [Haxe](https://haxe.org) | Zlib |
| [hb-raylib](https://github.com/MarcosLeonardoMendezGerencir/hb-raylib) | 3.5 | [Harbour](https://harbour.github.io) | MIT | | [hb-raylib](https://github.com/MarcosLeonardoMendezGerencir/hb-raylib) | 3.5 | [Harbour](https://harbour.github.io) | MIT |
| [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT | | [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT |

View File

@ -3,6 +3,17 @@ changelog
Current Release: raylib 5.0 (18 November 2023) Current Release: raylib 5.0 (18 November 2023)
-------------------------------------------------------------------------
Release: raylib 5.5 - 11th Anniversary Edition? (18 November 2024?)
-------------------------------------------------------------------------
KEY CHANGES:
-
-
-
Detailed changes:
...
------------------------------------------------------------------------- -------------------------------------------------------------------------
Release: raylib 5.0 - 10th Anniversary Edition (18 November 2023) Release: raylib 5.0 - 10th Anniversary Edition (18 November 2023)
------------------------------------------------------------------------- -------------------------------------------------------------------------

View File

@ -9,3 +9,6 @@ pub fn build(b: *std.Build) !void {
// expose helper functions to user's build.zig // expose helper functions to user's build.zig
pub const addRaylib = raylib.addRaylib; pub const addRaylib = raylib.addRaylib;
pub const addRaygui = raylib.addRaygui; pub const addRaygui = raylib.addRaygui;
// expose options for compiling
pub const RaylibOptions = raylib.Options;

View File

@ -100,9 +100,10 @@ elseif ("${PLATFORM}" MATCHES "SDL")
endif () endif ()
if (NOT ${OPENGL_VERSION} MATCHES "OFF") if (NOT ${OPENGL_VERSION} MATCHES "OFF")
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}") set(SUGGESTED_GRAPHICS "${GRAPHICS}")
if (${OPENGL_VERSION} MATCHES "4.3") if (${OPENGL_VERSION} MATCHES "4.3")
set(GRAPHICS "GRAPHICS_API_OPENGL_43") set(GRAPHICS "GRAPHICS_API_OPENGL_43")
elseif (${OPENGL_VERSION} MATCHES "3.3") elseif (${OPENGL_VERSION} MATCHES "3.3")
set(GRAPHICS "GRAPHICS_API_OPENGL_33") set(GRAPHICS "GRAPHICS_API_OPENGL_33")
elseif (${OPENGL_VERSION} MATCHES "2.1") elseif (${OPENGL_VERSION} MATCHES "2.1")
@ -114,8 +115,8 @@ if (NOT ${OPENGL_VERSION} MATCHES "OFF")
elseif (${OPENGL_VERSION} MATCHES "ES 3.0") elseif (${OPENGL_VERSION} MATCHES "ES 3.0")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES3") set(GRAPHICS "GRAPHICS_API_OPENGL_ES3")
endif () endif ()
if ("${SUGGESTED_GRAPHICS}" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}") if (NOT "${SUGGESTED_GRAPHICS}" STREQUAL "" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail") message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail.")
endif () endif ()
endif () endif ()

View File

@ -492,6 +492,7 @@ CORE = \
core/core_input_mouse \ core/core_input_mouse \
core/core_input_mouse_wheel \ core/core_input_mouse_wheel \
core/core_input_multitouch \ core/core_input_multitouch \
core/core_input_virtual_controls \
core/core_loading_thread \ core/core_loading_thread \
core/core_random_sequence \ core/core_random_sequence \
core/core_random_values \ core/core_random_values \
@ -548,7 +549,6 @@ TEXTURES = \
textures/textures_sprite_button \ textures/textures_sprite_button \
textures/textures_sprite_explosion \ textures/textures_sprite_explosion \
textures/textures_srcrec_dstrec \ textures/textures_srcrec_dstrec \
textures/textures_svg_loading \
textures/textures_textured_curve \ textures/textures_textured_curve \
textures/textures_to_image textures/textures_to_image

View File

@ -359,6 +359,7 @@ CORE = \
core/core_input_mouse \ core/core_input_mouse \
core/core_input_mouse_wheel \ core/core_input_mouse_wheel \
core/core_input_multitouch \ core/core_input_multitouch \
core/core_input_virtual_controls \
core/core_loading_thread \ core/core_loading_thread \
core/core_random_sequence \ core/core_random_sequence \
core/core_random_values \ core/core_random_values \
@ -414,7 +415,6 @@ TEXTURES = \
textures/textures_sprite_button \ textures/textures_sprite_button \
textures/textures_sprite_explosion \ textures/textures_sprite_explosion \
textures/textures_srcrec_dstrec \ textures/textures_srcrec_dstrec \
textures/textures_svg_loading \
textures/textures_textured_curve \ textures/textures_textured_curve \
textures/textures_to_image textures/textures_to_image
@ -775,10 +775,6 @@ textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/scarfy.png@resources/scarfy.png --preload-file textures/resources/scarfy.png@resources/scarfy.png
textures/textures_svg_loading: textures/textures_svg_loading.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/test.svg
textures/textures_textured_curve: textures/textures_textured_curve.c textures/textures_textured_curve: textures/textures_textured_curve.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
--preload-file textures/resources/road.png@resources/road.png --preload-file textures/resources/road.png@resources/road.png

View File

@ -31,31 +31,32 @@ Examples using raylib core platform functionality like window creation, inputs,
| 05 | [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐️☆☆☆ | 1.1 | **4.2** | [Ray](https://github.com/raysan5) | | 05 | [core_input_gamepad](core/core_input_gamepad.c) | <img src="core/core_input_gamepad.png" alt="core_input_gamepad" width="80"> | ⭐️☆☆☆ | 1.1 | **4.2** | [Ray](https://github.com/raysan5) |
| 06 | [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐️☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) | | 06 | [core_input_multitouch](core/core_input_multitouch.c) | <img src="core/core_input_multitouch.png" alt="core_input_multitouch" width="80"> | ⭐️☆☆☆ | 2.1 | 2.5 | [Berni](https://github.com/Berni8k) |
| 07 | [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) | | 07 | [core_input_gestures](core/core_input_gestures.c) | <img src="core/core_input_gestures.png" alt="core_input_gestures" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) |
| 08 | [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐️⭐️☆☆ | 1.5 | 3.0 | [Ray](https://github.com/raysan5) | | 08 | [core_input_virtual_controls](core/core_input_virtual_controls.c) | <img src="core/core_input_virtual_controls.png" alt="core_input_virtual_controls" width="80"> | ⭐️⭐️☆☆ | **5.0** | **5.0** | [oblerion](https://github.com/oblerion) |
| 09 | [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) | | 09 | [core_2d_camera](core/core_2d_camera.c) | <img src="core/core_2d_camera.png" alt="core_2d_camera" width="80"> | ⭐️⭐️☆☆ | 1.5 | 3.0 | [Ray](https://github.com/raysan5) |
| 10 | [core_2d_camera_platformer](core/core_2d_camera_platformer.c) | <img src="core/core_2d_camera_platformer.png" alt="core_2d_camera_platformer" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [avyy](https://github.com/avyy) | | 10 | [core_2d_camera_mouse_zoom](core/core_2d_camera_mouse_zoom.c) | <img src="core/core_2d_camera_mouse_zoom.png" alt="core_2d_camera_mouse_zoom" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) |
| 11 | [core_2d_camera_split_screen](core/core_2d_camera_split_screen.c) | <img src="core/core_2d_camera_split_screen.png" alt="core_2d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Gabriel dos Santos Sanches](https://github.com/gabrielssanches) | | 11 | [core_2d_camera_platformer](core/core_2d_camera_platformer.c) | <img src="core/core_2d_camera_platformer.png" alt="core_2d_camera_platformer" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [avyy](https://github.com/avyy) |
| 12 | [core_3d_camera_mode](core/core_3d_camera_mode.c) | <img src="core/core_3d_camera_mode.png" alt="core_3d_camera_mode" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | 12 | [core_2d_camera_split_screen](core/core_2d_camera_split_screen.c) | <img src="core/core_2d_camera_split_screen.png" alt="core_2d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | **4.5** | **4.5** | [Gabriel dos Santos Sanches](https://github.com/gabrielssanches) |
| 13 | [core_3d_camera_free](core/core_3d_camera_free.c) | <img src="core/core_3d_camera_free.png" alt="core_3d_camera_free" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | | 13 | [core_3d_camera_mode](core/core_3d_camera_mode.c) | <img src="core/core_3d_camera_mode.png" alt="core_3d_camera_mode" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
| 14 | [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | <img src="core/core_3d_camera_first_person.png" alt="core_3d_camera_first_person" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | | 14 | [core_3d_camera_free](core/core_3d_camera_free.c) | <img src="core/core_3d_camera_free.png" alt="core_3d_camera_free" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
| 15 | [core_3d_camera:split_screen](core/core_3d_camera_split_screen.c) | <img src="core/core_3d_camera_split_screen.png" alt="core_3d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.0** | [Jeffery Myers](https://github.com/JeffM2501) | | 15 | [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | <img src="core/core_3d_camera_first_person.png" alt="core_3d_camera_first_person" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
| 16 | [core_3d_picking](core/core_3d_picking.c) | <img src="core/core_3d_picking.png" alt="core_3d_picking" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | 16 | [core_3d_camera:split_screen](core/core_3d_camera_split_screen.c) | <img src="core/core_3d_camera_split_screen.png" alt="core_3d_camera_split_screen" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.0** | [Jeffery Myers](https://github.com/JeffM2501) |
| 17 | [core_world_screen](core/core_world_screen.c) | <img src="core/core_world_screen.png" alt="core_world_screen" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.4 | [Ray](https://github.com/raysan5) | | 17 | [core_3d_picking](core/core_3d_picking.c) | <img src="core/core_3d_picking.png" alt="core_3d_picking" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
| 18 | [core_custom_logging](core/core_custom_logging.c) | <img src="core/core_custom_logging.png" alt="core_custom_logging" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) | | 18 | [core_world_screen](core/core_world_screen.c) | <img src="core/core_world_screen.png" alt="core_world_screen" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.4 | [Ray](https://github.com/raysan5) |
| 19 | [core_window_flags](core/core_window_flags.c) | <img src="core/core_window_flags.png" alt="core_window_flags" width="80"> | ⭐️⭐️⭐️☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) | | 19 | [core_custom_logging](core/core_custom_logging.c) | <img src="core/core_custom_logging.png" alt="core_custom_logging" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) |
| 20 | [core_window_letterbox](core/core_window_letterbox.c) | <img src="core/core_window_letterbox.png" alt="core_window_letterbox" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Anata](https://github.com/anatagawa) | | 20 | [core_window_flags](core/core_window_flags.c) | <img src="core/core_window_flags.png" alt="core_window_flags" width="80"> | ⭐️⭐️⭐️☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
| 21 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | 21 | [core_window_letterbox](core/core_window_letterbox.c) | <img src="core/core_window_letterbox.png" alt="core_window_letterbox" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Anata](https://github.com/anatagawa) |
| 22 | [core_drop_files](core/core_drop_files.c) | <img src="core/core_drop_files.png" alt="core_drop_files" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | | 22 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
| 23 | [core_random_values](core/core_random_values.c) | <img src="core/core_random_values.png" alt="core_random_values" width="80"> | ⭐️☆☆☆ | 1.1 | 1.1 | [Ray](https://github.com/raysan5) | | 23 | [core_drop_files](core/core_drop_files.c) | <img src="core/core_drop_files.png" alt="core_drop_files" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
| 24 | [core_storage_values](core/core_storage_values.c) | <img src="core/core_storage_values.png" alt="core_storage_values" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) | | 24 | [core_random_values](core/core_random_values.c) | <img src="core/core_random_values.png" alt="core_random_values" width="80"> | ⭐️☆☆☆ | 1.1 | 1.1 | [Ray](https://github.com/raysan5) |
| 25 | [core_vr_simulator](core/core_vr_simulator.c) | <img src="core/core_vr_simulator.png" alt="core_vr_simulator" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | | 25 | [core_storage_values](core/core_storage_values.c) | <img src="core/core_storage_values.png" alt="core_storage_values" width="80"> | ⭐️⭐️☆☆ | 1.4 | **4.2** | [Ray](https://github.com/raysan5) |
| 26 | [core_loading_thread](core/core_loading_thread.c) | <img src="core/core_loading_thread.png" alt="core_loading_thread" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Ray](https://github.com/raysan5) | | 26 | [core_vr_simulator](core/core_vr_simulator.c) | <img src="core/core_vr_simulator.png" alt="core_vr_simulator" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
| 27 | [core_scissor_test](core/core_scissor_test.c) | <img src="core/core_scissor_test.png" alt="core_scissor_test" width="80"> | ⭐️☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) | | 27 | [core_loading_thread](core/core_loading_thread.c) | <img src="core/core_loading_thread.png" alt="core_loading_thread" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.0 | [Ray](https://github.com/raysan5) |
| 28 | [core_basic_screen_manager](core/core_basic_screen_manager.c) | <img src="core/core_basic_screen_manager.png" alt="core_basic_screen_manager" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) | | 28 | [core_scissor_test](core/core_scissor_test.c) | <img src="core/core_scissor_test.png" alt="core_scissor_test" width="80"> | ⭐️☆☆☆ | 2.5 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
| 29 | [core_custom_frame_control](core/core_custom_frame_control.c) | <img src="core/core_custom_frame_control.png" alt="core_custom_frame_control" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) | | 29 | [core_basic_screen_manager](core/core_basic_screen_manager.c) | <img src="core/core_basic_screen_manager.png" alt="core_basic_screen_manager" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
| 30 | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐️⭐️⭐️☆ | 3.7 | **4.0** | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) | | 30 | [core_custom_frame_control](core/core_custom_frame_control.c) | <img src="core/core_custom_frame_control.png" alt="core_custom_frame_control" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Ray](https://github.com/raysan5) |
| 31 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | 31 | [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐️⭐️⭐️☆ | 3.7 | **4.0** | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) |
| 32 | [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐️☆☆☆ | **5.0** | **5.0** | [REDl3east](https://github.com/REDl3east) | | 32 | [core_window_should_close](core/core_window_should_close.c) | <img src="core/core_window_should_close.png" alt="core_window_should_close" width="80"> | ⭐️⭐️☆☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
| 33 | [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐️☆☆☆ | **5.0** | **5.0** | [REDl3east](https://github.com/REDl3east) |
### category: shapes ### category: shapes
@ -63,22 +64,22 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
| 31 | [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | **4.0** | [Ray](https://github.com/raysan5) | | 34 | [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | **4.0** | [Ray](https://github.com/raysan5) |
| 32 | [shapes_bouncing_ball](shapes/shapes_bouncing_ball.c) | <img src="shapes/shapes_bouncing_ball.png" alt="shapes_bouncing_ball" width="80"> | ⭐️☆☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | 35 | [shapes_bouncing_ball](shapes/shapes_bouncing_ball.c) | <img src="shapes/shapes_bouncing_ball.png" alt="shapes_bouncing_ball" width="80"> | ⭐️☆☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
| 33 | [shapes_colors_palette](shapes/shapes_colors_palette.c) | <img src="shapes/shapes_colors_palette.png" alt="shapes_colors_palette" width="80"> | ⭐️⭐️☆☆ | 1.0 | 2.5 | [Ray](https://github.com/raysan5) | | 36 | [shapes_colors_palette](shapes/shapes_colors_palette.c) | <img src="shapes/shapes_colors_palette.png" alt="shapes_colors_palette" width="80"> | ⭐️⭐️☆☆ | 1.0 | 2.5 | [Ray](https://github.com/raysan5) |
| 34 | [shapes_logo_raylib](shapes/shapes_logo_raylib.c) | <img src="shapes/shapes_logo_raylib.png" alt="shapes_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | 37 | [shapes_logo_raylib](shapes/shapes_logo_raylib.c) | <img src="shapes/shapes_logo_raylib.png" alt="shapes_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
| 35 | [shapes_logo_raylib_anim](shapes/shapes_logo_raylib_anim.c) | <img src="shapes/shapes_logo_raylib_anim.png" alt="shapes_logo_raylib_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | | 38 | [shapes_logo_raylib_anim](shapes/shapes_logo_raylib_anim.c) | <img src="shapes/shapes_logo_raylib_anim.png" alt="shapes_logo_raylib_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
| 36 | [shapes_rectangle_scaling](shapes/shapes_rectangle_scaling.c) | <img src="shapes/shapes_rectangle_scaling.png" alt="shapes_rectangle_scaling" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) | | 39 | [shapes_rectangle_scaling](shapes/shapes_rectangle_scaling.c) | <img src="shapes/shapes_rectangle_scaling.png" alt="shapes_rectangle_scaling" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| 37 | [shapes_lines_bezier](shapes/shapes_lines_bezier.c) | <img src="shapes/shapes_lines_bezier.png" alt="shapes_lines_bezier" width="80"> | ⭐️☆☆☆ | 1.7 | 1.7 | [Ray](https://github.com/raysan5) | | 40 | [shapes_lines_bezier](shapes/shapes_lines_bezier.c) | <img src="shapes/shapes_lines_bezier.png" alt="shapes_lines_bezier" width="80"> | ⭐️☆☆☆ | 1.7 | 1.7 | [Ray](https://github.com/raysan5) |
| 38 | [shapes_collision_area](shapes/shapes_collision_area.c) | <img src="shapes/shapes_collision_area.png" alt="shapes_collision_area" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | 41 | [shapes_collision_area](shapes/shapes_collision_area.c) | <img src="shapes/shapes_collision_area.png" alt="shapes_collision_area" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
| 39 | [shapes_following_eyes](shapes/shapes_following_eyes.c) | <img src="shapes/shapes_following_eyes.png" alt="shapes_following_eyes" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | 42 | [shapes_following_eyes](shapes/shapes_following_eyes.c) | <img src="shapes/shapes_following_eyes.png" alt="shapes_following_eyes" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
| 40 | [shapes_easings_ball_anim](shapes/shapes_easings_ball_anim.c) | <img src="shapes/shapes_easings_ball_anim.png" alt="shapes_easings_ball_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | 43 | [shapes_easings_ball_anim](shapes/shapes_easings_ball_anim.c) | <img src="shapes/shapes_easings_ball_anim.png" alt="shapes_easings_ball_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
| 41 | [shapes_easings_box_anim](shapes/shapes_easings_box_anim.c) | <img src="shapes/shapes_easings_box_anim.png" alt="shapes_easings_box_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | 44 | [shapes_easings_box_anim](shapes/shapes_easings_box_anim.c) | <img src="shapes/shapes_easings_box_anim.png" alt="shapes_easings_box_anim" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
| 42 | [shapes_easings_rectangle_array](shapes/shapes_easings_rectangle_array.c) | <img src="shapes/shapes_easings_rectangle_array.png" alt="shapes_easings_rectangle_array" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | 45 | [shapes_easings_rectangle_array](shapes/shapes_easings_rectangle_array.c) | <img src="shapes/shapes_easings_rectangle_array.png" alt="shapes_easings_rectangle_array" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
| 43 | [shapes_draw_ring](shapes/shapes_draw_ring.c) | <img src="shapes/shapes_draw_ring.png" alt="shapes_draw_ring" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) | | 46 | [shapes_draw_ring](shapes/shapes_draw_ring.c) | <img src="shapes/shapes_draw_ring.png" alt="shapes_draw_ring" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| 44 | [shapes_draw_circle_sector](shapes/shapes_draw_circle_sector.c) | <img src="shapes/shapes_draw_circle_sector.png" alt="shapes_draw_circle_sector" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) | | 47 | [shapes_draw_circle_sector](shapes/shapes_draw_circle_sector.c) | <img src="shapes/shapes_draw_circle_sector.png" alt="shapes_draw_circle_sector" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| 45 | [shapes_draw_rectangle_rounded](shapes/shapes_draw_rectangle_rounded.c) | <img src="shapes/shapes_draw_rectangle_rounded.png" alt="shapes_draw_rectangle_rounded" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) | | 48 | [shapes_draw_rectangle_rounded](shapes/shapes_draw_rectangle_rounded.c) | <img src="shapes/shapes_draw_rectangle_rounded.png" alt="shapes_draw_rectangle_rounded" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
| 46 | [shapes_top_down_lights](shapes/shapes_top_down_lights.c) | <img src="shapes/shapes_top_down_lights.png" alt="shapes_top_down_lights" width="80"> | ⭐️⭐️⭐️⭐️ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) | | 49 | [shapes_top_down_lights](shapes/shapes_top_down_lights.c) | <img src="shapes/shapes_top_down_lights.png" alt="shapes_top_down_lights" width="80"> | ⭐️⭐️⭐️⭐️ | **4.2** | **4.2** | [Jeffery Myers](https://github.com/JeffM2501) |
### category: textures ### category: textures
@ -86,28 +87,28 @@ Examples using raylib textures functionality, including image/textures loading/g
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
| 47 | [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | 50 | [textures_logo_raylib](textures/textures_logo_raylib.c) | <img src="textures/textures_logo_raylib.png" alt="textures_logo_raylib" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
| 48 | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | | 51 | [textures_srcrec_dstrec](textures/textures_srcrec_dstrec.c) | <img src="textures/textures_srcrec_dstrec.png" alt="textures_srcrec_dstrec" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
| 49 | [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) | | 52 | [textures_image_drawing](textures/textures_image_drawing.c) | <img src="textures/textures_image_drawing.png" alt="textures_image_drawing" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
| 50 | [textures_image_generation](textures/textures_image_generation.c) | <img src="textures/textures_image_generation.png" alt="textures_image_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | 1.8 | [Ray](https://github.com/raysan5) | | 53 | [textures_image_generation](textures/textures_image_generation.c) | <img src="textures/textures_image_generation.png" alt="textures_image_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | 1.8 | [Ray](https://github.com/raysan5) |
| 51 | [textures_image_loading](textures/textures_image_loading.c) | <img src="textures/textures_image_loading.png" alt="textures_image_loading" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | | 54 | [textures_image_loading](textures/textures_image_loading.c) | <img src="textures/textures_image_loading.png" alt="textures_image_loading" width="80"> | ⭐️☆☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
| 52 | [textures_image_processing](textures/textures_image_processing.c) | <img src="textures/textures_image_processing.png" alt="textures_image_processing" width="80"> | ⭐️⭐️⭐️☆ | 1.4 | 3.5 | [Ray](https://github.com/raysan5) | | 55 | [textures_image_processing](textures/textures_image_processing.c) | <img src="textures/textures_image_processing.png" alt="textures_image_processing" width="80"> | ⭐️⭐️⭐️☆ | 1.4 | 3.5 | [Ray](https://github.com/raysan5) |
| 53 | [textures_image_text](textures/textures_image_text.c) | <img src="textures/textures_image_text.png" alt="textures_image_text" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) | | 56 | [textures_image_text](textures/textures_image_text.c) | <img src="textures/textures_image_text.png" alt="textures_image_text" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
| 54 | [textures_to_image](textures/textures_to_image.c) | <img src="textures/textures_to_image.png" alt="textures_to_image" width="80"> | ⭐️☆☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | 57 | [textures_to_image](textures/textures_to_image.c) | <img src="textures/textures_to_image.png" alt="textures_to_image" width="80"> | ⭐️☆☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
| 55 | [textures_raw_data](textures/textures_raw_data.c) | <img src="textures/textures_raw_data.png" alt="textures_raw_data" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) | | 58 | [textures_raw_data](textures/textures_raw_data.c) | <img src="textures/textures_raw_data.png" alt="textures_raw_data" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
| 56 | [textures_particles_blending](textures/textures_particles_blending.c) | <img src="textures/textures_particles_blending.png" alt="textures_particles_blending" width="80"> | ⭐️☆☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) | | 59 | [textures_particles_blending](textures/textures_particles_blending.c) | <img src="textures/textures_particles_blending.png" alt="textures_particles_blending" width="80"> | ⭐️☆☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
| 57 | [textures_npatch_drawing](textures/textures_npatch_drawing.c) | <img src="textures/textures_npatch_drawing.png" alt="textures_npatch_drawing" width="80"> | ⭐️⭐️⭐️☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) | | 60 | [textures_npatch_drawing](textures/textures_npatch_drawing.c) | <img src="textures/textures_npatch_drawing.png" alt="textures_npatch_drawing" width="80"> | ⭐️⭐️⭐️☆ | 2.0 | 2.5 | [Jorge A. Gomes](https://github.com/overdev) |
| 58 | [textures_background_scrolling](textures/textures_background_scrolling.c) | <img src="textures/textures_background_scrolling.png" alt="textures_background_scrolling" width="80"> | ⭐️☆☆☆ | 2.0 | 2.5 | [Ray](https://github.com/raysan5) | | 61 | [textures_background_scrolling](textures/textures_background_scrolling.c) | <img src="textures/textures_background_scrolling.png" alt="textures_background_scrolling" width="80"> | ⭐️☆☆☆ | 2.0 | 2.5 | [Ray](https://github.com/raysan5) |
| 59 | [textures_sprite_anim](textures/textures_sprite_anim.c) | <img src="textures/textures_sprite_anim.png" alt="textures_sprite_anim" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) | | 62 | [textures_sprite_anim](textures/textures_sprite_anim.c) | <img src="textures/textures_sprite_anim.png" alt="textures_sprite_anim" width="80"> | ⭐️⭐️☆☆ | 1.3 | 1.3 | [Ray](https://github.com/raysan5) |
| 60 | [textures_sprite_button](textures/textures_sprite_button.c) | <img src="textures/textures_sprite_button.png" alt="textures_sprite_button" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) | | 63 | [textures_sprite_button](textures/textures_sprite_button.c) | <img src="textures/textures_sprite_button.png" alt="textures_sprite_button" width="80"> | ⭐️⭐️☆☆ | 2.5 | 2.5 | [Ray](https://github.com/raysan5) |
| 61 | [textures_sprite_explosion](textures/textures_sprite_explosion.c) | <img src="textures/textures_sprite_explosion.png" alt="textures_sprite_explosion" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) | | 64 | [textures_sprite_explosion](textures/textures_sprite_explosion.c) | <img src="textures/textures_sprite_explosion.png" alt="textures_sprite_explosion" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
| 62 | [textures_bunnymark](textures/textures_bunnymark.c) | <img src="textures/textures_bunnymark.png" alt="textures_bunnymark" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | 2.5 | [Ray](https://github.com/raysan5) | | 65 | [textures_bunnymark](textures/textures_bunnymark.c) | <img src="textures/textures_bunnymark.png" alt="textures_bunnymark" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | 2.5 | [Ray](https://github.com/raysan5) |
| 63 | [textures_mouse_painting](textures/textures_mouse_painting.c) | <img src="textures/textures_mouse_painting.png" alt="textures_mouse_painting" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) | | 66 | [textures_mouse_painting](textures/textures_mouse_painting.c) | <img src="textures/textures_mouse_painting.png" alt="textures_mouse_painting" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Chris Dill](https://github.com/MysteriousSpace) |
| 64 | [textures_blend_modes](textures/textures_blend_modes.c) | <img src="textures/textures_blend_modes.png" alt="textures_blend_modes" width="80"> | ⭐️☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) | | 67 | [textures_blend_modes](textures/textures_blend_modes.c) | <img src="textures/textures_blend_modes.png" alt="textures_blend_modes" width="80"> | ⭐️☆☆☆ | 3.5 | 3.5 | [Karlo Licudine](https://github.com/accidentalrebel) |
| 65 | [textures_draw_tiled](textures/textures_draw_tiled.c) | <img src="textures/textures_draw_tiled.png" alt="textures_draw_tiled" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | **4.2** | [Vlad Adrian](https://github.com/demizdor) | | 68 | [textures_draw_tiled](textures/textures_draw_tiled.c) | <img src="textures/textures_draw_tiled.png" alt="textures_draw_tiled" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | **4.2** | [Vlad Adrian](https://github.com/demizdor) |
| 66 | [textures_polygon](textures/textures_polygon.c) | <img src="textures/textures_polygon.png" alt="textures_polygon" width="80"> | ⭐️☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/codifies) | | 69 | [textures_polygon](textures/textures_polygon.c) | <img src="textures/textures_polygon.png" alt="textures_polygon" width="80"> | ⭐️☆☆☆ | 3.7 | 3.7 | [Chris Camacho](https://github.com/codifies) |
| 67 | [textures_fog_of_war](textures/textures_fog_of_war.c) | <img src="textures/textures_fog_of_war.png" alt="textures_fog_of_war" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | 70 | [textures_fog_of_war](textures/textures_fog_of_war.c) | <img src="textures/textures_fog_of_war.png" alt="textures_fog_of_war" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
| 68 | [textures_gif_player](textures/textures_gif_player.c) | <img src="textures/textures_gif_player.png" alt="textures_gif_player" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | 71 | [textures_gif_player](textures/textures_gif_player.c) | <img src="textures/textures_gif_player.png" alt="textures_gif_player" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
### category: text ### category: text
@ -115,18 +116,18 @@ Examples using raylib text functionality, including sprite fonts loading/generat
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
| 69 | [text_raylib_fonts](text/text_raylib_fonts.c) | <img src="text/text_raylib_fonts.png" alt="text_raylib_fonts" width="80"> | ⭐️☆☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) | | 72 | [text_raylib_fonts](text/text_raylib_fonts.c) | <img src="text/text_raylib_fonts.png" alt="text_raylib_fonts" width="80"> | ⭐️☆☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
| 70 | [text_font_spritefont](text/text_font_spritefont.c) | <img src="text/text_font_spritefont.png" alt="text_font_spritefont" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) | | 73 | [text_font_spritefont](text/text_font_spritefont.c) | <img src="text/text_font_spritefont.png" alt="text_font_spritefont" width="80"> | ⭐️☆☆☆ | 1.0 | 1.0 | [Ray](https://github.com/raysan5) |
| 71 | [text_font_filters](text/text_font_filters.c) | <img src="text/text_font_filters.png" alt="text_font_filters" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | | 74 | [text_font_filters](text/text_font_filters.c) | <img src="text/text_font_filters.png" alt="text_font_filters" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
| 72 | [text_font_loading](text/text_font_loading.c) | <img src="text/text_font_loading.png" alt="text_font_loading" width="80"> | ⭐️☆☆☆ | 1.4 | 3.0 | [Ray](https://github.com/raysan5) | | 75 | [text_font_loading](text/text_font_loading.c) | <img src="text/text_font_loading.png" alt="text_font_loading" width="80"> | ⭐️☆☆☆ | 1.4 | 3.0 | [Ray](https://github.com/raysan5) |
| 73 | [text_font_sdf](text/text_font_sdf.c) | <img src="text/text_font_sdf.png" alt="text_font_sdf" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | 76 | [text_font_sdf](text/text_font_sdf.c) | <img src="text/text_font_sdf.png" alt="text_font_sdf" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
| 74 | [text_format_text](text/text_format_text.c) | <img src="text/text_format_text.png" alt="text_format_text" width="80"> | ⭐️☆☆☆ | 1.1 | 3.0 | [Ray](https://github.com/raysan5) | | 77 | [text_format_text](text/text_format_text.c) | <img src="text/text_format_text.png" alt="text_format_text" width="80"> | ⭐️☆☆☆ | 1.1 | 3.0 | [Ray](https://github.com/raysan5) |
| 75 | [text_input_box](text/text_input_box.c) | <img src="text/text_input_box.png" alt="text_input_box" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) | | 78 | [text_input_box](text/text_input_box.c) | <img src="text/text_input_box.png" alt="text_input_box" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.5 | [Ray](https://github.com/raysan5) |
| 76 | [text_writing_anim](text/text_writing_anim.c) | <img src="text/text_writing_anim.png" alt="text_writing_anim" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) | | 79 | [text_writing_anim](text/text_writing_anim.c) | <img src="text/text_writing_anim.png" alt="text_writing_anim" width="80"> | ⭐️⭐️☆☆ | 1.4 | 1.4 | [Ray](https://github.com/raysan5) |
| 77 | [text_rectangle_bounds](text/text_rectangle_bounds.c) | <img src="text/text_rectangle_bounds.png" alt="text_rectangle_bounds" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) | | 80 | [text_rectangle_bounds](text/text_rectangle_bounds.c) | <img src="text/text_rectangle_bounds.png" alt="text_rectangle_bounds" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
| 78 | [text_unicode](text/text_unicode.c) | <img src="text/text_unicode.png" alt="text_unicode" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) | | 81 | [text_unicode](text/text_unicode.c) | <img src="text/text_unicode.png" alt="text_unicode" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
| 79 | [text_draw_3d](text/text_draw_3d.c) | <img src="text/text_draw_3d.png" alt="text_draw_3d" width="80"> | ⭐️⭐️⭐️⭐️ | 3.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) | | 82 | [text_draw_3d](text/text_draw_3d.c) | <img src="text/text_draw_3d.png" alt="text_draw_3d" width="80"> | ⭐️⭐️⭐️⭐️ | 3.5 | **4.0** | [Vlad Adrian](https://github.com/demizdor) |
| 80 | [text_codepoints_loading](text/text_codepoints_loading.c) | <img src="text/text_codepoints_loading.png" alt="text_codepoints_loading" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) | | 83 | [text_codepoints_loading](text/text_codepoints_loading.c) | <img src="text/text_codepoints_loading.png" alt="text_codepoints_loading" width="80"> | ⭐️⭐️⭐️☆ | **4.2** | **4.2** | [Ray](https://github.com/raysan5) |
### category: models ### category: models
@ -134,25 +135,25 @@ Examples using raylib models functionality, including models loading/generation
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
| 81 | [models_animation](models/models_animation.c) | <img src="models/models_animation.png" alt="models_animation" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [culacant](https://github.com/culacant) | | 84 | [models_animation](models/models_animation.c) | <img src="models/models_animation.png" alt="models_animation" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [culacant](https://github.com/culacant) |
| 82 | [models_billboard](models/models_billboard.c) | <img src="models/models_billboard.png" alt="models_billboard" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) | | 85 | [models_billboard](models/models_billboard.c) | <img src="models/models_billboard.png" alt="models_billboard" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
| 83 | [models_box_collisions](models/models_box_collisions.c) | <img src="models/models_box_collisions.png" alt="models_box_collisions" width="80"> | ⭐️☆☆☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) | | 86 | [models_box_collisions](models/models_box_collisions.c) | <img src="models/models_box_collisions.png" alt="models_box_collisions" width="80"> | ⭐️☆☆☆ | 1.3 | 3.5 | [Ray](https://github.com/raysan5) |
| 84 | [models_cubicmap](models/models_cubicmap.c) | <img src="models/models_cubicmap.png" alt="models_cubicmap" width="80"> | ⭐️⭐️☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) | | 87 | [models_cubicmap](models/models_cubicmap.c) | <img src="models/models_cubicmap.png" alt="models_cubicmap" width="80"> | ⭐️⭐️☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
| 85 | [models_first_person_maze](models/models_first_person_maze.c) | <img src="models/models_first_person_maze.png" alt="models_first_person_maze" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) | | 88 | [models_first_person_maze](models/models_first_person_maze.c) | <img src="models/models_first_person_maze.png" alt="models_first_person_maze" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.5 | [Ray](https://github.com/raysan5) |
| 86 | [models_geometric_shapes](models/models_geometric_shapes.c) | <img src="models/models_geometric_shapes.png" alt="models_geometric_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | 3.5 | [Ray](https://github.com/raysan5) | | 89 | [models_geometric_shapes](models/models_geometric_shapes.c) | <img src="models/models_geometric_shapes.png" alt="models_geometric_shapes" width="80"> | ⭐️☆☆☆ | 1.0 | 3.5 | [Ray](https://github.com/raysan5) |
| 87 | [models_mesh_generation](models/models_mesh_generation.c) | <img src="models/models_mesh_generation.png" alt="models_mesh_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) | | 90 | [models_mesh_generation](models/models_mesh_generation.c) | <img src="models/models_mesh_generation.png" alt="models_mesh_generation" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
| 88 | [models_mesh_picking](models/models_mesh_picking.c) | <img src="models/models_mesh_picking.png" alt="models_mesh_picking" width="80"> | ⭐️⭐️⭐️☆ | 1.7 | **4.0** | [Joel Davis](https://github.com/joeld42) | | 91 | [models_mesh_picking](models/models_mesh_picking.c) | <img src="models/models_mesh_picking.png" alt="models_mesh_picking" width="80"> | ⭐️⭐️⭐️☆ | 1.7 | **4.0** | [Joel Davis](https://github.com/joeld42) |
| 89 | [models_loading](models/models_loading.c) | <img src="models/models_loading.png" alt="models_loading" width="80"> | ⭐️☆☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | | 92 | [models_loading](models/models_loading.c) | <img src="models/models_loading.png" alt="models_loading" width="80"> | ⭐️☆☆☆ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
| 90 | [models_loading_gltf](models/models_loading_gltf.c) | <img src="models/models_loading_gltf.png" alt="models_loading_gltf" width="80"> | ⭐️☆☆☆ | 3.7 | **4.2** | [Ray](https://github.com/raysan5) | | 93 | [models_loading_gltf](models/models_loading_gltf.c) | <img src="models/models_loading_gltf.png" alt="models_loading_gltf" width="80"> | ⭐️☆☆☆ | 3.7 | **4.2** | [Ray](https://github.com/raysan5) |
| 91 | [models_loading_vox](models/models_loading_vox.c) | <img src="models/models_loading_vox.png" alt="models_loading_vox" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Johann Nadalutti](https://github.com/procfxgen) | | 94 | [models_loading_vox](models/models_loading_vox.c) | <img src="models/models_loading_vox.png" alt="models_loading_vox" width="80"> | ⭐️☆☆☆ | **4.0** | **4.0** | [Johann Nadalutti](https://github.com/procfxgen) |
| 92 | [models_loading_m3d](models/models_loading_m3d.c) | <img src="models/models_loading_m3d.png" alt="models_loading_m3d" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [bzt](https://bztsrc.gitlab.io/model3d) | | 95 | [models_loading_m3d](models/models_loading_m3d.c) | <img src="models/models_loading_m3d.png" alt="models_loading_m3d" width="80"> | ⭐️☆☆☆ | **4.2** | **4.2** | [bzt](https://bztsrc.gitlab.io/model3d) |
| 93 | [models_orthographic_projection](models/models_orthographic_projection.c) | <img src="models/models_orthographic_projection.png" alt="models_orthographic_projection" width="80"> | ⭐️☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) | | 96 | [models_orthographic_projection](models/models_orthographic_projection.c) | <img src="models/models_orthographic_projection.png" alt="models_orthographic_projection" width="80"> | ⭐️☆☆☆ | 2.0 | 3.7 | [Max Danielsson](https://github.com/autious) |
| 94 | [models_point_rendering](models/models_point_rendering.c) | <img src="models/models_point_rendering.png" alt="models_point_rendering" width="80"> | ⭐️⭐️☆☆ | 5.0 | 5.0 | [Reese Gallagher](https://github.com/satchelfrost) | | 97 | [models_point_rendering](models/models_point_rendering.c) | <img src="models/models_point_rendering.png" alt="models_point_rendering" width="80"> | ⭐️⭐️☆☆ | 5.0 | 5.0 | [Reese Gallagher](https://github.com/satchelfrost) |
| 95 | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) | <img src="models/models_rlgl_solar_system.png" alt="models_rlgl_solar_system" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) | | 98 | [models_rlgl_solar_system](models/models_rlgl_solar_system.c) | <img src="models/models_rlgl_solar_system.png" alt="models_rlgl_solar_system" width="80"> | ⭐️⭐️⭐️⭐️ | 2.5 | **4.0** | [Ray](https://github.com/raysan5) |
| 96 | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) | <img src="models/models_yaw_pitch_roll.png" alt="models_yaw_pitch_roll" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Berni](https://github.com/Berni8k) | | 99 | [models_yaw_pitch_roll](models/models_yaw_pitch_roll.c) | <img src="models/models_yaw_pitch_roll.png" alt="models_yaw_pitch_roll" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Berni](https://github.com/Berni8k) |
| 97 | [models_waving_cubes](models/models_waving_cubes.c) | <img src="models/models_waving_cubes.png" alt="models_waving_cubes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [codecat](https://github.com/codecat) | | 100 | [models_waving_cubes](models/models_waving_cubes.c) | <img src="models/models_waving_cubes.png" alt="models_waving_cubes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [codecat](https://github.com/codecat) |
| 98 | [models_heightmap](models/models_heightmap.c) | <img src="models/models_heightmap.png" alt="models_heightmap" width="80"> | ⭐️☆☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) | | 101 | [models_heightmap](models/models_heightmap.c) | <img src="models/models_heightmap.png" alt="models_heightmap" width="80"> | ⭐️☆☆☆ | 1.8 | 3.5 | [Ray](https://github.com/raysan5) |
| 99 | [models_skybox](models/models_skybox.c) | <img src="models/models_skybox.png" alt="models_skybox" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) | | 102 | [models_skybox](models/models_skybox.c) | <img src="models/models_skybox.png" alt="models_skybox" width="80"> | ⭐️⭐️☆☆ | 1.8 | **4.0** | [Ray](https://github.com/raysan5) |
### category: shaders ### category: shaders
@ -160,25 +161,25 @@ Examples using raylib shaders functionality, including shaders loading, paramete
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
| 100 | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐️⭐️⭐️⭐️ | 3.0 | **4.2** | [Chris Camacho](https://github.com/codifies) | | 103 | [shaders_basic_lighting](shaders/shaders_basic_lighting.c) | <img src="shaders/shaders_basic_lighting.png" alt="shaders_basic_lighting" width="80"> | ⭐️⭐️⭐️⭐️ | 3.0 | **4.2** | [Chris Camacho](https://github.com/codifies) |
| 101 | [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐️⭐️☆☆ | 1.3 | 3.7 | [Ray](https://github.com/raysan5) | | 104 | [shaders_model_shader](shaders/shaders_model_shader.c) | <img src="shaders/shaders_model_shader.png" alt="shaders_model_shader" width="80"> | ⭐️⭐️☆☆ | 1.3 | 3.7 | [Ray](https://github.com/raysan5) |
| 102 | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) | | 105 | [shaders_shapes_textures](shaders/shaders_shapes_textures.c) | <img src="shaders/shaders_shapes_textures.png" alt="shaders_shapes_textures" width="80"> | ⭐️⭐️☆☆ | 1.7 | 3.7 | [Ray](https://github.com/raysan5) |
| 103 | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) | <img src="shaders/shaders_custom_uniform.png" alt="shaders_custom_uniform" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | 106 | [shaders_custom_uniform](shaders/shaders_custom_uniform.c) | <img src="shaders/shaders_custom_uniform.png" alt="shaders_custom_uniform" width="80"> | ⭐️⭐️☆☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
| 104 | [shaders_postprocessing](shaders/shaders_postprocessing.c) | <img src="shaders/shaders_postprocessing.png" alt="shaders_postprocessing" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) | | 107 | [shaders_postprocessing](shaders/shaders_postprocessing.c) | <img src="shaders/shaders_postprocessing.png" alt="shaders_postprocessing" width="80"> | ⭐️⭐️⭐️☆ | 1.3 | **4.0** | [Ray](https://github.com/raysan5) |
| 105 | [shaders_palette_switch](shaders/shaders_palette_switch.c) | <img src="shaders/shaders_palette_switch.png" alt="shaders_palette_switch" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) | | 108 | [shaders_palette_switch](shaders/shaders_palette_switch.c) | <img src="shaders/shaders_palette_switch.png" alt="shaders_palette_switch" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Marco Lizza](https://github.com/MarcoLizza) |
| 106 | [shaders_raymarching](shaders/shaders_raymarching.c) | <img src="shaders/shaders_raymarching.png" alt="shaders_raymarching" width="80"> | ⭐️⭐️⭐️⭐️ | 2.0 | **4.2** | [Ray](https://github.com/raysan5) | | 109 | [shaders_raymarching](shaders/shaders_raymarching.c) | <img src="shaders/shaders_raymarching.png" alt="shaders_raymarching" width="80"> | ⭐️⭐️⭐️⭐️ | 2.0 | **4.2** | [Ray](https://github.com/raysan5) |
| 107 | [shaders_texture_drawing](shaders/shaders_texture_drawing.c) | <img src="shaders/shaders_texture_drawing.png" alt="shaders_texture_drawing" width="80"> | ⭐️⭐️☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/) | | 110 | [shaders_texture_drawing](shaders/shaders_texture_drawing.c) | <img src="shaders/shaders_texture_drawing.png" alt="shaders_texture_drawing" width="80"> | ⭐️⭐️☆☆ | 2.0 | 3.7 | [Michał Ciesielski](https://github.com/) |
| 108 | [shaders_texture_outline](shaders/shaders_texture_outline.c) | <img src="shaders/shaders_texture_outline.png" alt="shaders_texture_outline" width="80"> | ⭐️⭐️⭐️☆ | **4.0** | **4.0** | [Samuel Skiff](https://github.com/GoldenThumbs) | | 111 | [shaders_texture_outline](shaders/shaders_texture_outline.c) | <img src="shaders/shaders_texture_outline.png" alt="shaders_texture_outline" width="80"> | ⭐️⭐️⭐️☆ | **4.0** | **4.0** | [Samuel Skiff](https://github.com/GoldenThumbs) |
| 109 | [shaders_texture_waves](shaders/shaders_texture_waves.c) | <img src="shaders/shaders_texture_waves.png" alt="shaders_texture_waves" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) | | 112 | [shaders_texture_waves](shaders/shaders_texture_waves.c) | <img src="shaders/shaders_texture_waves.png" alt="shaders_texture_waves" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Anata](https://github.com/anatagawa) |
| 110 | [shaders_julia_set](shaders/shaders_julia_set.c) | <img src="shaders/shaders_julia_set.png" alt="shaders_julia_set" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [eggmund](https://github.com/eggmund) | | 113 | [shaders_julia_set](shaders/shaders_julia_set.c) | <img src="shaders/shaders_julia_set.png" alt="shaders_julia_set" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [eggmund](https://github.com/eggmund) |
| 111 | [shaders_eratosthenes](shaders/shaders_eratosthenes.c) | <img src="shaders/shaders_eratosthenes.png" alt="shaders_eratosthenes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [ProfJski](https://github.com/ProfJski) | | 114 | [shaders_eratosthenes](shaders/shaders_eratosthenes.c) | <img src="shaders/shaders_eratosthenes.png" alt="shaders_eratosthenes" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | **4.0** | [ProfJski](https://github.com/ProfJski) |
| 112 | [shaders_fog](shaders/shaders_fog.c) | <img src="shaders/shaders_fog.png" alt="shaders_fog" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) | | 115 | [shaders_fog](shaders/shaders_fog.c) | <img src="shaders/shaders_fog.png" alt="shaders_fog" width="80"> | ⭐️⭐️⭐️☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
| 113 | [shaders_simple_mask](shaders/shaders_simple_mask.c) | <img src="shaders/shaders_simple_mask.png" alt="shaders_simple_mask" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) | | 116 | [shaders_simple_mask](shaders/shaders_simple_mask.c) | <img src="shaders/shaders_simple_mask.png" alt="shaders_simple_mask" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
| 114 | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.5 | [Ray](https://github.com/raysan5) | | 117 | [shaders_hot_reloading](shaders/shaders_hot_reloading.c) | <img src="shaders/shaders_hot_reloading.png" alt="shaders_hot_reloading" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.5 | [Ray](https://github.com/raysan5) |
| 115 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.2** | [seanpringle](https://github.com/seanpringle) | | 118 | [shaders_mesh_instancing](shaders/shaders_mesh_instancing.c) | <img src="shaders/shaders_mesh_instancing.png" alt="shaders_mesh_instancing" width="80"> | ⭐️⭐️⭐️⭐️ | 3.7 | **4.2** | [seanpringle](https://github.com/seanpringle) |
| 116 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) | | 119 | [shaders_multi_sample2d](shaders/shaders_multi_sample2d.c) | <img src="shaders/shaders_multi_sample2d.png" alt="shaders_multi_sample2d" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Ray](https://github.com/raysan5) |
| 117 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) | | 120 | [shaders_spotlight](shaders/shaders_spotlight.c) | <img src="shaders/shaders_spotlight.png" alt="shaders_spotlight" width="80"> | ⭐️⭐️☆☆ | 2.5 | 3.7 | [Chris Camacho](https://github.com/codifies) |
| 118 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) | | 121 | [shaders_deferred_render](shaders/shaders_deferred_render.c) | <img src="shaders/shaders_deferred_render.png" alt="shaders_deferred_render" width="80"> | ⭐️⭐️⭐️⭐️ | 4.5 | 4.5 | [Justin Andreas Lacoste](https://github.com/27justin) |
### category: audio ### category: audio
@ -186,10 +187,10 @@ Examples using raylib audio functionality, including sound/music loading and pla
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
| 119 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) | | 122 | [audio_module_playing](audio/audio_module_playing.c) | <img src="audio/audio_module_playing.png" alt="audio_module_playing" width="80"> | ⭐️☆☆☆ | 1.5 | 3.5 | [Ray](https://github.com/raysan5) |
| 120 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) | | 123 | [audio_music_stream](audio/audio_music_stream.c) | <img src="audio/audio_music_stream.png" alt="audio_music_stream" width="80"> | ⭐️☆☆☆ | 1.3 | **4.2** | [Ray](https://github.com/raysan5) |
| 121 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) | | 124 | [audio_raw_stream](audio/audio_raw_stream.c) | <img src="audio/audio_raw_stream.png" alt="audio_raw_stream" width="80"> | ⭐️⭐️⭐️☆ | 1.6 | **4.2** | [Ray](https://github.com/raysan5) |
| 122 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) | | 125 | [audio_sound_loading](audio/audio_sound_loading.c) | <img src="audio/audio_sound_loading.png" alt="audio_sound_loading" width="80"> | ⭐️☆☆☆ | 1.1 | 3.5 | [Ray](https://github.com/raysan5) |
### category: others ### category: others
@ -197,11 +198,11 @@ Examples showing raylib misc functionality that does not fit in other categories
| ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer | | ## | example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------| |----|----------|--------|:-------------------:|:------------------:|:------------------:|:----------|
| 123 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) | | 126 | [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐️⭐️⭐️⭐️ | 1.6 | **4.0** | [Ray](https://github.com/raysan5) |
| 124 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) | | 127 | [rlgl_compute_shader](others/rlgl_compute_shader.c) | <img src="others/rlgl_compute_shader.png" alt="rlgl_compute_shader" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Teddy Astie](https://github.com/tsnake41) |
| 125 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) | | 128 | [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐️⭐️⭐️☆ | 3.0 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
| 126 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) | | 129 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
| 127 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) | | 130 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with! As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!

View File

@ -0,0 +1,123 @@
/*******************************************************************************************
*
* raylib [core] example - input virtual controls
*
* Example originally created with raylib 5.0, last time updated with raylib 5.0
*
* Example create by GreenSnakeLinux (@GreenSnakeLinux),
* lighter by oblerion (@oblerion) and
* reviewed by Ramon Santamaria (@raysan5)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2024 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <math.h>
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls");
const int dpadX = 90;
const int dpadY = 300;
const int dpadRad = 25;//radius of each pad
Color dpadColor = BLUE;
int dpadKeydown = -1;//-1 if not down, else 0,1,2,3
const float dpadCollider[4][2]= // collider array with x,y position
{
{dpadX,dpadY-dpadRad*1.5},//up
{dpadX-dpadRad*1.5,dpadY},//left
{dpadX+dpadRad*1.5,dpadY},//right
{dpadX,dpadY+dpadRad*1.5}//down
};
const char dpadLabel[4]="XYBA";//label of Dpad
float playerX=100;
float playerY=100;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//--------------------------------------------------------------------------
dpadKeydown = -1; //reset
float inputX=0;
float inputY=0;
if(GetTouchPointCount()>0)
{//use touch pos
inputX = GetTouchX();
inputY = GetTouchY();
}
else
{//use mouse pos
inputX = GetMouseX();
inputY = GetMouseY();
}
for(int i=0;i<4;i++)
{
//test distance each collider and input < radius
if( fabsf(dpadCollider[i][1]-inputY) + fabsf(dpadCollider[i][0]-inputX) < dpadRad)
{
dpadKeydown = i;
break;
}
}
// move player
switch(dpadKeydown){
case 0: playerY -= 50*GetFrameTime();
break;
case 1: playerX -= 50*GetFrameTime();
break;
case 2: playerX += 50*GetFrameTime();
break;
case 3: playerY += 50*GetFrameTime();
default:;
};
//--------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
for(int i=0;i<4;i++)
{
//draw all pad
DrawCircle(dpadCollider[i][0],dpadCollider[i][1],dpadRad,dpadColor);
if(i!=dpadKeydown)
{
//draw label
DrawText(TextSubtext(dpadLabel,i,1),
dpadCollider[i][0]-5,
dpadCollider[i][1]-5,16,BLACK);
}
}
DrawText("Player",playerX,playerY,16,BLACK);
EndDrawing();
//--------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -47,7 +47,7 @@ int main(void)
UnloadImage(cat); // Unload image from RAM UnloadImage(cat); // Unload image from RAM
// Load custom font for frawing on image // Load custom font for drawing on image
Font font = LoadFont("resources/custom_jupiter_crash.png"); Font font = LoadFont("resources/custom_jupiter_crash.png");
// Draw over image using custom font // Draw over image using custom font
@ -93,4 +93,4 @@ int main(void)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -1,72 +0,0 @@
/*******************************************************************************************
*
* raylib [textures] example - SVG loading and texture creation
*
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
*
* Example originally created with raylib 4.2, last time updated with raylib 4.2
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2022 Dennis Meinen (@bixxy#4258 on Discord)
*
********************************************************************************************/
#include "raylib.h"
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [textures] example - svg loading");
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
Image image = LoadImageSvg("resources/test.svg", 400, 350); // Loaded in CPU memory (RAM)
Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE);
//Red border to illustrate how the SVG is centered within the specified dimensions
DrawRectangleLines((screenWidth / 2 - texture.width / 2) - 1, (screenHeight / 2 - texture.height / 2) - 1, texture.width + 2, texture.height + 2, RED);
DrawText("this IS a texture loaded from an SVG file!", 300, 410, 10, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Texture unloading
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -6815,25 +6815,6 @@
} }
] ]
}, },
{
"name": "LoadImageSvg",
"description": "Load image from SVG file data or string with specified size",
"returnType": "Image",
"params": [
{
"type": "const char *",
"name": "fileNameOrString"
},
{
"type": "int",
"name": "width"
},
{
"type": "int",
"name": "height"
}
]
},
{ {
"name": "LoadImageAnim", "name": "LoadImageAnim",
"description": "Load image sequence from file (frames appended to image.data)", "description": "Load image sequence from file (frames appended to image.data)",

View File

@ -5339,16 +5339,6 @@ return {
{type = "int", name = "headerSize"} {type = "int", name = "headerSize"}
} }
}, },
{
name = "LoadImageSvg",
description = "Load image from SVG file data or string with specified size",
returnType = "Image",
params = {
{type = "const char *", name = "fileNameOrString"},
{type = "int", name = "width"},
{type = "int", name = "height"}
}
},
{ {
name = "LoadImageAnim", name = "LoadImageAnim",
description = "Load image sequence from file (frames appended to image.data)", description = "Load image sequence from file (frames appended to image.data)",

File diff suppressed because it is too large Load Diff

View File

@ -675,7 +675,7 @@
<Param type="unsigned int" name="frames" desc="" /> <Param type="unsigned int" name="frames" desc="" />
</Callback> </Callback>
</Callbacks> </Callbacks>
<Functions count="578"> <Functions count="577">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context"> <Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" /> <Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" /> <Param type="int" name="height" desc="" />
@ -1699,11 +1699,6 @@
<Param type="int" name="format" desc="" /> <Param type="int" name="format" desc="" />
<Param type="int" name="headerSize" desc="" /> <Param type="int" name="headerSize" desc="" />
</Function> </Function>
<Function name="LoadImageSvg" retType="Image" paramCount="3" desc="Load image from SVG file data or string with specified size">
<Param type="const char *" name="fileNameOrString" desc="" />
<Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" />
</Function>
<Function name="LoadImageAnim" retType="Image" paramCount="2" desc="Load image sequence from file (frames appended to image.data)"> <Function name="LoadImageAnim" retType="Image" paramCount="2" desc="Load image sequence from file (frames appended to image.data)">
<Param type="const char *" name="fileName" desc="" /> <Param type="const char *" name="fileName" desc="" />
<Param type="int *" name="frames" desc="" /> <Param type="int *" name="frames" desc="" />

View File

@ -293,8 +293,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_outline", "
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_tiling", "examples\shaders_texture_tiling.vcxproj", "{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_texture_tiling", "examples\shaders_texture_tiling.vcxproj", "{EFA150D4-F93B-4D7D-A69C-9E8B4663BECD}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "textures_svg_loading", "examples\textures_svg_loading.vcxproj", "{D8026C60-CCBC-45DF-9085-BF21569EB414}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_splines_drawing", "examples\shapes_splines_drawing.vcxproj", "{DF25E545-00FF-4E64-844C-7DF98991F901}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_splines_drawing", "examples\shapes_splines_drawing.vcxproj", "{DF25E545-00FF-4E64-844C-7DF98991F901}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_top_down_lights", "examples\shapes_top_down_lights.vcxproj", "{703BE7BA-5B99-4F70-806D-3A259F6A991E}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shapes_top_down_lights", "examples\shapes_top_down_lights.vcxproj", "{703BE7BA-5B99-4F70-806D-3A259F6A991E}"

View File

@ -109,8 +109,9 @@ RAYLIB_MODULE_RAYGUI_PATH ?= $(RAYLIB_SRC_PATH)/../../raygui/src
# Use external GLFW library instead of rglfw module # Use external GLFW library instead of rglfw module
USE_EXTERNAL_GLFW ?= FALSE USE_EXTERNAL_GLFW ?= FALSE
# Enable support for both Wayland and X11 by default on Linux when using GLFW # Enable support for X11 by default on Linux when using GLFW
GLFW_LINUX_ENABLE_WAYLAND ?= TRUE # NOTE: Wayland is disabled by default, only enable if you are sure
GLFW_LINUX_ENABLE_WAYLAND ?= FALSE
GLFW_LINUX_ENABLE_X11 ?= TRUE GLFW_LINUX_ENABLE_X11 ?= TRUE
# PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally # PLATFORM_DESKTOP_SDL: It requires SDL library to be provided externally

View File

@ -1,8 +1,14 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
/// Minimum supported version of Zig
const min_ver = "0.12.0";
comptime { comptime {
if (builtin.zig_version.minor < 12) @compileError("Raylib requires zig version 0.12.0"); const order = std.SemanticVersion.order;
const parse = std.SemanticVersion.parse;
if (order(builtin.zig_version, parse(min_ver) catch unreachable) == .lt)
@compileError("Raylib requires zig version " ++ min_ver);
} }
// NOTE(freakmangd): I don't like using a global here, but it prevents having to // NOTE(freakmangd): I don't like using a global here, but it prevents having to
@ -24,7 +30,7 @@ pub fn addRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
.rshapes = options.rshapes, .rshapes = options.rshapes,
.rtext = options.rtext, .rtext = options.rtext,
.rtextures = options.rtextures, .rtextures = options.rtextures,
.platform_drm = options.platform_drm, .platform = options.platform,
.shared = options.shared, .shared = options.shared,
.linux_display_backend = options.linux_display_backend, .linux_display_backend = options.linux_display_backend,
.opengl_version = options.opengl_version, .opengl_version = options.opengl_version,
@ -40,6 +46,32 @@ pub fn addRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
return raylib; return raylib;
} }
fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend) void {
raylib.defineCMacro("PLATFORM_DESKTOP", null);
switch (platform) {
.glfw => raylib.defineCMacro("PLATFORM_DESKTOP_GLFW", null),
.rgfw => raylib.defineCMacro("PLATFORM_DESKTOP_RGFW", null),
.sdl => raylib.defineCMacro("PLATFORM_DESKTOP_SDL", null),
else => {},
}
}
/// TODO: Once the minimum supported version is bumped to 0.14.0, it can be simplified again:
/// https://github.com/raysan5/raylib/pull/4375#issuecomment-2408998315
/// https://github.com/raysan5/raylib/blob/9b9c72eb0dc705cde194b053a366a40396acfb67/src/build.zig#L54-L56
fn srcDir(b: *std.Build) []const u8 {
comptime {
const order = std.SemanticVersion.order;
const parse = std.SemanticVersion.parse;
if (order(parse(min_ver) catch unreachable, parse("0.14.0") catch unreachable) != .lt)
@compileError("Please take a look at this function again");
}
const src_file = std.fs.path.relative(b.allocator, @src().file, ".") catch @panic("OOM");
return std.fs.path.dirname(src_file) orelse ".";
}
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile { fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
raylib_flags_arr.clearRetainingCapacity(); raylib_flags_arr.clearRetainingCapacity();
@ -53,9 +85,8 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
"-DGL_SILENCE_DEPRECATION=199309L", "-DGL_SILENCE_DEPRECATION=199309L",
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674 "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
}); });
if (options.config) |config| { if (options.config.len > 0) {
const file = try std.fs.path.join(b.allocator, &.{ std.fs.path.dirname(@src().file) orelse ".", "config.h" }); const file = b.pathJoin(&.{ srcDir(b), "config.h" });
defer b.allocator.free(file);
const content = try std.fs.cwd().readFileAlloc(b.allocator, file, std.math.maxInt(usize)); const content = try std.fs.cwd().readFileAlloc(b.allocator, file, std.math.maxInt(usize));
defer b.allocator.free(content); defer b.allocator.free(content);
@ -63,22 +94,23 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
while (lines.next()) |line| { while (lines.next()) |line| {
if (!std.mem.containsAtLeast(u8, line, 1, "SUPPORT")) continue; if (!std.mem.containsAtLeast(u8, line, 1, "SUPPORT")) continue;
if (std.mem.startsWith(u8, line, "//")) continue; if (std.mem.startsWith(u8, line, "//")) continue;
if (std.mem.startsWith(u8, line, "#if")) continue;
var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace
flag = flag["#define ".len - 1 ..]; // Remove #define flag = flag["#define ".len - 1 ..]; // Remove #define
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace
flag = flag[0..std.mem.indexOf(u8, flag, " ").?]; // Flag is only one word, so capture till space flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
flag = try std.fmt.allocPrint(b.allocator, "-D{s}", .{flag}); // Prepend with -D flag = try std.fmt.allocPrint(b.allocator, "-D{s}", .{flag}); // Prepend with -D
// If user specifies the flag skip it // If user specifies the flag skip it
if (std.mem.containsAtLeast(u8, config, 1, flag)) continue; if (std.mem.containsAtLeast(u8, options.config, 1, flag)) continue;
// Append default value from config.h to compile flags // Append default value from config.h to compile flags
try raylib_flags_arr.append(b.allocator, flag); try raylib_flags_arr.append(b.allocator, flag);
} }
// Append config flags supplied by user to compile flags // Append config flags supplied by user to compile flags
try raylib_flags_arr.append(b.allocator, config); try raylib_flags_arr.append(b.allocator, options.config);
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS"); try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
} }
@ -102,8 +134,8 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.linkLibC(); raylib.linkLibC();
// No GLFW required on PLATFORM_DRM // No GLFW required on PLATFORM_DRM
if (!options.platform_drm) { if (options.platform != .drm) {
raylib.addIncludePath(b.path("src/external/glfw/include")); raylib.addIncludePath(b.path(b.pathJoin(&.{ srcDir(b), "external/glfw/include" })));
} }
var c_source_files = try std.ArrayList([]const u8).initCapacity(b.allocator, 2); var c_source_files = try std.ArrayList([]const u8).initCapacity(b.allocator, 2);
@ -136,10 +168,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.linkSystemLibrary("gdi32"); raylib.linkSystemLibrary("gdi32");
raylib.linkSystemLibrary("opengl32"); raylib.linkSystemLibrary("opengl32");
raylib.defineCMacro("PLATFORM_DESKTOP", null); setDesktopPlatform(raylib, options.platform);
}, },
.linux => { .linux => {
if (!options.platform_drm) { if (options.platform != .drm) {
try c_source_files.append("rglfw.c"); try c_source_files.append("rglfw.c");
raylib.linkSystemLibrary("GL"); raylib.linkSystemLibrary("GL");
raylib.linkSystemLibrary("rt"); raylib.linkSystemLibrary("rt");
@ -156,17 +188,16 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) { if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
_ = b.findProgram(&.{"wayland-scanner"}, &.{}) catch { _ = b.findProgram(&.{"wayland-scanner"}, &.{}) catch {
std.log.err( std.log.err(
\\ Wayland may not be installed on the system. \\ `wayland-scanner` may not be installed on the system.
\\ You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend` \\ You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend`
, .{}); , .{});
@panic("No Wayland"); @panic("`wayland-scanner` not found");
}; };
raylib.defineCMacro("_GLFW_WAYLAND", null); raylib.defineCMacro("_GLFW_WAYLAND", null);
raylib.linkSystemLibrary("wayland-client"); raylib.linkSystemLibrary("wayland-client");
raylib.linkSystemLibrary("wayland-cursor"); raylib.linkSystemLibrary("wayland-cursor");
raylib.linkSystemLibrary("wayland-egl"); raylib.linkSystemLibrary("wayland-egl");
raylib.linkSystemLibrary("xkbcommon"); raylib.linkSystemLibrary("xkbcommon");
raylib.addIncludePath(b.path("src"));
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol"); waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol"); waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol"); waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
@ -177,7 +208,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol"); waylandGenerate(b, raylib, "xdg-activation-v1.xml", "xdg-activation-v1-client-protocol");
waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol"); waylandGenerate(b, raylib, "idle-inhibit-unstable-v1.xml", "idle-inhibit-unstable-v1-client-protocol");
} }
raylib.defineCMacro("PLATFORM_DESKTOP", null); setDesktopPlatform(raylib, options.platform);
} else { } else {
if (options.opengl_version == .auto) { if (options.opengl_version == .auto) {
raylib.linkSystemLibrary("GLESv2"); raylib.linkSystemLibrary("GLESv2");
@ -211,13 +242,13 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.linkSystemLibrary("Xxf86vm"); raylib.linkSystemLibrary("Xxf86vm");
raylib.linkSystemLibrary("Xcursor"); raylib.linkSystemLibrary("Xcursor");
raylib.defineCMacro("PLATFORM_DESKTOP", null); setDesktopPlatform(raylib, options.platform);
}, },
.macos => { .macos => {
// On macos rglfw.c include Objective-C files. // On macos rglfw.c include Objective-C files.
try raylib_flags_arr.append(b.allocator, "-ObjC"); try raylib_flags_arr.append(b.allocator, "-ObjC");
raylib.root_module.addCSourceFile(.{ raylib.root_module.addCSourceFile(.{
.file = b.path("src/rglfw.c"), .file = b.path(b.pathJoin(&.{ srcDir(b), "rglfw.c" })),
.flags = raylib_flags_arr.items, .flags = raylib_flags_arr.items,
}); });
_ = raylib_flags_arr.pop(); _ = raylib_flags_arr.pop();
@ -227,7 +258,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.linkFramework("AppKit"); raylib.linkFramework("AppKit");
raylib.linkFramework("IOKit"); raylib.linkFramework("IOKit");
raylib.defineCMacro("PLATFORM_DESKTOP", null); setDesktopPlatform(raylib, options.platform);
}, },
.emscripten => { .emscripten => {
raylib.defineCMacro("PLATFORM_WEB", null); raylib.defineCMacro("PLATFORM_WEB", null);
@ -239,8 +270,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
@panic("Pass '--sysroot \"$EMSDK/upstream/emscripten\"'"); @panic("Pass '--sysroot \"$EMSDK/upstream/emscripten\"'");
} }
const cache_include = std.fs.path.join(b.allocator, &.{ b.sysroot.?, "cache", "sysroot", "include" }) catch @panic("Out of memory"); const cache_include = b.pathJoin(&.{ b.sysroot.?, "cache", "sysroot", "include" });
defer b.allocator.free(cache_include);
var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!"); var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!");
dir.close(); dir.close();
@ -251,9 +281,8 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
}, },
} }
raylib.addIncludePath(b.path("src"));
raylib.root_module.addCSourceFiles(.{ raylib.root_module.addCSourceFiles(.{
.root = b.path("src"), .root = b.path(srcDir(b)),
.files = c_source_files.items, .files = c_source_files.items,
.flags = raylib_flags_arr.items, .flags = raylib_flags_arr.items,
}); });
@ -286,11 +315,12 @@ pub const Options = struct {
rtext: bool = true, rtext: bool = true,
rtextures: bool = true, rtextures: bool = true,
raygui: bool = false, raygui: bool = false,
platform_drm: bool = false, platform: PlatformBackend = .glfw,
shared: bool = false, shared: bool = false,
linux_display_backend: LinuxDisplayBackend = .Both, linux_display_backend: LinuxDisplayBackend = .Both,
opengl_version: OpenglVersion = .auto, opengl_version: OpenglVersion = .auto,
config: ?[]const u8 = null, /// config should be a list of cflags, eg, "-DSUPPORT_CUSTOM_FRAME_CONTROL"
config: []const u8 = &.{},
raygui_dependency_name: []const u8 = "raygui", raygui_dependency_name: []const u8 = "raygui",
}; };
@ -323,6 +353,13 @@ pub const LinuxDisplayBackend = enum {
Both, Both,
}; };
pub const PlatformBackend = enum {
glfw,
rgfw,
sdl,
drm,
};
pub fn build(b: *std.Build) !void { pub fn build(b: *std.Build) !void {
// Standard target options allows the person running `zig build` to choose // Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which // what target to build for. Here we do not override the defaults, which
@ -336,8 +373,9 @@ pub fn build(b: *std.Build) !void {
const defaults = Options{}; const defaults = Options{};
const options = Options{ const options = Options{
.platform_drm = b.option(bool, "platform_drm", "Compile raylib in native mode (no X11)") orelse defaults.platform_drm, .platform = b.option(PlatformBackend, "platform", "Choose the platform backedn for desktop target") orelse defaults.platform,
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio, .raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
.raygui = b.option(bool, "raygui", "Compile with raygui support") orelse defaults.raygui,
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels, .rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext, .rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
.rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures, .rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures,
@ -345,22 +383,26 @@ pub fn build(b: *std.Build) !void {
.shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared, .shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared,
.linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend, .linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend,
.opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version, .opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version,
.config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse null, .config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{},
}; };
const lib = try compileRaylib(b, target, optimize, options); const lib = try compileRaylib(b, target, optimize, options);
lib.installHeader(b.path("src/raylib.h"), "raylib.h"); lib.installHeader(b.path(b.pathJoin(&.{ srcDir(b), "raylib.h" })), "raylib.h");
lib.installHeader(b.path("src/raymath.h"), "raymath.h"); lib.installHeader(b.path(b.pathJoin(&.{ srcDir(b), "raymath.h" })), "raymath.h");
lib.installHeader(b.path("src/rlgl.h"), "rlgl.h"); lib.installHeader(b.path(b.pathJoin(&.{ srcDir(b), "rlgl.h" })), "rlgl.h");
b.installArtifact(lib); b.installArtifact(lib);
} }
const waylandDir = "src/external/glfw/deps/wayland"; fn waylandGenerate(
b: *std.Build,
fn waylandGenerate(b: *std.Build, raylib: *std.Build.Step.Compile, comptime protocol: []const u8, comptime basename: []const u8) void { raylib: *std.Build.Step.Compile,
const protocolDir = waylandDir ++ "/" ++ protocol; comptime protocol: []const u8,
comptime basename: []const u8,
) void {
const waylandDir = b.pathJoin(&.{ srcDir(b), "external/glfw/deps/wayland" });
const protocolDir = b.pathJoin(&.{ waylandDir, protocol });
const clientHeader = basename ++ ".h"; const clientHeader = basename ++ ".h";
const privateCode = basename ++ "-code.h"; const privateCode = basename ++ "-code.h";

View File

@ -121,12 +121,10 @@
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
// The mac OpenGL drivers do not support more than 8 VBOs, so we can't support GPU animations
#ifndef __APPLE__
#define RL_SUPPORT_MESH_ANIMATION_VBO
#endif
#ifdef RL_SUPPORT_MESH_ANIMATION_VBO #define RL_SUPPORT_MESH_GPU_SKINNING // Remove this if your GPU does not support more than 8 VBOs
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
#endif #endif
@ -182,7 +180,6 @@
//#define SUPPORT_FILEFORMAT_ASTC 1 //#define SUPPORT_FILEFORMAT_ASTC 1
//#define SUPPORT_FILEFORMAT_PKM 1 //#define SUPPORT_FILEFORMAT_PKM 1
//#define SUPPORT_FILEFORMAT_PVR 1 //#define SUPPORT_FILEFORMAT_PVR 1
//#define SUPPORT_FILEFORMAT_SVG 1
// Support image export functionality (.png, .bmp, .tga, .jpg, .qoi) // Support image export functionality (.png, .bmp, .tga, .jpg, .qoi)
#define SUPPORT_IMAGE_EXPORT 1 #define SUPPORT_IMAGE_EXPORT 1
@ -237,7 +234,12 @@
// rmodels: Configuration values // rmodels: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported #define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
#define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh #define MAX_MESH_VERTEX_BUFFERS 9 // Maximum vertex buffers (VBO) per mesh
#else
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
#endif
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: raudio - Configuration Flags // Module: raudio - Configuration Flags

271
src/external/RGFW.h vendored
View File

@ -192,7 +192,7 @@
typedef u32 b32; typedef u32 b32;
#endif #endif
#define RGFW_TRUE 1 #define RGFW_TRUE (!(0))
#define RGFW_FALSE 0 #define RGFW_FALSE 0
/* thse OS macros looks better & are standardized */ /* thse OS macros looks better & are standardized */
@ -276,11 +276,6 @@
#endif #endif
#ifdef RGFW_EGL #ifdef RGFW_EGL
#if defined(__APPLE__)
#warning EGL is not supported for Cocoa, switching back to the native opengl api
#undef RGFW_EGL
#endif
#include <EGL/egl.h> #include <EGL/egl.h>
#elif defined(RGFW_OSMESA) #elif defined(RGFW_OSMESA)
#ifndef __APPLE__ #ifndef __APPLE__
@ -611,10 +606,17 @@ typedef struct RGFW_window {
/** * @defgroup Window_management /** * @defgroup Window_management
* @{ */ * @{ */
/*!
* the class name for X11 and WinAPI. apps with the same class will be grouped by the WM
* by default the class name will == the root window's name
*/
RGFWDEF void RGFW_setClassName(char* name);
/*! this has to be set before createWindow is called, else the fulscreen size is used */ /*! this has to be set before createWindow is called, else the fulscreen size is used */
RGFWDEF void RGFW_setBufferSize(RGFW_area size); /*!< the buffer cannot be resized (by RGFW) */ RGFWDEF void RGFW_setBufferSize(RGFW_area size); /*!< the buffer cannot be resized (by RGFW) */
RGFW_window* RGFW_createWindow( RGFWDEF RGFW_window* RGFW_createWindow(
const char* name, /* name of the window */ const char* name, /* name of the window */
RGFW_rect rect, /* rect of window */ RGFW_rect rect, /* rect of window */
u16 args /* extra arguments (NULL / (u16)0 means no args used)*/ u16 args /* extra arguments (NULL / (u16)0 means no args used)*/
@ -635,7 +637,7 @@ RGFWDEF RGFW_area RGFW_getScreenSize(void);
although you still need some way to tell RGFW to process events eg. `RGFW_window_checkEvents` although you still need some way to tell RGFW to process events eg. `RGFW_window_checkEvents`
*/ */
RGFW_Event* RGFW_window_checkEvent(RGFW_window* win); /*!< check current event (returns a pointer to win->event or NULL if there is no event)*/ RGFWDEF RGFW_Event* RGFW_window_checkEvent(RGFW_window* win); /*!< check current event (returns a pointer to win->event or NULL if there is no event)*/
/*! /*!
for RGFW_window_eventWait and RGFW_window_checkEvents for RGFW_window_eventWait and RGFW_window_checkEvents
@ -706,7 +708,7 @@ RGFWDEF void RGFW_window_setName(RGFW_window* win,
char* name char* name
); );
void RGFW_window_setIcon(RGFW_window* win, /*!< source window */ RGFWDEF void RGFW_window_setIcon(RGFW_window* win, /*!< source window */
u8* icon /*!< icon bitmap */, u8* icon /*!< icon bitmap */,
RGFW_area a /*!< width and height of the bitmap*/, RGFW_area a /*!< width and height of the bitmap*/,
i32 channels /*!< how many channels the bitmap has (rgb : 3, rgba : 4) */ i32 channels /*!< how many channels the bitmap has (rgb : 3, rgba : 4) */
@ -1609,9 +1611,6 @@ RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) {
if (args & RGFW_FULLSCREEN) if (args & RGFW_FULLSCREEN)
rect = RGFW_RECT(0, 0, screenR.w, screenR.h); rect = RGFW_RECT(0, 0, screenR.w, screenR.h);
if (args & RGFW_CENTER)
rect = RGFW_RECT((screenR.w - rect.w) / 2, (screenR.h - rect.h) / 2, rect.w, rect.h);
/* set and init the new window's data */ /* set and init the new window's data */
win->r = rect; win->r = rect;
win->event.inFocus = 1; win->event.inFocus = 1;
@ -1627,7 +1626,7 @@ RGFW_window* RGFW_window_basic_init(RGFW_rect rect, u16 args) {
void RGFW_window_scaleToMonitor(RGFW_window* win) { void RGFW_window_scaleToMonitor(RGFW_window* win) {
RGFW_monitor monitor = RGFW_window_getMonitor(win); RGFW_monitor monitor = RGFW_window_getMonitor(win);
RGFW_window_resize(win, RGFW_AREA(((u32) monitor.scaleX) * win->r.w, ((u32) monitor.scaleX) * win->r.h)); RGFW_window_resize(win, RGFW_AREA((u32)(monitor.scaleX * (float)win->r.w), (u32)(monitor.scaleX * (float)win->r.h)));
} }
#endif #endif
@ -1637,6 +1636,16 @@ RGFW_window* RGFW_root = NULL;
#define RGFW_HOLD_MOUSE (1L<<2) /*!< hold the moues still */ #define RGFW_HOLD_MOUSE (1L<<2) /*!< hold the moues still */
#define RGFW_MOUSE_LEFT (1L<<3) /* if mouse left the window */ #define RGFW_MOUSE_LEFT (1L<<3) /* if mouse left the window */
#ifdef RGFW_MACOS
RGFWDEF void RGFW_window_cocoaSetLayer(RGFW_window* win, void* layer);
RGFWDEF void* RGFW_cocoaGetLayer(void);
#endif
char* RGFW_className = NULL;
void RGFW_setClassName(char* name) {
RGFW_className = name;
}
void RGFW_clipboardFree(char* str) { RGFW_FREE(str); } void RGFW_clipboardFree(char* str) { RGFW_FREE(str); }
RGFW_keyState RGFW_mouseButtons[5] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} }; RGFW_keyState RGFW_mouseButtons[5] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} };
@ -2073,6 +2082,8 @@ void RGFW_updateLockState(RGFW_window* win, b8 capital, b8 numlock) {
#ifdef RGFW_WINDOWS #ifdef RGFW_WINDOWS
win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.hdc); win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.hdc);
#elif defined(RGFW_MACOS)
win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType)0);
#else #else
win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.display); win->src.EGL_display = eglGetDisplay((EGLNativeDisplayType) win->src.display);
#endif #endif
@ -2104,8 +2115,15 @@ void RGFW_updateLockState(RGFW_window* win, b8 capital, b8 numlock) {
EGLint numConfigs; EGLint numConfigs;
eglChooseConfig(win->src.EGL_display, egl_config, &config, 1, &numConfigs); eglChooseConfig(win->src.EGL_display, egl_config, &config, 1, &numConfigs);
#if defined(RGFW_MACOS)
win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL); void* layer = RGFW_cocoaGetLayer();
RGFW_window_cocoaSetLayer(win, layer);
win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) layer, NULL);
#else
win->src.EGL_surface = eglCreateWindowSurface(win->src.EGL_display, config, (EGLNativeWindowType) win->src.window, NULL);
#endif
EGLint attribs[] = { EGLint attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION,
@ -2322,7 +2340,7 @@ Start of Linux / Unix defines
u8 RGFW_mouseIconSrc[] = { XC_arrow, XC_left_ptr, XC_xterm, XC_crosshair, XC_hand2, XC_sb_h_double_arrow, XC_sb_v_double_arrow, XC_bottom_left_corner, XC_bottom_right_corner, XC_fleur, XC_X_cursor}; u8 RGFW_mouseIconSrc[] = { XC_arrow, XC_left_ptr, XC_xterm, XC_crosshair, XC_hand2, XC_sb_h_double_arrow, XC_sb_v_double_arrow, XC_bottom_left_corner, XC_bottom_right_corner, XC_fleur, XC_X_cursor};
/*atoms needed for drag and drop*/ /*atoms needed for drag and drop*/
Atom XdndAware, XdndTypeList, XdndSelection, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished, XdndActionCopy, XdndActionMove, XdndActionLink, XdndActionAsk, XdndActionPrivate; Atom XdndAware, XdndTypeList, XdndSelection, XdndEnter, XdndPosition, XdndStatus, XdndLeave, XdndDrop, XdndFinished, XdndActionCopy, XtextPlain, XtextUriList;
Atom wm_delete_window = 0; Atom wm_delete_window = 0;
@ -2563,9 +2581,13 @@ Start of Linux / Unix defines
// In your .desktop app, if you set the property // In your .desktop app, if you set the property
// StartupWMClass=RGFW that will assoicate the launcher icon // StartupWMClass=RGFW that will assoicate the launcher icon
// with your application - robrohan // with your application - robrohan
if (RGFW_className == NULL)
RGFW_className = (char*)name;
XClassHint *hint = XAllocClassHint(); XClassHint *hint = XAllocClassHint();
assert(hint != NULL); assert(hint != NULL);
hint->res_class = (char*)"RGFW"; hint->res_class = (char*)RGFW_className;
hint->res_name = (char*)name; // just use the window name as the app name hint->res_name = (char*)name; // just use the window name as the app name
XSetClassHint((Display*) win->src.display, win->src.window, hint); XSetClassHint((Display*) win->src.display, win->src.window, hint);
XFree(hint); XFree(hint);
@ -2609,6 +2631,11 @@ Start of Linux / Unix defines
RGFW_window_scaleToMonitor(win); RGFW_window_scaleToMonitor(win);
#endif #endif
if (args & RGFW_CENTER) {
RGFW_area screenR = RGFW_getScreenSize();
RGFW_window_move(win, RGFW_POINT((screenR.w - win->r.w) / 2, (screenR.h - win->r.h) / 2));
}
if (args & RGFW_NO_RESIZE) { /* make it so the user can't resize the window*/ if (args & RGFW_NO_RESIZE) { /* make it so the user can't resize the window*/
XSizeHints* sh = XAllocSizeHints(); XSizeHints* sh = XAllocSizeHints();
sh->flags = (1L << 4) | (1L << 5); sh->flags = (1L << 4) | (1L << 5);
@ -2646,7 +2673,6 @@ Start of Linux / Unix defines
if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */ if (args & RGFW_ALLOW_DND) { /* init drag and drop atoms and turn on drag and drop for this window */
win->_winArgs |= RGFW_ALLOW_DND; win->_winArgs |= RGFW_ALLOW_DND;
XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False);
XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False); XdndTypeList = XInternAtom((Display*) win->src.display, "XdndTypeList", False);
XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False); XdndSelection = XInternAtom((Display*) win->src.display, "XdndSelection", False);
@ -2660,15 +2686,16 @@ Start of Linux / Unix defines
/* actions */ /* actions */
XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False); XdndActionCopy = XInternAtom((Display*) win->src.display, "XdndActionCopy", False);
XdndActionMove = XInternAtom((Display*) win->src.display, "XdndActionMove", False);
XdndActionLink = XInternAtom((Display*) win->src.display, "XdndActionLink", False); XtextUriList = XInternAtom((Display*) win->src.display, "text/uri-list", False);
XdndActionAsk = XInternAtom((Display*) win->src.display, "XdndActionAsk", False); XtextPlain = XInternAtom((Display*) win->src.display, "text/plain", False);
XdndActionPrivate = XInternAtom((Display*) win->src.display, "XdndActionPrivate", False);
const Atom version = 5; XdndAware = XInternAtom((Display*) win->src.display, "XdndAware", False);
const u8 version = 5;
XChangeProperty((Display*) win->src.display, (Window) win->src.window, XChangeProperty((Display*) win->src.display, (Window) win->src.window,
XdndAware, 4, 32, XdndAware, 4, 32,
PropModeReplace, (u8*) &version, 1); /*!< turns on drag and drop */ PropModeReplace, &version, 1); /*!< turns on drag and drop */
} }
#ifdef RGFW_EGL #ifdef RGFW_EGL
@ -2716,17 +2743,16 @@ Start of Linux / Unix defines
return RGFWMouse; return RGFWMouse;
} }
typedef struct XDND {
long source, version;
i32 format;
} XDND; /*!< data structure for xdnd events */
XDND xdnd;
int xAxis = 0, yAxis = 0; int xAxis = 0, yAxis = 0;
RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) { RGFW_Event* RGFW_window_checkEvent(RGFW_window* win) {
assert(win != NULL); assert(win != NULL);
static struct {
long source, version;
i32 format;
} xdnd;
if (win->event.type == 0) if (win->event.type == 0)
RGFW_resetKey(); RGFW_resetKey();
@ -2893,13 +2919,16 @@ Start of Linux / Unix defines
win->event.droppedFilesCount = 0; win->event.droppedFilesCount = 0;
/*
much of this event (drag and drop code) is source from glfw
*/
if ((win->_winArgs & RGFW_ALLOW_DND) == 0) if ((win->_winArgs & RGFW_ALLOW_DND) == 0)
break; break;
XEvent reply = { ClientMessage };
reply.xclient.window = xdnd.source;
reply.xclient.format = 32;
reply.xclient.data.l[0] = (long) win->src.window;
reply.xclient.data.l[1] = 0;
reply.xclient.data.l[2] = None;
if (E.xclient.message_type == XdndEnter) { if (E.xclient.message_type == XdndEnter) {
unsigned long count; unsigned long count;
Atom* formats; Atom* formats;
@ -2944,28 +2973,11 @@ Start of Linux / Unix defines
formats = real_formats; formats = real_formats;
} }
u32 i; unsigned long i;
for (i = 0; i < (u32)count; i++) { for (i = 0; i < count; i++) {
char* name = XGetAtomName((Display*) win->src.display, formats[i]); if (formats[i] == XtextUriList || formats[i] == XtextPlain) {
xdnd.format = formats[i];
char* links[2] = { (char*) (const char*) "text/uri-list", (char*) (const char*) "text/plain" }; break;
for (; 1; name++) {
u32 j;
for (j = 0; j < 2; j++) {
if (*links[j] != *name) {
links[j] = (char*) (const char*) "\1";
continue;
}
if (*links[j] == '\0' && *name == '\0')
xdnd.format = formats[i];
if (*links[j] != '\0' && *links[j] != '\1')
links[j]++;
}
if (*name == '\0')
break;
} }
} }
@ -2994,13 +3006,8 @@ Start of Linux / Unix defines
win->event.point.x = xpos; win->event.point.x = xpos;
win->event.point.y = ypos; win->event.point.y = ypos;
XEvent reply = { ClientMessage };
reply.xclient.window = xdnd.source; reply.xclient.window = xdnd.source;
reply.xclient.message_type = XdndStatus; reply.xclient.message_type = XdndStatus;
reply.xclient.format = 32;
reply.xclient.data.l[0] = (long) win->src.window;
reply.xclient.data.l[2] = 0;
reply.xclient.data.l[3] = 0;
if (xdnd.format) { if (xdnd.format) {
reply.xclient.data.l[1] = 1; reply.xclient.data.l[1] = 1;
@ -3035,12 +3042,6 @@ Start of Linux / Unix defines
time); time);
} else if (xdnd.version >= 2) { } else if (xdnd.version >= 2) {
XEvent reply = { ClientMessage }; XEvent reply = { ClientMessage };
reply.xclient.window = xdnd.source;
reply.xclient.message_type = XdndFinished;
reply.xclient.format = 32;
reply.xclient.data.l[0] = (long) win->src.window;
reply.xclient.data.l[1] = 0;
reply.xclient.data.l[2] = None;
XSendEvent((Display*) win->src.display, xdnd.source, XSendEvent((Display*) win->src.display, xdnd.source,
False, NoEventMask, &reply); False, NoEventMask, &reply);
@ -3125,11 +3126,7 @@ Start of Linux / Unix defines
XFree(data); XFree(data);
if (xdnd.version >= 2) { if (xdnd.version >= 2) {
XEvent reply = { ClientMessage };
reply.xclient.window = xdnd.source;
reply.xclient.message_type = XdndFinished; reply.xclient.message_type = XdndFinished;
reply.xclient.format = 32;
reply.xclient.data.l[0] = (long) win->src.window;
reply.xclient.data.l[1] = result; reply.xclient.data.l[1] = result;
reply.xclient.data.l[2] = XdndActionCopy; reply.xclient.data.l[2] = XdndActionCopy;
@ -3480,7 +3477,7 @@ Start of Linux / Unix defines
*size = sizeN; *size = sizeN;
return s; return s;
} }
/* /*
almost all of this function is sourced from GLFW almost all of this function is sourced from GLFW
@ -3520,9 +3517,6 @@ Start of Linux / Unix defines
XEvent reply = { SelectionNotify }; XEvent reply = { SelectionNotify };
reply.xselection.property = 0; reply.xselection.property = 0;
const Atom formats[] = { UTF8_STRING, XA_STRING };
const i32 formatCount = sizeof(formats) / sizeof(formats[0]);
if (request->target == TARGETS) { if (request->target == TARGETS) {
const Atom targets[] = { TARGETS, const Atom targets[] = { TARGETS,
MULTIPLE, MULTIPLE,
@ -3552,15 +3546,7 @@ Start of Linux / Unix defines
unsigned long i; unsigned long i;
for (i = 0; i < (u32)count; i += 2) { for (i = 0; i < (u32)count; i += 2) {
i32 j; if (targets[i] == UTF8_STRING || targets[i] == XA_STRING) {
for (j = 0; j < formatCount; j++) {
if (targets[i] == formats[j])
break;
}
if (j < formatCount)
{
XChangeProperty((Display*) RGFW_root->src.display, XChangeProperty((Display*) RGFW_root->src.display,
request->requestor, request->requestor,
targets[i + 1], targets[i + 1],
@ -3727,32 +3713,54 @@ Start of Linux / Unix defines
RGFW_monitor monitor; RGFW_monitor monitor;
Display* display = XOpenDisplay(NULL); Display* display = XOpenDisplay(NULL);
RGFW_area size = RGFW_getScreenSize();
monitor.rect = RGFW_RECT(0, 0, DisplayWidth(display, screen), DisplayHeight(display, screen)); monitor.rect = RGFW_RECT(0, 0, size.w, size.h);
monitor.physW = (monitor.rect.w * 25.4f / 96.f); monitor.physW = DisplayWidthMM(display, screen);
monitor.physH = (monitor.rect.h * 25.4f / 96.f); monitor.physH = DisplayHeightMM(display, screen);
strncpy(monitor.name, DisplayString(display), 128);
XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY); XGetSystemContentScale(display, &monitor.scaleX, &monitor.scaleY);
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(display, RootWindow(display, screen)); XRRScreenResources* sr = XRRGetScreenResourcesCurrent(display, RootWindow(display, screen));
XRRCrtcInfo* ci = NULL; XRRCrtcInfo* ci = NULL;
int crtc = 0; int crtc = screen;
if (sr->ncrtc > crtc) { if (sr->ncrtc > crtc) {
ci = XRRGetCrtcInfo(display, sr, sr->crtcs[crtc]); ci = XRRGetCrtcInfo(display, sr, sr->crtcs[crtc]);
} }
if (ci == NULL) { if (ci == NULL) {
float dpi_width = round((double)monitor.rect.w/(((double)monitor.physW)/25.4));
float dpi_height = round((double)monitor.rect.h/(((double)monitor.physH)/25.4));
monitor.scaleX = (float) (dpi_width) / (float) 96;
monitor.scaleY = (float) (dpi_height) / (float) 96;
XRRFreeScreenResources(sr); XRRFreeScreenResources(sr);
XCloseDisplay(display); XCloseDisplay(display);
return monitor; return monitor;
} }
XRROutputInfo* info = XRRGetOutputInfo (display, sr, sr->outputs[screen]);
monitor.physW = info->mm_width;
monitor.physH = info->mm_height;
monitor.rect.x = ci->x; monitor.rect.x = ci->x;
monitor.rect.y = ci->y; monitor.rect.y = ci->y;
monitor.rect.w = ci->width;
monitor.rect.h = ci->height;
float dpi_width = round((double)monitor.rect.w/(((double)monitor.physW)/25.4));
float dpi_height = round((double)monitor.rect.h/(((double)monitor.physH)/25.4));
monitor.scaleX = (float) (dpi_width) / (float) 96;
monitor.scaleY = (float) (dpi_height) / (float) 96;
if (monitor.scaleX > 1 && monitor.scaleX < 1.1)
monitor.scaleX = 1;
if (monitor.scaleY > 1 && monitor.scaleY < 1.1)
monitor.scaleY = 1;
XRRFreeCrtcInfo(ci); XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr); XRRFreeScreenResources(sr);
@ -4150,9 +4158,6 @@ RGFW_Event RGFW_eventPipe_pop(RGFW_window* win) {
if (win->src.eventLen >= 0) if (win->src.eventLen >= 0)
ev = win->src.events[win->src.eventLen]; ev = win->src.events[win->src.eventLen];
else {
printf("H2\n");
}
return ev; return ev;
} }
@ -4675,6 +4680,10 @@ static const struct wl_callback_listener wl_surface_frame_listener = {
decoration_manager, win->src.xdg_toplevel); decoration_manager, win->src.xdg_toplevel);
} }
if (args & RGFW_CENTER) {
RGFW_area screenR = RGFW_getScreenSize();
RGFW_window_move(win, RGFW_POINT((screenR.w - win->r.w) / 2, (screenR.h - win->r.h) / 2));
}
if (args & RGFW_OPENGL_SOFTWARE) if (args & RGFW_OPENGL_SOFTWARE)
setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1); setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
@ -4999,9 +5008,7 @@ static const struct wl_callback_listener wl_surface_frame_listener = {
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define OEMRESOURCE #define OEMRESOURCE
#include <windows.h> #include <windows.h>
__declspec(dllimport) int __stdcall WideCharToMultiByte( UINT CodePage, DWORD dwFlags, const WCHAR* lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar);
#include <processthreadsapi.h> #include <processthreadsapi.h>
#include <wchar.h> #include <wchar.h>
#include <locale.h> #include <locale.h>
@ -5009,6 +5016,10 @@ static const struct wl_callback_listener wl_surface_frame_listener = {
#include <shellapi.h> #include <shellapi.h>
#include <shellscalingapi.h> #include <shellscalingapi.h>
#include <winuser.h>
__declspec(dllimport) int __stdcall WideCharToMultiByte( UINT CodePage, DWORD dwFlags, const WCHAR* lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar);
#ifndef RGFW_NO_XINPUT #ifndef RGFW_NO_XINPUT
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*); typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
PFN_XInputGetState XInputGetStateSRC = NULL; PFN_XInputGetState XInputGetStateSRC = NULL;
@ -5226,14 +5237,15 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
} }
void RGFW_releaseCursor(RGFW_window* win) { void RGFW_releaseCursor(RGFW_window* win) {
RGFW_UNUSED(win);
ClipCursor(NULL); ClipCursor(NULL);
const RAWINPUTDEVICE id = { 0x01, 0x02, RIDEV_REMOVE, NULL }; const RAWINPUTDEVICE id = { 0x01, 0x02, RIDEV_REMOVE, NULL };
RegisterRawInputDevices(&id, 1, sizeof(id)); RegisterRawInputDevices(&id, 1, sizeof(id));
} }
void RGFW_captureCursor(RGFW_window* win, RGFW_rect rect) { void RGFW_captureCursor(RGFW_window* win, RGFW_rect rect) {
RGFW_UNUSED(win) RGFW_UNUSED(win); RGFW_UNUSED(rect);
RECT clipRect; RECT clipRect;
GetClientRect(win->src.window, &clipRect); GetClientRect(win->src.window, &clipRect);
ClientToScreen(win->src.window, (POINT*) &clipRect.left); ClientToScreen(win->src.window, (POINT*) &clipRect.left);
@ -5254,6 +5266,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
if (RGFW_Shcore_dll == NULL) { if (RGFW_Shcore_dll == NULL) {
RGFW_Shcore_dll = LoadLibraryA("shcore.dll"); RGFW_Shcore_dll = LoadLibraryA("shcore.dll");
GetDpiForMonitorSRC = (PFN_GetDpiForMonitor)(void*)GetProcAddress(RGFW_Shcore_dll, "GetDpiForMonitor"); GetDpiForMonitorSRC = (PFN_GetDpiForMonitor)(void*)GetProcAddress(RGFW_Shcore_dll, "GetDpiForMonitor");
SetProcessDPIAware();
} }
#endif #endif
@ -5288,7 +5301,10 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
WNDCLASSA Class = { }; WNDCLASSA Class = { };
#endif #endif
Class.lpszClassName = name; if (RGFW_className == NULL)
RGFW_className = (char*)name;
Class.lpszClassName = RGFW_className;
Class.hInstance = inh; Class.hInstance = inh;
Class.hCursor = LoadCursor(NULL, IDC_ARROW); Class.hCursor = LoadCursor(NULL, IDC_ARROW);
Class.lpfnWndProc = WndProc; Class.lpfnWndProc = WndProc;
@ -5501,6 +5517,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
if (args & RGFW_SCALE_TO_MONITOR) if (args & RGFW_SCALE_TO_MONITOR)
RGFW_window_scaleToMonitor(win); RGFW_window_scaleToMonitor(win);
#endif #endif
if (args & RGFW_CENTER) {
RGFW_area screenR = RGFW_getScreenSize();
RGFW_window_move(win, RGFW_POINT((screenR.w - win->r.w) / 2, (screenR.h - win->r.h) / 2));
}
#ifdef RGFW_EGL #ifdef RGFW_EGL
if ((args & RGFW_NO_INIT_API) == 0) if ((args & RGFW_NO_INIT_API) == 0)
@ -6102,7 +6123,8 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
if (GetDpiForMonitor != NULL) { if (GetDpiForMonitor != NULL) {
u32 x, y; u32 x, y;
GetDpiForMonitor(src, MDT_ANGULAR_DPI, &x, &y); GetDpiForMonitor(src, MDT_EFFECTIVE_DPI, &x, &y);
monitor.scaleX = (float) (x) / (float) USER_DEFAULT_SCREEN_DPI; monitor.scaleX = (float) (x) / (float) USER_DEFAULT_SCREEN_DPI;
monitor.scaleY = (float) (y) / (float) USER_DEFAULT_SCREEN_DPI; monitor.scaleY = (float) (y) / (float) USER_DEFAULT_SCREEN_DPI;
} }
@ -6117,7 +6139,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
/* Calculate physical height in inches */ /* Calculate physical height in inches */
monitor.physW = GetSystemMetrics(SM_CYSCREEN) / (float) ppiX; monitor.physW = GetSystemMetrics(SM_CYSCREEN) / (float) ppiX;
monitor.physH = GetSystemMetrics(SM_CXSCREEN) / (float) ppiY; monitor.physH = GetSystemMetrics(SM_CXSCREEN) / (float) ppiY;
return monitor; return monitor;
} }
#endif /* RGFW_NO_MONITOR */ #endif /* RGFW_NO_MONITOR */
@ -6152,7 +6174,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
RGFW_mInfo info; RGFW_mInfo info;
info.iIndex = 0; info.iIndex = 0;
while (EnumDisplayMonitors(NULL, NULL, GetMonitorHandle, (LPARAM) &info)); while (EnumDisplayMonitors(NULL, NULL, GetMonitorHandle, (LPARAM) &info));
return RGFW_monitors; return RGFW_monitors;
} }
@ -7104,7 +7126,6 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
id fileURL = objc_msgSend_arr(fileURLs, sel_registerName("objectAtIndex:"), i); id fileURL = objc_msgSend_arr(fileURLs, sel_registerName("objectAtIndex:"), i);
const char *filePath = ((const char* (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("UTF8String")); const char *filePath = ((const char* (*)(id, SEL))objc_msgSend)(fileURL, sel_registerName("UTF8String"));
// printf("File: %s\n", filePath);
strncpy(win->event.droppedFiles[i], filePath, RGFW_MAX_PATH); strncpy(win->event.droppedFiles[i], filePath, RGFW_MAX_PATH);
win->event.droppedFiles[i][RGFW_MAX_PATH - 1] = '\0'; win->event.droppedFiles[i][RGFW_MAX_PATH - 1] = '\0';
} }
@ -7208,6 +7229,16 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
#endif #endif
} }
void RGFW_window_cocoaSetLayer(RGFW_window* win, void* layer) {
objc_msgSend_void_id(win->src.view, sel_registerName("setLayer"), layer);
}
void* RGFW_cocoaGetLayer(void) {
return objc_msgSend_class(objc_getClass("CAMetalLayer"), sel_registerName("layer"));
}
NSPasteboardType const NSPasteboardTypeURL = "public.url"; NSPasteboardType const NSPasteboardTypeURL = "public.url";
NSPasteboardType const NSPasteboardTypeFileURL = "public.file-url"; NSPasteboardType const NSPasteboardTypeFileURL = "public.file-url";
@ -7263,6 +7294,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
NSString* str = NSString_stringWithUTF8String(name); NSString* str = NSString_stringWithUTF8String(name);
objc_msgSend_void_id(win->src.window, sel_registerName("setTitle:"), str); objc_msgSend_void_id(win->src.window, sel_registerName("setTitle:"), str);
#ifdef RGFW_EGL
if ((args & RGFW_NO_INIT_API) == 0)
RGFW_createOpenGLContext(win);
#endif
#ifdef RGFW_OPENGL #ifdef RGFW_OPENGL
if ((args & RGFW_NO_INIT_API) == 0) { if ((args & RGFW_NO_INIT_API) == 0) {
void* attrs = RGFW_initFormatAttribs(args & RGFW_OPENGL_SOFTWARE); void* attrs = RGFW_initFormatAttribs(args & RGFW_OPENGL_SOFTWARE);
@ -7329,6 +7365,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
RGFW_window_scaleToMonitor(win); RGFW_window_scaleToMonitor(win);
#endif #endif
if (args & RGFW_CENTER) {
RGFW_area screenR = RGFW_getScreenSize();
RGFW_window_move(win, RGFW_POINT((screenR.w - win->r.w) / 2, (screenR.h - win->r.h) / 2));
}
if (args & RGFW_HIDE_MOUSE) if (args & RGFW_HIDE_MOUSE)
RGFW_window_showMouse(win, 0); RGFW_window_showMouse(win, 0);
@ -7935,6 +7976,7 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
} }
void RGFW_releaseCursor(RGFW_window* win) { void RGFW_releaseCursor(RGFW_window* win) {
RGFW_UNUSED(win);
CGAssociateMouseAndMouseCursorPosition(1); CGAssociateMouseAndMouseCursorPosition(1);
} }
@ -7994,13 +8036,11 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
monitor.rect = RGFW_RECT((int) bounds.origin.x, (int) bounds.origin.y, (int) bounds.size.width, (int) bounds.size.height); monitor.rect = RGFW_RECT((int) bounds.origin.x, (int) bounds.origin.y, (int) bounds.size.width, (int) bounds.size.height);
CGSize screenSizeMM = CGDisplayScreenSize(display); CGSize screenSizeMM = CGDisplayScreenSize(display);
monitor.physW = screenSizeMM.width / 25.4; monitor.physW = screenSizeMM.width;
monitor.physH = screenSizeMM.height / 25.4; monitor.physH = screenSizeMM.height;
monitor.scaleX = (monitor.rect.w / (screenSizeMM.width)) / 2.6; monitor.scaleX = ((monitor.rect.w / (screenSizeMM.width / 25.4)) / 96) + 0.25;
monitor.scaleY = (monitor.rect.h / (screenSizeMM.height)) / 2.6; monitor.scaleY = ((monitor.rect.h / (screenSizeMM.height / 25.4)) / 96) + 0.25;
snprintf(monitor.name, 128, "%i %i %i", CGDisplayModelNumber(display), CGDisplayVendorNumber(display), CGDisplaySerialNumber(display));
return monitor; return monitor;
} }
@ -8090,6 +8130,8 @@ RGFW_UNUSED(win); /*!< if buffer rendering is not being used */
#if defined(RGFW_OPENGL) #if defined(RGFW_OPENGL)
NSOpenGLContext_setValues(win->src.ctx, &swapInterval, 222); NSOpenGLContext_setValues(win->src.ctx, &swapInterval, 222);
#else
RGFW_UNUSED(swapInterval);
#endif #endif
} }
#endif #endif
@ -8532,7 +8574,7 @@ RGFW_window* RGFW_createWindow(const char* name, RGFW_rect rect, u16 args) {
emscripten_webgl_make_context_current(win->src.ctx); emscripten_webgl_make_context_current(win->src.ctx);
#ifdef LEGACY_GL_EMULATION #ifdef LEGACY_GL_EMULATION
EM_ASM("Module.useWebGL = true; GLImmediate.init();"); EM_ASM("Module.useWebGL = true; GLImmediate.init();");
#endif #endif
emscripten_set_canvas_element_size("#canvas", rect.w, rect.h); emscripten_set_canvas_element_size("#canvas", rect.w, rect.h);
@ -8875,11 +8917,12 @@ u64 RGFW_getTime(void) {
} }
void RGFW_releaseCursor(RGFW_window* win) { void RGFW_releaseCursor(RGFW_window* win) {
RGFW_UNUSED(win);
emscripten_exit_pointerlock(); emscripten_exit_pointerlock();
} }
void RGFW_captureCursor(RGFW_window* win, RGFW_rect r) { void RGFW_captureCursor(RGFW_window* win, RGFW_rect r) {
RGFW_UNUSED(win) RGFW_UNUSED(win); RGFW_UNUSED(r);
emscripten_request_pointerlock("#canvas", 1); emscripten_request_pointerlock("#canvas", 1);
} }

3053
src/external/nanosvg.h vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -704,7 +704,6 @@ void PollInputEvents(void)
} }
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Internal Functions Definition // Module Internal Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -1234,7 +1234,6 @@ void PollInputEvents(void)
glfwSetWindowShouldClose(platform.handle, GLFW_FALSE); glfwSetWindowShouldClose(platform.handle, GLFW_FALSE);
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Internal Functions Definition // Module Internal Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1447,7 +1446,7 @@ int InitPlatform(void)
} }
} }
TRACELOG(LOG_WARNING, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height); TRACELOG(LOG_INFO, "SYSTEM: Closest fullscreen videomode: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example, // NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
// for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3), // for a desired screen size of 800x450 (16:9), closest supported videomode is 800x600 (4:3),

View File

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* rcore_desktop_rgfw template - Functions to manage window, graphics device and inputs * rcore_desktop_rgfw - Functions to manage window, graphics device and inputs
* *
* PLATFORM: RGFW * PLATFORM: RGFW
* - Windows (Win32, Win64) * - Windows (Win32, Win64)
@ -69,6 +69,7 @@ void CloseWindow(void);
#define CloseWindow CloseWindow_win32 #define CloseWindow CloseWindow_win32
#define ShowCursor __imp_ShowCursor #define ShowCursor __imp_ShowCursor
#define _APISETSTRING_ #define _APISETSTRING_
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
@ -76,8 +77,6 @@ void CloseWindow(void);
#define Size NSSIZE #define Size NSSIZE
#endif #endif
__declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
#include "../external/RGFW.h" #include "../external/RGFW.h"
#if defined(__WIN32) || defined(__WIN64) #if defined(__WIN32) || defined(__WIN64)
@ -289,7 +288,6 @@ void SetWindowState(unsigned int flags)
} }
if (flags & FLAG_WINDOW_RESIZABLE) if (flags & FLAG_WINDOW_RESIZABLE)
{ {
printf("%i %i\n", platform.window->r.w, platform.window->r.h);
RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h));
} }
@ -688,7 +686,7 @@ void DisableCursor(void)
{ {
RGFW_disableCursor = true; RGFW_disableCursor = true;
RGFW_window_mouseHold(platform.window, RGFW_AREA(CORE.Window.screen.width / 2, CORE.Window.screen.height / 2)); RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
HideCursor(); HideCursor();
} }
@ -872,9 +870,8 @@ void PollInputEvents(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
CORE.Window.resizedLastFrame = false; CORE.Window.resizedLastFrame = false;
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
#define RGFW_HOLD_MOUSE (1L<<2) #define RGFW_HOLD_MOUSE (1L<<2)
#if defined(RGFW_X11) //|| defined(RGFW_MACOS)
if (platform.window->_winArgs & RGFW_HOLD_MOUSE) if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
{ {
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f };
@ -884,11 +881,9 @@ void PollInputEvents(void)
{ {
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
} }
#endif
while (RGFW_window_checkEvent(platform.window)) while (RGFW_window_checkEvent(platform.window))
{ {
if ((platform.window->event.type >= RGFW_jsButtonPressed) && (platform.window->event.type <= RGFW_jsAxisMove)) if ((platform.window->event.type >= RGFW_jsButtonPressed) && (platform.window->event.type <= RGFW_jsAxisMove))
{ {
if (!CORE.Input.Gamepad.ready[platform.window->event.joystick]) if (!CORE.Input.Gamepad.ready[platform.window->event.joystick])
@ -1030,15 +1025,8 @@ void PollInputEvents(void)
{ {
if (platform.window->_winArgs & RGFW_HOLD_MOUSE) if (platform.window->_winArgs & RGFW_HOLD_MOUSE)
{ {
CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; CORE.Input.Mouse.currentPosition.x += (float)event->point.x;
CORE.Input.Mouse.currentPosition.y += (float)event->point.y;
if (event->point.x)
CORE.Input.Mouse.previousPosition.x = CORE.Input.Mouse.currentPosition.x;
if (event->point.y)
CORE.Input.Mouse.previousPosition.y = CORE.Input.Mouse.currentPosition.y;
CORE.Input.Mouse.currentPosition.x = (float)event->point.x;
CORE.Input.Mouse.currentPosition.y = (float)event->point.y;
} }
else else
{ {
@ -1205,7 +1193,6 @@ void PollInputEvents(void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Internal Functions Definition // Module Internal Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1262,7 +1249,6 @@ int InitPlatform(void)
*/ */
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1); if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1);
RGFW_window_makeCurrent(platform.window); RGFW_window_makeCurrent(platform.window);

View File

@ -57,6 +57,13 @@
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer) #include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
#endif #endif
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#ifndef MAX_CLIPBOARD_BUFFER_LENGTH
#define MAX_CLIPBOARD_BUFFER_LENGTH 1024 // Size of the clipboard buffer used on GetClipboardText()
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -852,10 +859,22 @@ void SetClipboardText(const char *text)
} }
// Get clipboard text content // Get clipboard text content
// NOTE: returned string must be freed with SDL_free()
const char *GetClipboardText(void) const char *GetClipboardText(void)
{ {
return SDL_GetClipboardText(); static char buffer[MAX_CLIPBOARD_BUFFER_LENGTH] = { 0 };
char *clipboard = SDL_GetClipboardText();
int clipboardSize = snprintf(buffer, sizeof(buffer), "%s", clipboard);
if (clipboardSize >= MAX_CLIPBOARD_BUFFER_LENGTH)
{
char *truncate = buffer + MAX_CLIPBOARD_BUFFER_LENGTH - 4;
sprintf(truncate, "...");
}
SDL_free(clipboard);
return buffer;
} }
// Show mouse cursor // Show mouse cursor
@ -1589,8 +1608,8 @@ int InitPlatform(void)
// Initialize storage system // Initialize storage system
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Define base path for storage // Define base path for storage
CORE.Storage.basePath = SDL_GetBasePath(); // Alternative: GetWorkingDirectory(); CORE.Storage.basePath = SDL_GetBasePath(); // Alternative: GetWorkingDirectory();
CHDIR(CORE.Storage.basePath); CHDIR(CORE.Storage.basePath);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully"); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (SDL): Initialized successfully");

View File

@ -1480,7 +1480,6 @@ static void ConfigureEvdevDevice(char *device)
TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true; TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true;
} }
if (TEST_BIT(evBits, EV_KEY)) if (TEST_BIT(evBits, EV_KEY))
{ {
// The first 32 keys as defined in input-event-codes.h are pretty much // The first 32 keys as defined in input-event-codes.h are pretty much

View File

@ -430,7 +430,6 @@ void PollInputEvents(void)
// TODO: Poll input events for current platform // TODO: Poll input events for current platform
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Internal Functions Definition // Module Internal Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -935,7 +935,6 @@ void PollInputEvents(void)
// so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed! // so, if mouse is not moved it returns a (0, 0) position... this behaviour should be reviewed!
//for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 }; //for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };
// Gamepad support using emscripten API // Gamepad support using emscripten API
// NOTE: GLFW3 joystick functionality not available in web // NOTE: GLFW3 joystick functionality not available in web

View File

@ -1312,7 +1312,6 @@ RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2);
// NOTE: These functions do not require GPU access // NOTE: These functions do not require GPU access
RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
RLAPI Image LoadImageSvg(const char *fileNameOrString, int width, int height); // Load image from SVG file data or string with specified size
RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data) RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data)
RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png' RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'

View File

@ -162,7 +162,6 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
#endif // RCAMERA_H #endif // RCAMERA_H
/*********************************************************************************** /***********************************************************************************
* *
* CAMERA IMPLEMENTATION * CAMERA IMPLEMENTATION
@ -444,11 +443,17 @@ void UpdateCamera(Camera *camera, int mode)
bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL)); bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
bool rotateUp = false; bool rotateUp = false;
// Camera speeds based on frame time
float cameraMoveSpeed = CAMERA_MOVE_SPEED*GetFrameTime();
float cameraRotationSpeed = CAMERA_ROTATION_SPEED*GetFrameTime();
float cameraPanSpeed = CAMERA_PAN_SPEED*GetFrameTime();
float cameraOrbitalSpeed = CAMERA_ORBITAL_SPEED*GetFrameTime();
if (mode == CAMERA_CUSTOM) {} if (mode == CAMERA_CUSTOM) {}
else if (mode == CAMERA_ORBITAL) else if (mode == CAMERA_ORBITAL)
{ {
// Orbital can just orbit // Orbital can just orbit
Matrix rotation = MatrixRotate(GetCameraUp(camera), CAMERA_ORBITAL_SPEED*GetFrameTime()); Matrix rotation = MatrixRotate(GetCameraUp(camera), cameraOrbitalSpeed);
Vector3 view = Vector3Subtract(camera->position, camera->target); Vector3 view = Vector3Subtract(camera->position, camera->target);
view = Vector3Transform(view, rotation); view = Vector3Transform(view, rotation);
camera->position = Vector3Add(camera->target, view); camera->position = Vector3Add(camera->target, view);
@ -456,22 +461,22 @@ void UpdateCamera(Camera *camera, int mode)
else else
{ {
// Camera rotation // Camera rotation
if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp); if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
if (IsKeyDown(KEY_UP)) CameraPitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp); if (IsKeyDown(KEY_UP)) CameraPitch(camera, cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget); if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -cameraRotationSpeed, rotateAroundTarget);
if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget); if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, cameraRotationSpeed, rotateAroundTarget);
if (IsKeyDown(KEY_Q)) CameraRoll(camera, -CAMERA_ROTATION_SPEED); if (IsKeyDown(KEY_Q)) CameraRoll(camera, -cameraRotationSpeed);
if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED); if (IsKeyDown(KEY_E)) CameraRoll(camera, cameraRotationSpeed);
// Camera movement // Camera movement
// Camera pan (for CAMERA_FREE) // Camera pan (for CAMERA_FREE)
if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))) if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
{ {
const Vector2 mouseDelta = GetMouseDelta(); const Vector2 mouseDelta = GetMouseDelta();
if (mouseDelta.x > 0.0f) CameraMoveRight(camera, CAMERA_PAN_SPEED, moveInWorldPlane); if (mouseDelta.x > 0.0f) CameraMoveRight(camera, cameraPanSpeed, moveInWorldPlane);
if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -CAMERA_PAN_SPEED, moveInWorldPlane); if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -cameraPanSpeed, moveInWorldPlane);
if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -CAMERA_PAN_SPEED); if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -cameraPanSpeed);
if (mouseDelta.y < 0.0f) CameraMoveUp(camera, CAMERA_PAN_SPEED); if (mouseDelta.y < 0.0f) CameraMoveUp(camera, cameraPanSpeed);
} }
else else
{ {
@ -481,7 +486,6 @@ void UpdateCamera(Camera *camera, int mode)
} }
// Keyboard support // Keyboard support
float cameraMoveSpeed = CAMERA_MOVE_SPEED*GetFrameTime();
if (IsKeyDown(KEY_W)) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane); if (IsKeyDown(KEY_W)) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane); if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane); if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);

View File

@ -578,7 +578,6 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
//void DisableCursor(void) //void DisableCursor(void)
// Initialize window and OpenGL context // Initialize window and OpenGL context
// NOTE: data parameter could be used to pass any kind of required data to the initialization
void InitWindow(int width, int height, const char *title) void InitWindow(int width, int height, const char *title)
{ {
TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION); TRACELOG(LOG_INFO, "Initializing raylib %s", RAYLIB_VERSION);

View File

@ -345,15 +345,17 @@
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
#endif #endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
#endif #endif
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
#endif #endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
#endif #endif
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
@ -4172,7 +4174,7 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT); glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
#ifdef RL_SUPPORT_MESH_ANIMATION_VBO #ifdef RL_SUPPORT_MESH_GPU_SKINNING
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS); glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS); glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS);
#endif #endif

View File

@ -702,7 +702,6 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
rlPopMatrix(); rlPopMatrix();
} }
// Draw a wired cylinder with base at startPos and top at endPos // Draw a wired cylinder with base at startPos and top at endPos
// NOTE: It could be also used for pyramid and cone // NOTE: It could be also used for pyramid and cone
void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color) void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color)
@ -1253,9 +1252,11 @@ void UploadMesh(Mesh *mesh, bool dynamic)
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT] = 0; // Vertex buffer: tangents mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT] = 0; // Vertex buffer: tangents
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2] = 0; // Vertex buffer: texcoords2 mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2] = 0; // Vertex buffer: texcoords2
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES] = 0; // Vertex buffer: indices mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES] = 0; // Vertex buffer: indices
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS] = 0; // Vertex buffer: boneIds mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS] = 0; // Vertex buffer: boneIds
mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS] = 0; // Vertex buffer: boneWeights mesh->vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS] = 0; // Vertex buffer: boneWeights
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
mesh->vaoId = rlLoadVertexArray(); mesh->vaoId = rlLoadVertexArray();
@ -1342,7 +1343,7 @@ void UploadMesh(Mesh *mesh, bool dynamic)
rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2); rlDisableVertexAttribute(RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2);
} }
#ifdef RL_SUPPORT_MESH_ANIMATION_VBO #ifdef RL_SUPPORT_MESH_GPU_SKINNING
if (mesh->boneIds != NULL) if (mesh->boneIds != NULL)
{ {
// Enable vertex attribute: boneIds (shader-location = 6) // Enable vertex attribute: boneIds (shader-location = 6)
@ -1489,7 +1490,7 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
// Upload model normal matrix (if locations available) // Upload model normal matrix (if locations available)
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel))); if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
#ifdef RL_SUPPORT_MESH_ANIMATION_VBO #ifdef RL_SUPPORT_MESH_GPU_SKINNING
// Upload Bone Transforms // Upload Bone Transforms
if (material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1 && mesh.boneMatrices) if (material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1 && mesh.boneMatrices)
{ {
@ -1575,7 +1576,7 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]); rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
} }
#ifdef RL_SUPPORT_MESH_ANIMATION_VBO #ifdef RL_SUPPORT_MESH_GPU_SKINNING
// Bind mesh VBO data: vertex bone ids (shader-location = 6, if available) // Bind mesh VBO data: vertex bone ids (shader-location = 6, if available)
if (material.shader.locs[SHADER_LOC_VERTEX_BONEIDS] != -1) if (material.shader.locs[SHADER_LOC_VERTEX_BONEIDS] != -1)
{ {
@ -1735,7 +1736,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
// Upload model normal matrix (if locations available) // Upload model normal matrix (if locations available)
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel))); if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
#ifdef RL_SUPPORT_MESH_ANIMATION_VBO #ifdef RL_SUPPORT_MESH_GPU_SKINNING
// Upload Bone Transforms // Upload Bone Transforms
if (material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1 && mesh.boneMatrices) if (material.shader.locs[SHADER_LOC_BONE_MATRICES] != -1 && mesh.boneMatrices)
{ {
@ -1819,7 +1820,8 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0); rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]); rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
} }
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
// Bind mesh VBO data: vertex bone ids (shader-location = 6, if available) // Bind mesh VBO data: vertex bone ids (shader-location = 6, if available)
if (material.shader.locs[SHADER_LOC_VERTEX_BONEIDS] != -1) if (material.shader.locs[SHADER_LOC_VERTEX_BONEIDS] != -1)
{ {
@ -1835,6 +1837,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS], 4, RL_FLOAT, 0, 0, 0); rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS], 4, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS]); rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS]);
} }
#endif
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES]); if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES]);
} }
@ -2093,7 +2096,6 @@ bool ExportMeshAsCode(Mesh mesh, const char *fileName)
return success; return success;
} }
#if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL) #if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)
// Process obj materials // Process obj materials
static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, int materialCount) static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, int materialCount)
@ -5224,17 +5226,19 @@ static Model LoadGLTF(const char *fileName)
***********************************************************************************************/ ***********************************************************************************************/
// Macro to simplify attributes loading code // Macro to simplify attributes loading code
#define LOAD_ATTRIBUTE(accesor, numComp, dataType, dstPtr) \ #define LOAD_ATTRIBUTE(accesor, numComp, srcType, dstPtr) LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, srcType)
#define LOAD_ATTRIBUTE_CAST(accesor, numComp, srcType, dstPtr, dstType) \
{ \ { \
int n = 0; \ int n = 0; \
dataType *buffer = (dataType *)accesor->buffer_view->buffer->data + accesor->buffer_view->offset/sizeof(dataType) + accesor->offset/sizeof(dataType); \ srcType *buffer = (srcType *)accesor->buffer_view->buffer->data + accesor->buffer_view->offset/sizeof(srcType) + accesor->offset/sizeof(srcType); \
for (unsigned int k = 0; k < accesor->count; k++) \ for (unsigned int k = 0; k < accesor->count; k++) \
{\ {\
for (int l = 0; l < numComp; l++) \ for (int l = 0; l < numComp; l++) \
{\ {\
dstPtr[numComp*k + l] = buffer[n + l];\ dstPtr[numComp*k + l] = (dstType)buffer[n + l];\
}\ }\
n += (int)(accesor->stride/sizeof(dataType));\ n += (int)(accesor->stride/sizeof(srcType));\
}\ }\
} }
@ -5675,8 +5679,6 @@ static Model LoadGLTF(const char *fileName)
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Color attribute data format not supported", fileName);
} }
// NOTE: Attributes related to animations are processed separately // NOTE: Attributes related to animations are processed separately
@ -5697,23 +5699,25 @@ static Model LoadGLTF(const char *fileName)
// Load unsigned short data type into mesh.indices // Load unsigned short data type into mesh.indices
LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices) LOAD_ATTRIBUTE(attribute, 1, unsigned short, model.meshes[meshIndex].indices)
} }
else if (attribute->component_type == cgltf_component_type_r_8u)
{
// Init raylib mesh indices to copy glTF attribute data
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count * sizeof(unsigned short));
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short)
}
else if (attribute->component_type == cgltf_component_type_r_32u) else if (attribute->component_type == cgltf_component_type_r_32u)
{ {
// Init raylib mesh indices to copy glTF attribute data // Init raylib mesh indices to copy glTF attribute data
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short)); model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short));
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned int, model.meshes[meshIndex].indices, unsigned short);
// Load data into a temp buffer to be converted to raylib data type
unsigned int *temp = RL_MALLOC(attribute->count*sizeof(unsigned int));
LOAD_ATTRIBUTE(attribute, 1, unsigned int, temp);
// Convert data to raylib indices data type (unsigned short)
for (unsigned int d = 0; d < attribute->count; d++) model.meshes[meshIndex].indices[d] = (unsigned short)temp[d];
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName); TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data converted from u32 to u16, possible loss of data", fileName);
RL_FREE(temp);
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName); else
{
TRACELOG(LOG_WARNING, "MODEL: [%s] Indices data format not supported, use u16", fileName);
}
} }
else model.meshes[meshIndex].triangleCount = model.meshes[meshIndex].vertexCount/3; // Unindexed mesh else model.meshes[meshIndex].triangleCount = model.meshes[meshIndex].vertexCount/3; // Unindexed mesh
@ -5745,7 +5749,7 @@ static Model LoadGLTF(const char *fileName)
// - Only supports linear interpolation (default method in Blender when checked "Always Sample Animations" when exporting a GLTF file) // - Only supports linear interpolation (default method in Blender when checked "Always Sample Animations" when exporting a GLTF file)
// - Only supports translation/rotation/scale animation channel.path, weights not considered (i.e. morph targets) // - Only supports translation/rotation/scale animation channel.path, weights not considered (i.e. morph targets)
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
if (data->skins_count == 1) if (data->skins_count > 0)
{ {
cgltf_skin skin = data->skins[0]; cgltf_skin skin = data->skins[0];
model.bones = LoadBoneInfoGLTF(skin, &model.boneCount); model.bones = LoadBoneInfoGLTF(skin, &model.boneCount);
@ -5765,9 +5769,9 @@ static Model LoadGLTF(const char *fileName)
MatrixDecompose(worldMatrix, &(model.bindPose[i].translation), &(model.bindPose[i].rotation), &(model.bindPose[i].scale)); MatrixDecompose(worldMatrix, &(model.bindPose[i].translation), &(model.bindPose[i].rotation), &(model.bindPose[i].scale));
} }
} }
else if (data->skins_count > 1) if (data->skins_count > 1)
{ {
TRACELOG(LOG_ERROR, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count); TRACELOG(LOG_WARNING, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
} }
meshIndex = 0; meshIndex = 0;
@ -6088,7 +6092,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
if (result == cgltf_result_success) if (result == cgltf_result_success)
{ {
if (data->skins_count == 1) if (data->skins_count > 0)
{ {
cgltf_skin skin = data->skins[0]; cgltf_skin skin = data->skins[0];
*animCount = (int)data->animations_count; *animCount = (int)data->animations_count;
@ -6223,7 +6227,11 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
RL_FREE(boneChannels); RL_FREE(boneChannels);
} }
} }
else TRACELOG(LOG_ERROR, "MODEL: [%s] expected exactly one skin to load animation data from, but found %i", fileName, data->skins_count);
if (data->skins_count > 1)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] expected exactly one skin to load animation data from, but found %i", fileName, data->skins_count);
}
cgltf_free(data); cgltf_free(data);
} }

View File

@ -828,8 +828,8 @@ void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color)
{ {
if ((lineThick > rec.width) || (lineThick > rec.height)) if ((lineThick > rec.width) || (lineThick > rec.height))
{ {
if (rec.width > rec.height) lineThick = rec.height/2; if (rec.width >= rec.height) lineThick = rec.height/2;
else if (rec.width < rec.height) lineThick = rec.width/2; else if (rec.width <= rec.height) lineThick = rec.width/2;
} }
// When rec = { x, y, 8.0f, 6.0f } and lineThick = 2, the following // When rec = { x, y, 8.0f, 6.0f } and lineThick = 2, the following

View File

@ -1302,15 +1302,15 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
{ {
byteCounter++; byteCounter++;
int next = 0; int codepointByteCount = 0;
letter = GetCodepointNext(&text[i], &next); letter = GetCodepointNext(&text[i], &codepointByteCount);
index = GetGlyphIndex(font, letter); index = GetGlyphIndex(font, letter);
i += next; i += codepointByteCount;
if (letter != '\n') if (letter != '\n')
{ {
if (font.glyphs[index].advanceX != 0) textWidth += font.glyphs[index].advanceX; if (font.glyphs[index].advanceX > 0) textWidth += font.glyphs[index].advanceX;
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX); else textWidth += (font.recs[index].width + font.glyphs[index].offsetX);
} }
else else
@ -1930,7 +1930,8 @@ int GetCodepointCount(const char *text)
const char *CodepointToUTF8(int codepoint, int *utf8Size) const char *CodepointToUTF8(int codepoint, int *utf8Size)
{ {
static char utf8[6] = { 0 }; static char utf8[6] = { 0 };
int size = 0; // Byte size of codepoint memset(utf8, 0, 6); // Clear static array
int size = 0; // Byte size of codepoint
if (codepoint <= 0x7f) if (codepoint <= 0x7f)
{ {

View File

@ -225,14 +225,6 @@
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#if defined(SUPPORT_FILEFORMAT_SVG)
#define NANOSVG_IMPLEMENTATION // Expands implementation
#include "external/nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "external/nanosvgrast.h"
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -335,84 +327,6 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
return image; return image;
} }
// Load an image from a SVG file or string with custom size
Image LoadImageSvg(const char *fileNameOrString, int width, int height)
{
Image image = { 0 };
#if defined(SUPPORT_FILEFORMAT_SVG)
bool isSvgStringValid = false;
// Validate fileName or string
if (fileNameOrString != NULL)
{
int dataSize = 0;
unsigned char *fileData = NULL;
if (FileExists(fileNameOrString))
{
fileData = LoadFileData(fileNameOrString, &dataSize);
isSvgStringValid = true;
}
else
{
// Validate fileData as valid SVG string data
//<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2484" viewBox="0 0 192.756 191.488">
if ((fileNameOrString != NULL) &&
(fileNameOrString[0] == '<') &&
(fileNameOrString[1] == 's') &&
(fileNameOrString[2] == 'v') &&
(fileNameOrString[3] == 'g'))
{
fileData = (unsigned char *)fileNameOrString;
isSvgStringValid = true;
}
}
if (isSvgStringValid)
{
struct NSVGimage *svgImage = nsvgParse((char *)fileData, "px", 96.0f);
unsigned char *img = RL_MALLOC(width*height*4);
// Calculate scales for both the width and the height
const float scaleWidth = width/svgImage->width;
const float scaleHeight = height/svgImage->height;
// Set the largest of the 2 scales to be the scale to use
const float scale = (scaleHeight > scaleWidth)? scaleWidth : scaleHeight;
int offsetX = 0;
int offsetY = 0;
if (scaleHeight > scaleWidth) offsetY = (height - svgImage->height*scale)/2;
else offsetX = (width - svgImage->width*scale)/2;
// Rasterize
struct NSVGrasterizer *rast = nsvgCreateRasterizer();
nsvgRasterize(rast, svgImage, (int)offsetX, (int)offsetY, scale, img, width, height, width*4);
// Populate image struct with all data
image.data = img;
image.width = width;
image.height = height;
image.mipmaps = 1;
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
// Free used memory
nsvgDelete(svgImage);
nsvgDeleteRasterizer(rast);
}
if (isSvgStringValid && (fileData != (unsigned char *)fileNameOrString)) UnloadFileData(fileData);
}
#else
TRACELOG(LOG_WARNING, "SVG image support not enabled, image can not be loaded");
#endif
return image;
}
// Load animated image data // Load animated image data
// - Image.data buffer includes all frames: [image#0][image#1][image#2][...] // - Image.data buffer includes all frames: [image#0][image#1][image#2][...]
// - Number of frames is returned through 'frames' parameter // - Number of frames is returned through 'frames' parameter
@ -592,44 +506,14 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
if (fileData != NULL) if (fileData != NULL)
{ {
qoi_desc desc = { 0 }; qoi_desc desc = { 0 };
image.data = qoi_decode(fileData, dataSize, &desc, 4); image.data = qoi_decode(fileData, dataSize, &desc, (int) fileData[12]);
image.width = desc.width; image.width = desc.width;
image.height = desc.height; image.height = desc.height;
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; image.format = desc.channels == 4 ? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 : PIXELFORMAT_UNCOMPRESSED_R8G8B8;
image.mipmaps = 1; image.mipmaps = 1;
} }
} }
#endif #endif
#if defined(SUPPORT_FILEFORMAT_SVG)
else if ((strcmp(fileType, ".svg") == 0) || (strcmp(fileType, ".SVG") == 0))
{
// Validate fileData as valid SVG string data
//<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2484" viewBox="0 0 192.756 191.488">
if ((fileData != NULL) &&
(fileData[0] == '<') &&
(fileData[1] == 's') &&
(fileData[2] == 'v') &&
(fileData[3] == 'g'))
{
struct NSVGimage *svgImage = nsvgParse((char *)fileData, "px", 96.0f);
unsigned char *img = RL_MALLOC(svgImage->width*svgImage->height*4);
// Rasterize
struct NSVGrasterizer *rast = nsvgCreateRasterizer();
nsvgRasterize(rast, svgImage, 0, 0, 1.0f, img, svgImage->width, svgImage->height, svgImage->width*4);
// Populate image struct with all data
image.data = img;
image.width = svgImage->width;
image.height = svgImage->height;
image.mipmaps = 1;
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
nsvgDelete(svgImage);
nsvgDeleteRasterizer(rast);
}
}
#endif
#if defined(SUPPORT_FILEFORMAT_DDS) #if defined(SUPPORT_FILEFORMAT_DDS)
else if ((strcmp(fileType, ".dds") == 0) || (strcmp(fileType, ".DDS") == 0)) else if ((strcmp(fileType, ".dds") == 0) || (strcmp(fileType, ".DDS") == 0))
{ {
@ -4988,8 +4872,6 @@ Vector3 ColorToHSV(Color color)
return hsv; return hsv;
} }
// Get a Color from HSV values // Get a Color from HSV values
// Implementation reference: https://en.wikipedia.org/wiki/HSL_and_HSV#Alternative_HSV_conversion // Implementation reference: https://en.wikipedia.org/wiki/HSL_and_HSV#Alternative_HSV_conversion
// NOTE: Color->HSV->Color conversion will not yield exactly the same color due to rounding errors // NOTE: Color->HSV->Color conversion will not yield exactly the same color due to rounding errors

View File

@ -76,7 +76,6 @@ void SetSaveFileDataCallback(SaveFileDataCallback callback) { saveFileData = cal
void SetLoadFileTextCallback(LoadFileTextCallback callback) { loadFileText = callback; } // Set custom file text loader void SetLoadFileTextCallback(LoadFileTextCallback callback) { loadFileText = callback; } // Set custom file text loader
void SetSaveFileTextCallback(SaveFileTextCallback callback) { saveFileText = callback; } // Set custom file text saver void SetSaveFileTextCallback(SaveFileTextCallback callback) { saveFileText = callback; } // Set custom file text saver
#if defined(PLATFORM_ANDROID) #if defined(PLATFORM_ANDROID)
static AAssetManager *assetManager = NULL; // Android assets manager pointer static AAssetManager *assetManager = NULL; // Android assets manager pointer
static const char *internalDataPath = NULL; // Android internal data path static const char *internalDataPath = NULL; // Android internal data path