commit
7fff975121
66 changed files with 16159 additions and 6814 deletions
|
|
@ -63,7 +63,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
|
||||
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **5.0** | [OCaml](https://ocaml.org) | MIT |
|
||||
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
|
||||
| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **5.5** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
||||
| [Ray4Laz](https://github.com/GuvaCode/Ray4Laz) | **5.5** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)/[Delphi](https://en.wikipedia.org/wiki/Delphi_(software)) | Zlib |
|
||||
| [Raylib.4.0.Pascal](https://github.com/sysrpl/Raylib.4.0.Pascal) | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
|
||||
| [pyraylib](https://github.com/Ho011/pyraylib) | 3.7 | [Python](https://www.python.org) | Zlib |
|
||||
| [raylib-python-cffi](https://github.com/electronstudio/raylib-python-cffi) | **5.5** | [Python](https://www.python.org) | EPL-2.0 |
|
||||
|
|
@ -185,4 +185,4 @@ Missing some language or wrapper? Feel free to create a new one! :)
|
|||
|
||||
Usually, raylib bindings follow the convention: `raylib-{language}`
|
||||
|
||||
Let me know if you're writing a new binding for raylib, I will list it here!
|
||||
Let me know if you're writing a new binding for raylib, I will list it here!
|
||||
|
|
|
|||
|
|
@ -393,14 +393,14 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
|||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
|
||||
|
||||
# On X11 requires also below libraries
|
||||
LDLIBS += -lX11
|
||||
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
|
||||
#LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
|
||||
# On Wayland windowing system, additional libraries requires
|
||||
# On Wayland, additional libraries requires
|
||||
ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
|
||||
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
|
||||
else
|
||||
# On X11, additional libraries required
|
||||
LDLIBS += -lX11
|
||||
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
|
||||
#LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
endif
|
||||
# Explicit link to libc
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
|
|
@ -439,15 +439,16 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
|
|||
# NOTE: Required packages: libegl1-mesa-dev
|
||||
LDLIBS = -lraylib $(SDL_LIBRARIES) -lGL -lm -lpthread -ldl -lrt
|
||||
|
||||
# On X11 requires also below libraries
|
||||
# On X11, addition libraries required
|
||||
LDLIBS += -lX11
|
||||
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
|
||||
#LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
|
||||
# On Wayland windowing system, additional libraries requires
|
||||
# On Wayland, additional libraries requires
|
||||
ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
|
||||
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
|
||||
endif
|
||||
|
||||
# Explicit link to libc
|
||||
ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
||||
LDLIBS += -lc
|
||||
|
|
@ -560,6 +561,7 @@ CORE = \
|
|||
core/core_window_flags \
|
||||
core/core_window_letterbox \
|
||||
core/core_window_should_close \
|
||||
core/core_window_web \
|
||||
core/core_world_screen
|
||||
|
||||
SHAPES = \
|
||||
|
|
@ -577,6 +579,7 @@ SHAPES = \
|
|||
shapes/shapes_easings_ball \
|
||||
shapes/shapes_easings_box \
|
||||
shapes/shapes_easings_rectangles \
|
||||
shapes/shapes_easings_testbed \
|
||||
shapes/shapes_following_eyes \
|
||||
shapes/shapes_hilbert_curve \
|
||||
shapes/shapes_kaleidoscope \
|
||||
|
|
@ -654,6 +657,8 @@ TEXT = \
|
|||
text/text_writing_anim
|
||||
|
||||
MODELS = \
|
||||
models/models_animation_blending \
|
||||
models/models_animation_bone_blending \
|
||||
models/models_animation_gpu_skinning \
|
||||
models/models_animation_playing \
|
||||
models/models_basic_voxel \
|
||||
|
|
@ -706,6 +711,7 @@ SHADERS = \
|
|||
shaders/shaders_palette_switch \
|
||||
shaders/shaders_postprocessing \
|
||||
shaders/shaders_raymarching_rendering \
|
||||
shaders/shaders_rlgl_compute \
|
||||
shaders/shaders_rounded_rectangle \
|
||||
shaders/shaders_shadowmap_rendering \
|
||||
shaders/shaders_shapes_textures \
|
||||
|
|
@ -727,14 +733,6 @@ AUDIO = \
|
|||
audio/audio_sound_positioning \
|
||||
audio/audio_spectrum_visualizer \
|
||||
audio/audio_stream_effects
|
||||
|
||||
OTHERS = \
|
||||
others/easings_testbed \
|
||||
others/embedded_files_loading \
|
||||
others/raylib_opengl_interop \
|
||||
others/rlgl_compute_shader \
|
||||
others/rlgl_standalone \
|
||||
others/web_basic_window
|
||||
#EXAMPLES_LIST_END
|
||||
|
||||
# Define processes to execute
|
||||
|
|
|
|||
|
|
@ -546,6 +546,7 @@ CORE = \
|
|||
core/core_window_flags \
|
||||
core/core_window_letterbox \
|
||||
core/core_window_should_close \
|
||||
core/core_window_web \
|
||||
core/core_world_screen
|
||||
|
||||
SHAPES = \
|
||||
|
|
@ -563,6 +564,7 @@ SHAPES = \
|
|||
shapes/shapes_easings_ball \
|
||||
shapes/shapes_easings_box \
|
||||
shapes/shapes_easings_rectangles \
|
||||
shapes/shapes_easings_testbed \
|
||||
shapes/shapes_following_eyes \
|
||||
shapes/shapes_hilbert_curve \
|
||||
shapes/shapes_kaleidoscope \
|
||||
|
|
@ -640,6 +642,8 @@ TEXT = \
|
|||
text/text_writing_anim
|
||||
|
||||
MODELS = \
|
||||
models/models_animation_blending \
|
||||
models/models_animation_bone_blending \
|
||||
models/models_animation_gpu_skinning \
|
||||
models/models_animation_playing \
|
||||
models/models_basic_voxel \
|
||||
|
|
@ -692,6 +696,7 @@ SHADERS = \
|
|||
shaders/shaders_palette_switch \
|
||||
shaders/shaders_postprocessing \
|
||||
shaders/shaders_raymarching_rendering \
|
||||
shaders/shaders_rlgl_compute \
|
||||
shaders/shaders_rounded_rectangle \
|
||||
shaders/shaders_shadowmap_rendering \
|
||||
shaders/shaders_shapes_textures \
|
||||
|
|
@ -871,6 +876,9 @@ core/core_window_letterbox: core/core_window_letterbox.c
|
|||
core/core_window_should_close: core/core_window_should_close.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_window_web: core/core_window_web.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_world_screen: core/core_world_screen.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
|
|
@ -917,6 +925,9 @@ shapes/shapes_easings_box: shapes/shapes_easings_box.c
|
|||
shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_easings_testbed: shapes/shapes_easings_testbed.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
|
|
@ -1188,6 +1199,18 @@ text/text_writing_anim: text/text_writing_anim.c
|
|||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
# Compile MODELS examples
|
||||
models/models_animation_blending: models/models_animation_blending.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file models/resources/models/gltf/robot.glb@resources/models/gltf/robot.glb \
|
||||
--preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \
|
||||
--preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs
|
||||
|
||||
models/models_animation_bone_blending: models/models_animation_bone_blending.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \
|
||||
--preload-file models/resources/shaders/glsl100/skinning.vs@resources/shaders/glsl100/skinning.vs \
|
||||
--preload-file models/resources/shaders/glsl100/skinning.fs@resources/shaders/glsl100/skinning.fs
|
||||
|
||||
models/models_animation_gpu_skinning: models/models_animation_gpu_skinning.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file models/resources/models/gltf/greenman.glb@resources/models/gltf/greenman.glb \
|
||||
|
|
@ -1461,6 +1484,9 @@ shaders/shaders_raymarching_rendering: shaders/shaders_raymarching_rendering.c
|
|||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file shaders/resources/shaders/glsl100/raymarching.fs@resources/shaders/glsl100/raymarching.fs
|
||||
|
||||
shaders/shaders_rlgl_compute: shaders/shaders_rlgl_compute.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shaders/shaders_rounded_rectangle: shaders/shaders_rounded_rectangle.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file shaders/resources/shaders/glsl100/base.vs@resources/shaders/glsl100/base.vs \
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ You may find it easier to use than other toolchains, especially when it comes to
|
|||
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
|
||||
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
|
||||
|
||||
## EXAMPLES COLLECTION [TOTAL: 208]
|
||||
## EXAMPLES COLLECTION [TOTAL: 207]
|
||||
|
||||
### category: core [48]
|
||||
### category: core [49]
|
||||
|
||||
Examples using raylib [core](../src/rcore.c) module platform functionality: window creation, inputs, drawing modes and system functionality.
|
||||
|
||||
|
|
@ -73,8 +73,9 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
|||
| [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
|
||||
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_keyboard_testbed](core/core_keyboard_testbed.c) | <img src="core/core_keyboard_testbed.png" alt="core_keyboard_testbed" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_window_web](core/core_window_web.c) | <img src="core/core_window_web.png" alt="core_window_web" width="80"> | ⭐☆☆☆ | 1.3 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
|
||||
### category: shapes [39]
|
||||
### category: shapes [40]
|
||||
|
||||
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
|
||||
|
||||
|
|
@ -119,6 +120,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
|||
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [shapes_hilbert_curve](shapes/shapes_hilbert_curve.c) | <img src="shapes/shapes_hilbert_curve.png" alt="shapes_hilbert_curve" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
||||
| [shapes_easings_testbed](shapes/shapes_easings_testbed.c) | <img src="shapes/shapes_easings_testbed.png" alt="shapes_easings_testbed" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||
|
||||
### category: textures [30]
|
||||
|
||||
|
|
@ -180,7 +182,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
|||
| [text_words_alignment](text/text_words_alignment.c) | <img src="text/text_words_alignment.png" alt="text_words_alignment" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [text_strings_management](text/text_strings_management.c) | <img src="text/text_strings_management.png" alt="text_strings_management" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
|
||||
### category: models [27]
|
||||
### category: models [29]
|
||||
|
||||
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
|
||||
|
||||
|
|
@ -213,8 +215,10 @@ Examples using raylib models functionality, including models loading/generation
|
|||
| [models_rotating_cube](models/models_rotating_cube.c) | <img src="models/models_rotating_cube.png" alt="models_rotating_cube" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
||||
| [models_decals](models/models_decals.c) | <img src="models/models_decals.png" alt="models_decals" width="80"> | ⭐⭐⭐⭐️ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [models_directional_billboard](models/models_directional_billboard.c) | <img src="models/models_directional_billboard.png" alt="models_directional_billboard" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [models_animation_bone_blending](models/models_animation_bone_blending.c) | <img src="models/models_animation_bone_blending.png" alt="models_animation_bone_blending" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.5 | [dmitrii-brand](https://github.com/dmitrii-brand) |
|
||||
| [models_animation_blending](models/models_animation_blending.c) | <img src="models/models_animation_blending.png" alt="models_animation_blending" width="80"> | ☆☆☆☆ | 5.5 | 5.6-dev | [Kirandeep](https://github.com/Kirandeep-Singh-Khehra) |
|
||||
|
||||
### category: shaders [33]
|
||||
### category: shaders [34]
|
||||
|
||||
Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module.
|
||||
|
||||
|
|
@ -253,6 +257,7 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
|||
| [shaders_rounded_rectangle](shaders/shaders_rounded_rectangle.c) | <img src="shaders/shaders_rounded_rectangle.png" alt="shaders_rounded_rectangle" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) |
|
||||
| [shaders_depth_rendering](shaders/shaders_depth_rendering.c) | <img src="shaders/shaders_depth_rendering.png" alt="shaders_depth_rendering" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) |
|
||||
| [shaders_game_of_life](shaders/shaders_game_of_life.c) | <img src="shaders/shaders_game_of_life.png" alt="shaders_game_of_life" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
| [shaders_rlgl_compute](shaders/shaders_rlgl_compute.c) | <img src="shaders/shaders_rlgl_compute.png" alt="shaders_rlgl_compute" width="80"> | ⭐⭐⭐⭐️ | 4.0 | 4.0 | [Teddy Astie](https://github.com/tsnake41) |
|
||||
|
||||
### category: audio [9]
|
||||
|
||||
|
|
@ -270,18 +275,5 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
|||
| [audio_sound_positioning](audio/audio_sound_positioning.c) | <img src="audio/audio_sound_positioning.png" alt="audio_sound_positioning" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
|
||||
| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | <img src="audio/audio_spectrum_visualizer.png" alt="audio_spectrum_visualizer" width="80"> | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) |
|
||||
|
||||
### category: others [6]
|
||||
|
||||
Examples showing raylib misc functionality that does not fit in other categories, like standalone modules usage or examples integrating external libraries.
|
||||
|
||||
| example | image | difficulty<br>level | version<br>created | last version<br>updated | original<br>developer |
|
||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||
| [rlgl_standalone](others/rlgl_standalone.c) | <img src="others/rlgl_standalone.png" alt="rlgl_standalone" width="80"> | ⭐⭐⭐⭐️ | 1.6 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [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) |
|
||||
| [easings_testbed](others/easings_testbed.c) | <img src="others/easings_testbed.png" alt="easings_testbed" width="80"> | ⭐⭐⭐☆ | 2.5 | 3.0 | [Juan Miguel López](https://github.com/flashback-fx) |
|
||||
| [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐⭐⭐⭐️ | 3.8 | 4.0 | [Stephan Soller](https://github.com/arkanis) |
|
||||
| [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐⭐☆☆ | 3.0 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
|
||||
| [web_basic_window](others/web_basic_window.c) | <img src="others/web_basic_window.png" alt="web_basic_window" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
|
||||
Some example missing? As always, contributions are welcome, feel free to send new examples!
|
||||
Here is an [examples template](examples_template.c) with instructions to start with!
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ int main(void)
|
|||
.z = 5.0f*sinf(th)
|
||||
};
|
||||
|
||||
SetSoundPosition(camera, sound, spherePos, 20.0f);
|
||||
SetSoundPosition(camera, sound, spherePos, 1.0f);
|
||||
|
||||
if (!IsSoundPlaying(sound)) PlaySound(sound);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -148,10 +148,11 @@ int main(void)
|
|||
DrawText("Controls:", 20, 20, 10, BLACK);
|
||||
DrawText("- Right/Left to move", 40, 40, 10, DARKGRAY);
|
||||
DrawText("- Space to jump", 40, 60, 10, DARKGRAY);
|
||||
DrawText("- Mouse Wheel to Zoom in-out, R to reset zoom", 40, 80, 10, DARKGRAY);
|
||||
DrawText("- C to change camera mode", 40, 100, 10, DARKGRAY);
|
||||
DrawText("Current camera mode:", 20, 120, 10, BLACK);
|
||||
DrawText(cameraDescriptions[cameraOption], 40, 140, 10, DARKGRAY);
|
||||
DrawText("- Mouse Wheel to Zoom in-out", 40, 80, 10, DARKGRAY);
|
||||
DrawText("- R to reset position + zoom", 40, 100, 10, DARKGRAY);
|
||||
DrawText("- C to change camera mode", 40, 120, 10, DARKGRAY);
|
||||
DrawText("Current camera mode:", 20, 140, 10, BLACK);
|
||||
DrawText(cameraDescriptions[cameraOption], 40, 160, 10, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -37,10 +37,18 @@ int main(void)
|
|||
char directory[MAX_FILEPATH_SIZE] = { 0 };
|
||||
strcpy(directory, GetWorkingDirectory());
|
||||
|
||||
FilePathList files = LoadDirectoryFiles(directory);
|
||||
// Load file-paths on current working directory
|
||||
// NOTE: LoadDirectoryFiles() loads files and directories by default,
|
||||
// use LoadDirectoryFilesEx() for custom filters and recursive directories loading
|
||||
//FilePathList files = LoadDirectoryFiles(directory);
|
||||
FilePathList files = LoadDirectoryFilesEx(directory, ".png;.c", false);
|
||||
|
||||
int btnBackPressed = false;
|
||||
|
||||
int listScrollIndex = 0;
|
||||
int listItemActive = -1;
|
||||
int listItemFocused = -1;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -62,10 +70,18 @@ int main(void)
|
|||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText(directory, 100, 40, 20, DARKGRAY);
|
||||
btnBackPressed = GuiButton((Rectangle){ 40.0f, 10.0f, 48, 28 }, "<");
|
||||
|
||||
btnBackPressed = GuiButton((Rectangle){ 40.0f, 38.0f, 48, 24 }, "<");
|
||||
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize*2);
|
||||
GuiLabel((Rectangle){ 40 + 48 + 10, 10, 700, 28 }, directory);
|
||||
GuiSetStyle(DEFAULT, TEXT_SIZE, GuiGetFont().baseSize);
|
||||
|
||||
GuiSetStyle(LISTVIEW, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
|
||||
GuiSetStyle(LISTVIEW, TEXT_PADDING, 40);
|
||||
GuiListViewEx((Rectangle){ 0, 50, GetScreenWidth(), GetScreenHeight() - 50 },
|
||||
files.paths, files.count, &listScrollIndex, &listItemActive, &listItemFocused);
|
||||
|
||||
/*
|
||||
for (int i = 0; i < (int)files.count; i++)
|
||||
{
|
||||
Color color = Fade(LIGHTGRAY, 0.3f);
|
||||
|
|
@ -84,6 +100,7 @@ int main(void)
|
|||
DrawRectangle(0, 85 + 40*i, screenWidth, 40, color);
|
||||
DrawText(GetFileName(files.paths[i]), 120, 100 + 40*i, 10, GRAY);
|
||||
}
|
||||
*/
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ int main(void)
|
|||
DrawText(TextFormat("WINDOW POSITION: %ix%i", (int)windowPos.x, (int)windowPos.y), 50, 90, 20, DARKGRAY);
|
||||
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 130, 20, DARKGRAY);
|
||||
DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 170, 20, DARKGRAY);
|
||||
DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY);
|
||||
DrawText(TextFormat("SCALE FACTOR: %.2fx%.2f", scaleDpi.x, scaleDpi.y), 50, 210, 20, GRAY);
|
||||
|
||||
// Draw reference rectangles, top-left and bottom-right corners
|
||||
DrawRectangle(0, 0, 30, 60, RED);
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ int main(void)
|
|||
|
||||
DrawRectangleV(position, size, releaseAction? BLUE : RED);
|
||||
|
||||
DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE);
|
||||
DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Arrow keys", 10, 10, 20, WHITE);
|
||||
DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN);
|
||||
|
||||
EndDrawing();
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@
|
|||
// NOTE: Gamepad name ID depends on drivers and OS
|
||||
#define XBOX_ALIAS_1 "xbox"
|
||||
#define XBOX_ALIAS_2 "x-box"
|
||||
#define PS_ALIAS "playstation"
|
||||
#define PS_ALIAS_1 "playstation"
|
||||
#define PS_ALIAS_2 "sony"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
|
|
@ -148,7 +149,8 @@ int main(void)
|
|||
//DrawText(TextFormat("Xbox axis LT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK);
|
||||
//DrawText(TextFormat("Xbox axis RT: %02.02f", GetGamepadAxisMovement(gamepad, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK);
|
||||
}
|
||||
else if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), PS_ALIAS) > -1)
|
||||
else if ((TextFindIndex(TextToLower(GetGamepadName(gamepad)), PS_ALIAS_1) > -1) ||
|
||||
(TextFindIndex(TextToLower(GetGamepadName(gamepad)), PS_ALIAS_2) > -1))
|
||||
{
|
||||
DrawTexture(texPs3Pad, 0, 0, DARKGRAY);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,11 +51,31 @@ int main(void)
|
|||
{ padPosition.x, padPosition.y + buttonRadius*1.5f } // Down
|
||||
};
|
||||
|
||||
const char *buttonLabels[BUTTON_MAX] = {
|
||||
"Y", // Up
|
||||
"X", // Left
|
||||
"B", // Right
|
||||
"A" // Down
|
||||
Vector2 arrowTris[4][3] = {
|
||||
// Up
|
||||
{
|
||||
{ buttonPositions[0].x, buttonPositions[0].y - 12 },
|
||||
{ buttonPositions[0].x - 9, buttonPositions[0].y + 9 },
|
||||
{ buttonPositions[0].x + 9, buttonPositions[0].y + 9 }
|
||||
},
|
||||
// Left
|
||||
{
|
||||
{ buttonPositions[1].x + 9, buttonPositions[1].y - 9 },
|
||||
{ buttonPositions[1].x - 12, buttonPositions[1].y },
|
||||
{ buttonPositions[1].x + 9, buttonPositions[1].y + 9 }
|
||||
},
|
||||
// Right
|
||||
{
|
||||
{ buttonPositions[2].x + 12, buttonPositions[2].y },
|
||||
{ buttonPositions[2].x - 9, buttonPositions[2].y - 9 },
|
||||
{ buttonPositions[2].x - 9, buttonPositions[2].y + 9 }
|
||||
},
|
||||
// Down
|
||||
{
|
||||
{ buttonPositions[3].x - 9, buttonPositions[3].y - 9 },
|
||||
{ buttonPositions[3].x, buttonPositions[3].y + 12 },
|
||||
{ buttonPositions[3].x + 9, buttonPositions[3].y - 9 }
|
||||
}
|
||||
};
|
||||
|
||||
Color buttonLabelColors[BUTTON_MAX] = {
|
||||
|
|
@ -128,9 +148,12 @@ int main(void)
|
|||
{
|
||||
DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton)? DARKGRAY : BLACK);
|
||||
|
||||
DrawText(buttonLabels[i],
|
||||
(int)buttonPositions[i].x - 7, (int)buttonPositions[i].y - 8,
|
||||
20, buttonLabelColors[i]);
|
||||
DrawTriangle(
|
||||
arrowTris[i][0],
|
||||
arrowTris[i][1],
|
||||
arrowTris[i][2],
|
||||
buttonLabelColors[i]
|
||||
);
|
||||
}
|
||||
|
||||
DrawText("move the player with D-Pad buttons", 10, 10, 20, DARKGRAY);
|
||||
|
|
|
|||
|
|
@ -96,8 +96,6 @@ int main(void)
|
|||
{
|
||||
DrawRectangleRec(rectangles[i].rect, rectangles[i].color);
|
||||
|
||||
DrawText("Press SPACE to shuffle the sequence", 10, screenHeight - 96, 20, BLACK);
|
||||
|
||||
DrawText("Press SPACE to shuffle the current sequence", 10, screenHeight - 96, 20, BLACK);
|
||||
DrawText("Press UP to add a rectangle and generate a new sequence", 10, screenHeight - 64, 20, BLACK);
|
||||
DrawText("Press DOWN to remove a rectangle and generate a new sequence", 10, screenHeight - 32, 20, BLACK);
|
||||
|
|
|
|||
86
examples/core/core_window_web.c
Normal file
86
examples/core/core_window_web.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - window web
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 5.5
|
||||
*
|
||||
* This example has been adapted to compile for PLATFORM_WEB and PLATFORM_DESKTOP
|
||||
* As you will notice, code structure is slightly different to the other examples
|
||||
*
|
||||
* 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) 2015-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void UpdateDrawFrame(void); // Update and Draw one frame
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//----------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - window web");
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
UpdateDrawFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("Welcome to raylib web structure!", 220, 200, 20, SKYBLUE);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
BIN
examples/core/core_window_web.png
Normal file
BIN
examples/core/core_window_web.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
File diff suppressed because it is too large
Load diff
|
|
@ -57,6 +57,7 @@ core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Anan
|
|||
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
|
||||
core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_keyboard_testbed;★★☆☆;5.6;5.6;2026;2026;"Ramon Santamaria";@raysan5
|
||||
core;core_window_web;★☆☆☆;1.3;5.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
|
||||
shapes;shapes_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
|
||||
shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower
|
||||
|
|
@ -96,6 +97,7 @@ shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@Robi
|
|||
shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||
shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||
shapes;shapes_hilbert_curve;★★★☆;5.6;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
||||
shapes;shapes_easings_testbed;★★★☆;2.5;2.5;2019;2025;"Juan Miguel López";@flashback-fx
|
||||
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
||||
|
|
@ -169,6 +171,8 @@ models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle
|
|||
models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||
models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
||||
models;models_animation_bone_blending;★★★★;5.5;5.5;2026;2026;"dmitrii-brand";@dmitrii-brand
|
||||
models;models_animation_blending;☆☆☆☆;5.5;5.6-dev;2024;2024;"Kirandeep";@Kirandeep-Singh-Khehra
|
||||
shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
|
||||
shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
|
||||
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
|
||||
|
|
@ -202,6 +206,7 @@ shaders;shaders_lightmap_rendering;★★★☆;4.5;4.5;2019;2025;"Jussi Viitala
|
|||
shaders;shaders_rounded_rectangle;★★★☆;5.5;5.5;2025;2025;"Anstro Pleuton";@anstropleuton
|
||||
shaders;shaders_depth_rendering;★★★☆;5.6-dev;5.6-dev;2025;2025;"Luís Almeida";@luis605
|
||||
shaders;shaders_game_of_life;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
shaders;shaders_rlgl_compute;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
||||
audio;audio_module_playing;★☆☆☆;1.5;3.5;2016;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_music_stream;★☆☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_raw_stream;★★★☆;1.6;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
|
|
@ -211,9 +216,3 @@ audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@ra
|
|||
audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501
|
||||
audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71
|
||||
audio;audio_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4
|
||||
others;rlgl_standalone;★★★★;1.6;4.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
others;rlgl_compute_shader;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
||||
others;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flashback-fx
|
||||
others;raylib_opengl_interop;★★★★;3.8;4.0;2021;2025;"Stephan Soller";@arkanis
|
||||
others;embedded_files_loading;★★☆☆;3.0;3.5;2020;2025;"Kristian Holmgren";@defutura
|
||||
others;web_basic_window;★☆☆☆;5.6-dev;5.6-dev;2014;2025;"Ramon Santamaria";@raysan5
|
||||
|
|
|
|||
152
examples/models/models_animation_blending.c
Normal file
152
examples/models/models_animation_blending.c
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - animation blending
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
|
||||
*
|
||||
* Example contributed by Kirandeep (@Kirandeep-Singh-Khehra)
|
||||
*
|
||||
* 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 Kirandeep (@Kirandeep-Singh-Khehra)
|
||||
*
|
||||
* Note: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS
|
||||
* Note: This example uses CPU for updating meshes.
|
||||
* For GPU skinning see comments with 'INFO:'.
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define clamp(x,a,b) ((x < a)? a : (x > b)? b : x)
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - animation blending");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 8.0f, 8.0f, 8.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
// Load gltf model
|
||||
Model characterModel = LoadModel("resources/models/gltf/robot.glb"); // Load character model
|
||||
|
||||
/* INFO: Uncomment this to use GPU skinning
|
||||
// Load skinning shader
|
||||
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||
|
||||
for (int i = 0; i < characterModel.materialCount; i++)
|
||||
{
|
||||
characterModel.materials[i].shader = skinningShader;
|
||||
}
|
||||
*/
|
||||
|
||||
// Load gltf model animations
|
||||
int animsCount = 0;
|
||||
unsigned int animIndex0 = 0;
|
||||
unsigned int animIndex1 = 0;
|
||||
unsigned int animCurrentFrame = 0;
|
||||
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/robot.glb", &animsCount);
|
||||
|
||||
float blendFactor = 0.5f;
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||
|
||||
// Select current animation
|
||||
if (IsKeyPressed(KEY_T)) animIndex0 = (animIndex0 + 1)%animsCount;
|
||||
else if (IsKeyPressed(KEY_G)) animIndex0 = (animIndex0 + animsCount - 1)%animsCount;
|
||||
if (IsKeyPressed(KEY_Y)) animIndex1 = (animIndex1 + 1)%animsCount;
|
||||
else if (IsKeyPressed(KEY_H)) animIndex1 = (animIndex1 + animsCount - 1)%animsCount;
|
||||
|
||||
// Select blend factor
|
||||
if (IsKeyPressed(KEY_U)) blendFactor = clamp(blendFactor - 0.1, 0.0f, 1.0f);
|
||||
else if (IsKeyPressed(KEY_J)) blendFactor = clamp(blendFactor + 0.1, 0.0f, 1.0f);
|
||||
|
||||
// Update animation
|
||||
animCurrentFrame++;
|
||||
|
||||
// Update bones
|
||||
// Note: Same animation frame index is used below. By default it loops both animations
|
||||
UpdateModelAnimationBonesLerp(characterModel, modelAnimations[animIndex0], animCurrentFrame, modelAnimations[animIndex1], animCurrentFrame, blendFactor);
|
||||
|
||||
// INFO: Comment the following line to use GPU skinning
|
||||
UpdateModelVertsToCurrentBones(characterModel);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
/* INFO: Uncomment this to use GPU skinning
|
||||
// Draw character mesh, pose calculation is done in shader (GPU skinning)
|
||||
for (int i = 0; i < characterModel.meshCount; i++)
|
||||
{
|
||||
DrawMesh(characterModel.meshes[i], characterModel.materials[characterModel.meshMaterial[i]], characterModel.transform);
|
||||
}
|
||||
*/
|
||||
|
||||
// INFO: Comment the following line to use GPU skinning
|
||||
DrawModel(characterModel, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
|
||||
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Use the U/J to adjust blend factor", 10, 10, 20, GRAY);
|
||||
DrawText("Use the T/G to switch first animation", 10, 30, 20, GRAY);
|
||||
DrawText("Use the Y/H to switch second animation", 10, 50, 20, GRAY);
|
||||
DrawText(TextFormat("Animations: %s, %s", modelAnimations[animIndex0].name, modelAnimations[animIndex1].name), 10, 70, 20, BLACK);
|
||||
DrawText(TextFormat("Blend Factor: %f", blendFactor), 10, 86, 20, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModelAnimations(modelAnimations, animsCount); // Unload model animation
|
||||
UnloadModel(characterModel); // Unload model and meshes/material
|
||||
|
||||
// INFO: Uncomment the following line to use GPU skinning
|
||||
// UnloadShader(skinningShader); // Unload GPU skinning shader
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/models/models_animation_blending.png
Normal file
BIN
examples/models/models_animation_blending.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
296
examples/models/models_animation_bone_blending.c
Normal file
296
examples/models/models_animation_bone_blending.c
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - animation bone blending
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* This example demonstrates per-bone animation blending, allowing smooth transitions
|
||||
* between two animations by interpolating bone transforms. This is useful for:
|
||||
* - Blending movement animations (walk/run) with action animations (jump/attack)
|
||||
* - Creating smooth animation transitions
|
||||
* - Layering animations (e.g., upper body attack while lower body walks)
|
||||
*
|
||||
* Example contributed by dmitrii-brand (@dmitrii-brand) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* NOTE: Due to limitations in the Apple OpenGL driver, this feature does not work on MacOS
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2026 dmitrii-brand (@dmitrii-brand)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
#include <string.h> // Required for: memcpy()
|
||||
#include <stdlib.h> // Required for: NULL
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static bool IsUpperBodyBone(const char *boneName);
|
||||
static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int frame1,
|
||||
ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - animation bone blending");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 2.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
// Load gltf model
|
||||
Model characterModel = LoadModel("resources/models/gltf/greenman.glb");
|
||||
|
||||
// Load skinning shader
|
||||
Shader skinningShader = LoadShader(TextFormat("resources/shaders/glsl%i/skinning.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/skinning.fs", GLSL_VERSION));
|
||||
|
||||
characterModel.materials[1].shader = skinningShader;
|
||||
|
||||
// Load gltf model animations
|
||||
int animsCount = 0;
|
||||
ModelAnimation *modelAnimations = LoadModelAnimations("resources/models/gltf/greenman.glb", &animsCount);
|
||||
|
||||
// Log all available animations for debugging
|
||||
TraceLog(LOG_INFO, "Found %d animations:", animsCount);
|
||||
for (int i = 0; i < animsCount; i++)
|
||||
{
|
||||
TraceLog(LOG_INFO, " Animation %d: %s (%d frames)", i, modelAnimations[i].name, modelAnimations[i].frameCount);
|
||||
}
|
||||
|
||||
// Use specific indices: walk/move = 2, attack = 3
|
||||
unsigned int animIndex1 = 2; // Walk/Move animation (index 2)
|
||||
unsigned int animIndex2 = 3; // Attack animation (index 3)
|
||||
unsigned int animCurrentFrame1 = 0;
|
||||
unsigned int animCurrentFrame2 = 0;
|
||||
|
||||
// Validate indices
|
||||
if (animIndex1 >= animsCount) animIndex1 = 0;
|
||||
if (animIndex2 >= animsCount) animIndex2 = (animsCount > 1) ? 1 : 0;
|
||||
|
||||
TraceLog(LOG_INFO, "Using Walk (index %d): %s", animIndex1, modelAnimations[animIndex1].name);
|
||||
TraceLog(LOG_INFO, "Using Attack (index %d): %s", animIndex2, modelAnimations[animIndex2].name);
|
||||
|
||||
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
bool upperBodyBlend = true; // Toggle: true = upper/lower body blending, false = uniform blending (50/50)
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||
|
||||
// Toggle upper/lower body blending mode (SPACE key)
|
||||
if (IsKeyPressed(KEY_SPACE)) upperBodyBlend = !upperBodyBlend;
|
||||
|
||||
// Update animation frames
|
||||
ModelAnimation anim1 = modelAnimations[animIndex1];
|
||||
ModelAnimation anim2 = modelAnimations[animIndex2];
|
||||
|
||||
animCurrentFrame1 = (animCurrentFrame1 + 1)%anim1.frameCount;
|
||||
animCurrentFrame2 = (animCurrentFrame2 + 1)%anim2.frameCount;
|
||||
|
||||
// Blend the two animations
|
||||
characterModel.transform = MatrixTranslate(position.x, position.y, position.z);
|
||||
// When upperBodyBlend is ON: upper body = attack (1.0), lower body = walk (0.0)
|
||||
// When upperBodyBlend is OFF: uniform blend at 0.5 (50% walk, 50% attack)
|
||||
float blendFactor = upperBodyBlend ? 1.0f : 0.5f;
|
||||
BlendModelAnimationsBones(&characterModel, &anim1, animCurrentFrame1, &anim2, animCurrentFrame2, blendFactor, upperBodyBlend);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
// Draw character mesh, pose calculation is done in shader (GPU skinning)
|
||||
DrawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
// Draw UI
|
||||
DrawText("BONE BLENDING EXAMPLE", 10, 10, 20, DARKGRAY);
|
||||
DrawText(TextFormat("Walk (Animation 2): %s", anim1.name), 10, 35, 10, GRAY);
|
||||
DrawText(TextFormat("Attack (Animation 3): %s", anim2.name), 10, 50, 10, GRAY);
|
||||
DrawText(TextFormat("Mode: %s", upperBodyBlend ? "Upper/Lower Body Blending" : "Uniform Blending"), 10, 65, 10, GRAY);
|
||||
DrawText("SPACE - Toggle blending mode", 10, GetScreenHeight() - 20, 10, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModelAnimations(modelAnimations, animsCount); // Unload model animation
|
||||
UnloadModel(characterModel); // Unload model and meshes/material
|
||||
UnloadShader(skinningShader); // Unload GPU skinning shader
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Check if a bone is part of upper body (for selective blending)
|
||||
static bool IsUpperBodyBone(const char *boneName)
|
||||
{
|
||||
// Common upper body bone names (adjust based on your model)
|
||||
if (TextIsEqual(boneName, "spine") || TextIsEqual(boneName, "spine1") || TextIsEqual(boneName, "spine2") ||
|
||||
TextIsEqual(boneName, "chest") || TextIsEqual(boneName, "upperChest") ||
|
||||
TextIsEqual(boneName, "neck") || TextIsEqual(boneName, "head") ||
|
||||
TextIsEqual(boneName, "shoulder") || TextIsEqual(boneName, "shoulder_L") || TextIsEqual(boneName, "shoulder_R") ||
|
||||
TextIsEqual(boneName, "upperArm") || TextIsEqual(boneName, "upperArm_L") || TextIsEqual(boneName, "upperArm_R") ||
|
||||
TextIsEqual(boneName, "lowerArm") || TextIsEqual(boneName, "lowerArm_L") || TextIsEqual(boneName, "lowerArm_R") ||
|
||||
TextIsEqual(boneName, "hand") || TextIsEqual(boneName, "hand_L") || TextIsEqual(boneName, "hand_R") ||
|
||||
TextIsEqual(boneName, "clavicle") || TextIsEqual(boneName, "clavicle_L") || TextIsEqual(boneName, "clavicle_R"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if bone name contains upper body keywords
|
||||
if (strstr(boneName, "spine") != NULL || strstr(boneName, "chest") != NULL ||
|
||||
strstr(boneName, "neck") != NULL || strstr(boneName, "head") != NULL ||
|
||||
strstr(boneName, "shoulder") != NULL || strstr(boneName, "arm") != NULL ||
|
||||
strstr(boneName, "hand") != NULL || strstr(boneName, "clavicle") != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Blend two animations per-bone with selective upper/lower body blending
|
||||
static void BlendModelAnimationsBones(Model *model, ModelAnimation *anim1, int frame1,
|
||||
ModelAnimation *anim2, int frame2, float blendFactor, bool upperBodyBlend)
|
||||
{
|
||||
// Validate inputs
|
||||
if (anim1->boneCount == 0 || anim1->framePoses == NULL ||
|
||||
anim2->boneCount == 0 || anim2->framePoses == NULL ||
|
||||
model->boneCount == 0 || model->bindPose == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Clamp blend factor to [0, 1]
|
||||
blendFactor = fminf(1.0f, fmaxf(0.0f, blendFactor));
|
||||
|
||||
// Ensure frame indices are valid
|
||||
if (frame1 >= anim1->frameCount) frame1 = anim1->frameCount - 1;
|
||||
if (frame2 >= anim2->frameCount) frame2 = anim2->frameCount - 1;
|
||||
if (frame1 < 0) frame1 = 0;
|
||||
if (frame2 < 0) frame2 = 0;
|
||||
|
||||
// Find first mesh with bones
|
||||
int firstMeshWithBones = -1;
|
||||
for (int i = 0; i < model->meshCount; i++)
|
||||
{
|
||||
if (model->meshes[i].boneMatrices)
|
||||
{
|
||||
firstMeshWithBones = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstMeshWithBones == -1) return;
|
||||
|
||||
// Get bone count (use minimum of all to be safe)
|
||||
int boneCount = model->boneCount;
|
||||
if (anim1->boneCount < boneCount) boneCount = anim1->boneCount;
|
||||
if (anim2->boneCount < boneCount) boneCount = anim2->boneCount;
|
||||
|
||||
// Blend each bone
|
||||
for (int boneId = 0; boneId < boneCount; boneId++)
|
||||
{
|
||||
// Determine blend factor for this bone
|
||||
float boneBlendFactor = blendFactor;
|
||||
|
||||
// If upper body blending is enabled, use different blend factors for upper vs lower body
|
||||
if (upperBodyBlend)
|
||||
{
|
||||
const char *boneName = model->bones[boneId].name;
|
||||
bool isUpperBody = IsUpperBodyBone(boneName);
|
||||
|
||||
// Upper body: use anim2 (attack), Lower body: use anim1 (walk)
|
||||
// blendFactor = 0.0 means full anim1 (walk), 1.0 means full anim2 (attack)
|
||||
if (isUpperBody) boneBlendFactor = blendFactor; // Upper body: blend towards anim2 (attack)
|
||||
else boneBlendFactor = 1.0f - blendFactor; // Lower body: blend towards anim1 (walk) - invert the blend
|
||||
}
|
||||
|
||||
// Get transforms from both animations
|
||||
Transform *bindTransform = &model->bindPose[boneId];
|
||||
Transform *anim1Transform = &anim1->framePoses[frame1][boneId];
|
||||
Transform *anim2Transform = &anim2->framePoses[frame2][boneId];
|
||||
|
||||
// Blend the transforms
|
||||
Transform blended;
|
||||
blended.translation = Vector3Lerp(anim1Transform->translation, anim2Transform->translation, boneBlendFactor);
|
||||
blended.rotation = QuaternionSlerp(anim1Transform->rotation, anim2Transform->rotation, boneBlendFactor);
|
||||
blended.scale = Vector3Lerp(anim1Transform->scale, anim2Transform->scale, boneBlendFactor);
|
||||
|
||||
// Convert bind pose to matrix
|
||||
Matrix bindMatrix = MatrixMultiply(MatrixMultiply(
|
||||
MatrixScale(bindTransform->scale.x, bindTransform->scale.y, bindTransform->scale.z),
|
||||
QuaternionToMatrix(bindTransform->rotation)),
|
||||
MatrixTranslate(bindTransform->translation.x, bindTransform->translation.y, bindTransform->translation.z));
|
||||
|
||||
// Convert blended transform to matrix
|
||||
Matrix blendedMatrix = MatrixMultiply(MatrixMultiply(
|
||||
MatrixScale(blended.scale.x, blended.scale.y, blended.scale.z),
|
||||
QuaternionToMatrix(blended.rotation)),
|
||||
MatrixTranslate(blended.translation.x, blended.translation.y, blended.translation.z));
|
||||
|
||||
// Calculate final bone matrix (similar to UpdateModelAnimationBones)
|
||||
model->meshes[firstMeshWithBones].boneMatrices[boneId] = MatrixMultiply(MatrixInvert(bindMatrix), blendedMatrix);
|
||||
}
|
||||
|
||||
// Copy bone matrices to remaining meshes
|
||||
for (int i = firstMeshWithBones + 1; i < model->meshCount; i++)
|
||||
{
|
||||
if (model->meshes[i].boneMatrices)
|
||||
{
|
||||
memcpy(model->meshes[i].boneMatrices,
|
||||
model->meshes[firstMeshWithBones].boneMatrices,
|
||||
model->meshes[i].boneCount*sizeof(model->meshes[i].boneMatrices[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
#define WORLD_SIZE 8 // Size of our voxel world (8x8x8 cubes)
|
||||
|
|
@ -32,7 +33,7 @@ int main(void)
|
|||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - basic voxel");
|
||||
|
||||
DisableCursor(); // Lock mouse to window center
|
||||
DisableCursor(); // Lock mouse to window center
|
||||
|
||||
// Define the camera to look into our 3d world (first person)
|
||||
Camera3D camera = { 0 };
|
||||
|
|
@ -59,7 +60,7 @@ int main(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ int main(void)
|
|||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
// Cast a ray from the screen center (where crosshair would be)
|
||||
Vector2 screenCenter = { screenWidth/2.0f, screenHeight/2.0f };
|
||||
Vector2 screenCenter = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||
Ray ray = GetMouseRay(screenCenter, camera);
|
||||
|
||||
// Check ray collision with all voxels
|
||||
|
|
@ -132,8 +133,11 @@ int main(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EndMode3D();
|
||||
|
||||
// Draw reference point for raycasting to delete blocks
|
||||
DrawCircle(GetRenderWidth()/2, GetScreenHeight()/2, 4, RED);
|
||||
|
||||
DrawText("Left-click a voxel to remove it!", 10, 10, 20, DARKGRAY);
|
||||
DrawText("WASD to move, mouse to look around", 10, 35, 10, GRAY);
|
||||
|
|
@ -145,6 +149,7 @@ int main(void)
|
|||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadModel(cubeModel);
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue