Merge branch 'master' into master
4
.github/workflows/analyze_codeql.yml
vendored
|
|
@ -71,7 +71,7 @@ jobs:
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
|
@ -90,7 +90,7 @@ jobs:
|
||||||
cmake --build . --config $BUILD_TYPE
|
cmake --build . --config $BUILD_TYPE
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
with:
|
with:
|
||||||
category: "/language:${{matrix.language}}"
|
category: "/language:${{matrix.language}}"
|
||||||
upload: false
|
upload: false
|
||||||
|
|
|
||||||
8
.github/workflows/parse_api.yml
vendored
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Update parse files
|
- name: Update parse files
|
||||||
working-directory: tools/parser
|
working-directory: tools/rlparser
|
||||||
run: |
|
run: |
|
||||||
make raylib_api
|
make raylib_api
|
||||||
mv raylib_api.* output
|
mv raylib_api.* output
|
||||||
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
- name: Diff parse files
|
- name: Diff parse files
|
||||||
id: diff
|
id: diff
|
||||||
run: |
|
run: |
|
||||||
git add -N parser
|
git add -N tools/rlparser
|
||||||
git diff --name-only --exit-code
|
git diff --name-only --exit-code
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
|
|
@ -32,6 +32,6 @@ jobs:
|
||||||
set -x
|
set -x
|
||||||
git config user.name "github-actions[bot]"
|
git config user.name "github-actions[bot]"
|
||||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
git add tools/parser
|
git add tools/rlparser
|
||||||
git commit -m "Update raylib_api.* by CI"
|
git commit -m "rlparser: update raylib_api.* by CI"
|
||||||
git push
|
git push
|
||||||
|
|
|
||||||
3
.gitignore
vendored
|
|
@ -55,6 +55,8 @@ packages/
|
||||||
*.so
|
*.so
|
||||||
*.so.*
|
*.so.*
|
||||||
*.dll
|
*.dll
|
||||||
|
*.h.pch
|
||||||
|
./*.obj
|
||||||
|
|
||||||
# Emscripten
|
# Emscripten
|
||||||
emsdk
|
emsdk
|
||||||
|
|
@ -81,6 +83,7 @@ DerivedData/
|
||||||
|
|
||||||
# VSCode project
|
# VSCode project
|
||||||
.vscode
|
.vscode
|
||||||
|
.clangd
|
||||||
|
|
||||||
# Jetbrains project
|
# Jetbrains project
|
||||||
.idea/
|
.idea/
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ include(CMakeOptions.txt)
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE AND NOT "${PLATFORM}" MATCHES "DRM" AND NOT "${PLATFORM}" MATCHES "Web")
|
if (UNIX AND NOT APPLE AND NOT "${PLATFORM}" MATCHES "DRM" AND NOT "${PLATFORM}" MATCHES "Web")
|
||||||
if (NOT GLFW_BUILD_WAYLAND AND NOT GLFW_BUILD_X11)
|
if (NOT GLFW_BUILD_WAYLAND AND NOT GLFW_BUILD_X11)
|
||||||
MESSAGE(FATAL_ERROR "Cannot disable both Wayland and X11")
|
message(FATAL_ERROR "Cannot disable both Wayland and X11")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ if(NOT TARGET uninstall AND PROJECT_IS_TOP_LEVEL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (${BUILD_EXAMPLES})
|
if (${BUILD_EXAMPLES})
|
||||||
MESSAGE(STATUS "Building examples is enabled")
|
message(STATUS "Building examples is enabled")
|
||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ if(EMSCRIPTEN)
|
||||||
endif()
|
endif()
|
||||||
enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM;SDL" "Platform to build for.")
|
enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM;SDL" "Platform to build for.")
|
||||||
|
|
||||||
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0" "Force a specific OpenGL Version?")
|
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")
|
||||||
|
|
||||||
# Configuration options
|
# Configuration options
|
||||||
option(BUILD_EXAMPLES "Build the examples." ${PROJECT_IS_TOP_LEVEL})
|
option(BUILD_EXAMPLES "Build the examples." ${PROJECT_IS_TOP_LEVEL})
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ If you have any doubt, don't hesitate to [contact me](mailto:ray@raylib.com)!.
|
||||||
You can write me a direct mail but you can also contact me on the following networks:
|
You can write me a direct mail but you can also contact me on the following networks:
|
||||||
|
|
||||||
- [raylib Discord](https://discord.gg/raylib) - A direct communication channel for project discussions.
|
- [raylib Discord](https://discord.gg/raylib) - A direct communication channel for project discussions.
|
||||||
- [raylib twitter](https://twitter.com/raysan5) - My personal twitter account, I usually post about raylib, you can send me PMs.
|
|
||||||
- [raylib reddit](https://www.reddit.com/r/raylib/) - A good place for discussions or to ask for help.
|
- [raylib reddit](https://www.reddit.com/r/raylib/) - A good place for discussions or to ask for help.
|
||||||
- [raylib web](http://www.raylib.com/) - On top-right corner there is a bunch of networks where you can find me.
|
- [raylib web](http://www.raylib.com/) - On top-right corner there is a bunch of networks where you can find me.
|
||||||
|
- [raylib X](https://x.com/raysan5) - My personal X account, I usually post about raylib, you can send me PMs.
|
||||||
|
|
||||||
Thank you very much for your time! :)
|
Thank you very much for your time! :)
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ raylib is present in several networks and raylib community is growing everyday.
|
||||||
|
|
||||||
- Webpage: [https://www.raylib.com](https://www.raylib.com)
|
- Webpage: [https://www.raylib.com](https://www.raylib.com)
|
||||||
- Discord: [https://discord.gg/raylib](https://discord.gg/raylib)
|
- Discord: [https://discord.gg/raylib](https://discord.gg/raylib)
|
||||||
- Twitter: [https://www.twitter.com/raysan5](https://www.twitter.com/raysan5)
|
- X: [https://x.com/raysan5](https://x.com/raysan5)
|
||||||
- BlueSky: [https://bsky.app/profile/raysan5](https://bsky.app/profile/raysan5.bsky.social)
|
- BlueSky: [https://bsky.app/profile/raysan5](https://bsky.app/profile/raysan5.bsky.social)
|
||||||
- Twitch: [https://www.twitch.tv/raysan5](https://www.twitch.tv/raysan5)
|
- Twitch: [https://www.twitch.tv/raysan5](https://www.twitch.tv/raysan5)
|
||||||
- Reddit: [https://www.reddit.com/r/raylib](https://www.reddit.com/r/raylib)
|
- Reddit: [https://www.reddit.com/r/raylib](https://www.reddit.com/r/raylib)
|
||||||
|
|
|
||||||
|
|
@ -386,6 +386,8 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||||
setDesktopPlatform(raylib, options.platform);
|
setDesktopPlatform(raylib, options.platform);
|
||||||
},
|
},
|
||||||
.emscripten => {
|
.emscripten => {
|
||||||
|
const activate_emsdk_step = emsdk.zemscripten.activateEmsdkStep(b);
|
||||||
|
raylib.step.dependOn(activate_emsdk_step);
|
||||||
raylib.root_module.addCMacro("PLATFORM_WEB", "");
|
raylib.root_module.addCMacro("PLATFORM_WEB", "");
|
||||||
if (options.opengl_version == .auto) {
|
if (options.opengl_version == .auto) {
|
||||||
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES3", "");
|
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES3", "");
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ if (${PLATFORM} MATCHES "Desktop")
|
||||||
find_library(OSS_LIBRARY ossaudio)
|
find_library(OSS_LIBRARY ossaudio)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
|
set(LIBS_PRIVATE pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
|
||||||
|
set(LIBS_PUBLIC m)
|
||||||
else ()
|
else ()
|
||||||
find_library(pthread NAMES pthread)
|
find_library(pthread NAMES pthread)
|
||||||
find_package(OpenGL QUIET)
|
find_package(OpenGL QUIET)
|
||||||
|
|
@ -46,11 +47,13 @@ if (${PLATFORM} MATCHES "Desktop")
|
||||||
set(OPENGL_LIBRARIES "GL")
|
set(OPENGL_LIBRARIES "GL")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(LIBS_PRIVATE m atomic pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
|
set(LIBS_PRIVATE pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
|
||||||
|
set(LIBS_PUBLIC m)
|
||||||
|
|
||||||
if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD")
|
if ("${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD")
|
||||||
find_library(OSS_LIBRARY ossaudio)
|
find_library(OSS_LIBRARY ossaudio)
|
||||||
set(LIBS_PRIVATE m pthread ${OPENGL_LIBRARIES} ${OSS_LIBRARY})
|
else ()
|
||||||
|
set(LIBS_PRIVATE ${LIBS_PRIVATE} atomic)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT "${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD" AND USE_AUDIO)
|
if (NOT "${CMAKE_SYSTEM_NAME}" MATCHES "(Net|Open)BSD" AND USE_AUDIO)
|
||||||
|
|
@ -82,7 +85,8 @@ elseif (${PLATFORM} MATCHES "Android")
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup")
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup")
|
||||||
|
|
||||||
find_library(OPENGL_LIBRARY OpenGL)
|
find_library(OPENGL_LIBRARY OpenGL)
|
||||||
set(LIBS_PRIVATE m log android EGL GLESv2 OpenSLES atomic c)
|
set(LIBS_PRIVATE log android EGL GLESv2 OpenSLES atomic c)
|
||||||
|
set(LIBS_PUBLIC m)
|
||||||
|
|
||||||
elseif ("${PLATFORM}" MATCHES "DRM")
|
elseif ("${PLATFORM}" MATCHES "DRM")
|
||||||
set(PLATFORM_CPP "PLATFORM_DRM")
|
set(PLATFORM_CPP "PLATFORM_DRM")
|
||||||
|
|
@ -100,7 +104,8 @@ elseif ("${PLATFORM}" MATCHES "DRM")
|
||||||
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
|
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
|
||||||
include_directories(/usr/include/libdrm)
|
include_directories(/usr/include/libdrm)
|
||||||
endif ()
|
endif ()
|
||||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread m dl)
|
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
||||||
|
set(LIBS_PUBLIC m)
|
||||||
|
|
||||||
elseif ("${PLATFORM}" MATCHES "SDL")
|
elseif ("${PLATFORM}" MATCHES "SDL")
|
||||||
# First, check if SDL is included as a subdirectory
|
# First, check if SDL is included as a subdirectory
|
||||||
|
|
@ -153,6 +158,8 @@ if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
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")
|
||||||
|
elseif (${OPENGL_VERSION} MATCHES "Software")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_11_SOFTWARE")
|
||||||
endif ()
|
endif ()
|
||||||
if (NOT "${SUGGESTED_GRAPHICS}" STREQUAL "" 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.")
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,10 @@ elseif ("${PLATFORM}" STREQUAL "DRM")
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||||
|
|
||||||
|
elseif ("${OPENGL_VERSION}" STREQUAL "Software")
|
||||||
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||||
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||||
|
|
||||||
elseif (NOT SUPPORT_GESTURES_SYSTEM)
|
elseif (NOT SUPPORT_GESTURES_SYSTEM)
|
||||||
# Items requiring gestures system
|
# Items requiring gestures system
|
||||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_mouse_painting.c)
|
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_mouse_painting.c)
|
||||||
|
|
|
||||||
|
|
@ -512,10 +512,15 @@ CORE = \
|
||||||
core/core_automation_events \
|
core/core_automation_events \
|
||||||
core/core_basic_screen_manager \
|
core/core_basic_screen_manager \
|
||||||
core/core_basic_window \
|
core/core_basic_window \
|
||||||
|
core/core_clipboard_text \
|
||||||
core/core_custom_frame_control \
|
core/core_custom_frame_control \
|
||||||
core/core_custom_logging \
|
core/core_custom_logging \
|
||||||
|
core/core_delta_time \
|
||||||
|
core/core_directory_files \
|
||||||
core/core_drop_files \
|
core/core_drop_files \
|
||||||
core/core_high_dpi \
|
core/core_high_dpi \
|
||||||
|
core/core_highdpi_testbed \
|
||||||
|
core/core_input_actions \
|
||||||
core/core_input_gamepad \
|
core/core_input_gamepad \
|
||||||
core/core_input_gestures \
|
core/core_input_gestures \
|
||||||
core/core_input_gestures_testbed \
|
core/core_input_gestures_testbed \
|
||||||
|
|
@ -524,12 +529,15 @@ CORE = \
|
||||||
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_input_virtual_controls \
|
||||||
|
core/core_monitor_detector \
|
||||||
core/core_random_sequence \
|
core/core_random_sequence \
|
||||||
core/core_random_values \
|
core/core_random_values \
|
||||||
core/core_render_texture \
|
core/core_render_texture \
|
||||||
core/core_scissor_test \
|
core/core_scissor_test \
|
||||||
|
core/core_screen_recording \
|
||||||
core/core_smooth_pixelperfect \
|
core/core_smooth_pixelperfect \
|
||||||
core/core_storage_values \
|
core/core_storage_values \
|
||||||
|
core/core_text_file_loading \
|
||||||
core/core_undo_redo \
|
core/core_undo_redo \
|
||||||
core/core_vr_simulator \
|
core/core_vr_simulator \
|
||||||
core/core_window_flags \
|
core/core_window_flags \
|
||||||
|
|
@ -540,24 +548,36 @@ CORE = \
|
||||||
SHAPES = \
|
SHAPES = \
|
||||||
shapes/shapes_basic_shapes \
|
shapes/shapes_basic_shapes \
|
||||||
shapes/shapes_bouncing_ball \
|
shapes/shapes_bouncing_ball \
|
||||||
|
shapes/shapes_bullet_hell \
|
||||||
shapes/shapes_circle_sector_drawing \
|
shapes/shapes_circle_sector_drawing \
|
||||||
|
shapes/shapes_clock_of_clocks \
|
||||||
shapes/shapes_collision_area \
|
shapes/shapes_collision_area \
|
||||||
shapes/shapes_colors_palette \
|
shapes/shapes_colors_palette \
|
||||||
|
shapes/shapes_dashed_line \
|
||||||
shapes/shapes_digital_clock \
|
shapes/shapes_digital_clock \
|
||||||
shapes/shapes_double_pendulum \
|
shapes/shapes_double_pendulum \
|
||||||
shapes/shapes_easings_ball \
|
shapes/shapes_easings_ball \
|
||||||
shapes/shapes_easings_box \
|
shapes/shapes_easings_box \
|
||||||
shapes/shapes_easings_rectangles \
|
shapes/shapes_easings_rectangles \
|
||||||
shapes/shapes_following_eyes \
|
shapes/shapes_following_eyes \
|
||||||
|
shapes/shapes_kaleidoscope \
|
||||||
shapes/shapes_lines_bezier \
|
shapes/shapes_lines_bezier \
|
||||||
shapes/shapes_logo_raylib \
|
shapes/shapes_logo_raylib \
|
||||||
shapes/shapes_logo_raylib_anim \
|
shapes/shapes_logo_raylib_anim \
|
||||||
|
shapes/shapes_math_sine_cosine \
|
||||||
|
shapes/shapes_mouse_trail \
|
||||||
|
shapes/shapes_pie_chart \
|
||||||
shapes/shapes_rectangle_advanced \
|
shapes/shapes_rectangle_advanced \
|
||||||
shapes/shapes_rectangle_scaling \
|
shapes/shapes_rectangle_scaling \
|
||||||
|
shapes/shapes_recursive_tree \
|
||||||
shapes/shapes_ring_drawing \
|
shapes/shapes_ring_drawing \
|
||||||
shapes/shapes_rounded_rectangle_drawing \
|
shapes/shapes_rounded_rectangle_drawing \
|
||||||
|
shapes/shapes_simple_particles \
|
||||||
shapes/shapes_splines_drawing \
|
shapes/shapes_splines_drawing \
|
||||||
shapes/shapes_top_down_lights
|
shapes/shapes_starfield_effect \
|
||||||
|
shapes/shapes_top_down_lights \
|
||||||
|
shapes/shapes_triangle_strip \
|
||||||
|
shapes/shapes_vector_angle
|
||||||
|
|
||||||
TEXTURES = \
|
TEXTURES = \
|
||||||
textures/textures_background_scrolling \
|
textures/textures_background_scrolling \
|
||||||
|
|
@ -601,18 +621,19 @@ TEXT = \
|
||||||
text/text_sprite_fonts \
|
text/text_sprite_fonts \
|
||||||
text/text_unicode_emojis \
|
text/text_unicode_emojis \
|
||||||
text/text_unicode_ranges \
|
text/text_unicode_ranges \
|
||||||
|
text/text_words_alignment \
|
||||||
text/text_writing_anim
|
text/text_writing_anim
|
||||||
|
|
||||||
MODELS = \
|
MODELS = \
|
||||||
|
models/models_animation_gpu_skinning \
|
||||||
models/models_animation_playing \
|
models/models_animation_playing \
|
||||||
models/models_animation_blending \
|
models/models_basic_voxel \
|
||||||
models/models_billboard_rendering \
|
models/models_billboard_rendering \
|
||||||
models/models_bone_socket \
|
models/models_bone_socket \
|
||||||
models/models_box_collisions \
|
models/models_box_collisions \
|
||||||
models/models_cubicmap_rendering \
|
models/models_cubicmap_rendering \
|
||||||
models/models_first_person_maze \
|
models/models_first_person_maze \
|
||||||
models/models_geometric_shapes \
|
models/models_geometric_shapes \
|
||||||
models/models_gpu_skinning \
|
|
||||||
models/models_heightmap_rendering \
|
models/models_heightmap_rendering \
|
||||||
models/models_loading \
|
models/models_loading \
|
||||||
models/models_loading_gltf \
|
models/models_loading_gltf \
|
||||||
|
|
@ -623,6 +644,7 @@ MODELS = \
|
||||||
models/models_orthographic_projection \
|
models/models_orthographic_projection \
|
||||||
models/models_point_rendering \
|
models/models_point_rendering \
|
||||||
models/models_rlgl_solar_system \
|
models/models_rlgl_solar_system \
|
||||||
|
models/models_rotating_cube \
|
||||||
models/models_skybox_rendering \
|
models/models_skybox_rendering \
|
||||||
models/models_tesseract_view \
|
models/models_tesseract_view \
|
||||||
models/models_textured_cube \
|
models/models_textured_cube \
|
||||||
|
|
@ -630,6 +652,7 @@ MODELS = \
|
||||||
models/models_yaw_pitch_roll
|
models/models_yaw_pitch_roll
|
||||||
|
|
||||||
SHADERS = \
|
SHADERS = \
|
||||||
|
shaders/shaders_ascii_rendering \
|
||||||
shaders/shaders_basic_lighting \
|
shaders/shaders_basic_lighting \
|
||||||
shaders/shaders_basic_pbr \
|
shaders/shaders_basic_pbr \
|
||||||
shaders/shaders_custom_uniform \
|
shaders/shaders_custom_uniform \
|
||||||
|
|
@ -642,6 +665,7 @@ SHADERS = \
|
||||||
shaders/shaders_hybrid_rendering \
|
shaders/shaders_hybrid_rendering \
|
||||||
shaders/shaders_julia_set \
|
shaders/shaders_julia_set \
|
||||||
shaders/shaders_lightmap_rendering \
|
shaders/shaders_lightmap_rendering \
|
||||||
|
shaders/shaders_mandelbrot_set \
|
||||||
shaders/shaders_mesh_instancing \
|
shaders/shaders_mesh_instancing \
|
||||||
shaders/shaders_model_shader \
|
shaders/shaders_model_shader \
|
||||||
shaders/shaders_multi_sample2d \
|
shaders/shaders_multi_sample2d \
|
||||||
|
|
@ -674,9 +698,9 @@ OTHERS = \
|
||||||
others/easings_testbed \
|
others/easings_testbed \
|
||||||
others/embedded_files_loading \
|
others/embedded_files_loading \
|
||||||
others/raylib_opengl_interop \
|
others/raylib_opengl_interop \
|
||||||
others/raymath_vector_angle \
|
|
||||||
others/rlgl_compute_shader \
|
others/rlgl_compute_shader \
|
||||||
others/rlgl_standalone
|
others/rlgl_standalone \
|
||||||
|
others/web_basic_window
|
||||||
#EXAMPLES_LIST_END
|
#EXAMPLES_LIST_END
|
||||||
|
|
||||||
# Define processes to execute
|
# Define processes to execute
|
||||||
|
|
|
||||||
|
|
@ -512,10 +512,15 @@ CORE = \
|
||||||
core/core_automation_events \
|
core/core_automation_events \
|
||||||
core/core_basic_screen_manager \
|
core/core_basic_screen_manager \
|
||||||
core/core_basic_window \
|
core/core_basic_window \
|
||||||
|
core/core_clipboard_text \
|
||||||
core/core_custom_frame_control \
|
core/core_custom_frame_control \
|
||||||
core/core_custom_logging \
|
core/core_custom_logging \
|
||||||
|
core/core_delta_time \
|
||||||
|
core/core_directory_files \
|
||||||
core/core_drop_files \
|
core/core_drop_files \
|
||||||
core/core_high_dpi \
|
core/core_high_dpi \
|
||||||
|
core/core_highdpi_testbed \
|
||||||
|
core/core_input_actions \
|
||||||
core/core_input_gamepad \
|
core/core_input_gamepad \
|
||||||
core/core_input_gestures \
|
core/core_input_gestures \
|
||||||
core/core_input_gestures_testbed \
|
core/core_input_gestures_testbed \
|
||||||
|
|
@ -524,12 +529,15 @@ CORE = \
|
||||||
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_input_virtual_controls \
|
||||||
|
core/core_monitor_detector \
|
||||||
core/core_random_sequence \
|
core/core_random_sequence \
|
||||||
core/core_random_values \
|
core/core_random_values \
|
||||||
core/core_render_texture \
|
core/core_render_texture \
|
||||||
core/core_scissor_test \
|
core/core_scissor_test \
|
||||||
|
core/core_screen_recording \
|
||||||
core/core_smooth_pixelperfect \
|
core/core_smooth_pixelperfect \
|
||||||
core/core_storage_values \
|
core/core_storage_values \
|
||||||
|
core/core_text_file_loading \
|
||||||
core/core_undo_redo \
|
core/core_undo_redo \
|
||||||
core/core_vr_simulator \
|
core/core_vr_simulator \
|
||||||
core/core_window_flags \
|
core/core_window_flags \
|
||||||
|
|
@ -540,24 +548,36 @@ CORE = \
|
||||||
SHAPES = \
|
SHAPES = \
|
||||||
shapes/shapes_basic_shapes \
|
shapes/shapes_basic_shapes \
|
||||||
shapes/shapes_bouncing_ball \
|
shapes/shapes_bouncing_ball \
|
||||||
|
shapes/shapes_bullet_hell \
|
||||||
shapes/shapes_circle_sector_drawing \
|
shapes/shapes_circle_sector_drawing \
|
||||||
|
shapes/shapes_clock_of_clocks \
|
||||||
shapes/shapes_collision_area \
|
shapes/shapes_collision_area \
|
||||||
shapes/shapes_colors_palette \
|
shapes/shapes_colors_palette \
|
||||||
|
shapes/shapes_dashed_line \
|
||||||
shapes/shapes_digital_clock \
|
shapes/shapes_digital_clock \
|
||||||
shapes/shapes_double_pendulum \
|
shapes/shapes_double_pendulum \
|
||||||
shapes/shapes_easings_ball \
|
shapes/shapes_easings_ball \
|
||||||
shapes/shapes_easings_box \
|
shapes/shapes_easings_box \
|
||||||
shapes/shapes_easings_rectangles \
|
shapes/shapes_easings_rectangles \
|
||||||
shapes/shapes_following_eyes \
|
shapes/shapes_following_eyes \
|
||||||
|
shapes/shapes_kaleidoscope \
|
||||||
shapes/shapes_lines_bezier \
|
shapes/shapes_lines_bezier \
|
||||||
shapes/shapes_logo_raylib \
|
shapes/shapes_logo_raylib \
|
||||||
shapes/shapes_logo_raylib_anim \
|
shapes/shapes_logo_raylib_anim \
|
||||||
|
shapes/shapes_math_sine_cosine \
|
||||||
|
shapes/shapes_mouse_trail \
|
||||||
|
shapes/shapes_pie_chart \
|
||||||
shapes/shapes_rectangle_advanced \
|
shapes/shapes_rectangle_advanced \
|
||||||
shapes/shapes_rectangle_scaling \
|
shapes/shapes_rectangle_scaling \
|
||||||
|
shapes/shapes_recursive_tree \
|
||||||
shapes/shapes_ring_drawing \
|
shapes/shapes_ring_drawing \
|
||||||
shapes/shapes_rounded_rectangle_drawing \
|
shapes/shapes_rounded_rectangle_drawing \
|
||||||
|
shapes/shapes_simple_particles \
|
||||||
shapes/shapes_splines_drawing \
|
shapes/shapes_splines_drawing \
|
||||||
shapes/shapes_top_down_lights
|
shapes/shapes_starfield_effect \
|
||||||
|
shapes/shapes_top_down_lights \
|
||||||
|
shapes/shapes_triangle_strip \
|
||||||
|
shapes/shapes_vector_angle
|
||||||
|
|
||||||
TEXTURES = \
|
TEXTURES = \
|
||||||
textures/textures_background_scrolling \
|
textures/textures_background_scrolling \
|
||||||
|
|
@ -601,18 +621,19 @@ TEXT = \
|
||||||
text/text_sprite_fonts \
|
text/text_sprite_fonts \
|
||||||
text/text_unicode_emojis \
|
text/text_unicode_emojis \
|
||||||
text/text_unicode_ranges \
|
text/text_unicode_ranges \
|
||||||
|
text/text_words_alignment \
|
||||||
text/text_writing_anim
|
text/text_writing_anim
|
||||||
|
|
||||||
MODELS = \
|
MODELS = \
|
||||||
|
models/models_animation_gpu_skinning \
|
||||||
models/models_animation_playing \
|
models/models_animation_playing \
|
||||||
models/models_animation_blending \
|
models/models_basic_voxel \
|
||||||
models/models_billboard_rendering \
|
models/models_billboard_rendering \
|
||||||
models/models_bone_socket \
|
models/models_bone_socket \
|
||||||
models/models_box_collisions \
|
models/models_box_collisions \
|
||||||
models/models_cubicmap_rendering \
|
models/models_cubicmap_rendering \
|
||||||
models/models_first_person_maze \
|
models/models_first_person_maze \
|
||||||
models/models_geometric_shapes \
|
models/models_geometric_shapes \
|
||||||
models/models_gpu_skinning \
|
|
||||||
models/models_heightmap_rendering \
|
models/models_heightmap_rendering \
|
||||||
models/models_loading \
|
models/models_loading \
|
||||||
models/models_loading_gltf \
|
models/models_loading_gltf \
|
||||||
|
|
@ -623,6 +644,7 @@ MODELS = \
|
||||||
models/models_orthographic_projection \
|
models/models_orthographic_projection \
|
||||||
models/models_point_rendering \
|
models/models_point_rendering \
|
||||||
models/models_rlgl_solar_system \
|
models/models_rlgl_solar_system \
|
||||||
|
models/models_rotating_cube \
|
||||||
models/models_skybox_rendering \
|
models/models_skybox_rendering \
|
||||||
models/models_tesseract_view \
|
models/models_tesseract_view \
|
||||||
models/models_textured_cube \
|
models/models_textured_cube \
|
||||||
|
|
@ -630,6 +652,7 @@ MODELS = \
|
||||||
models/models_yaw_pitch_roll
|
models/models_yaw_pitch_roll
|
||||||
|
|
||||||
SHADERS = \
|
SHADERS = \
|
||||||
|
shaders/shaders_ascii_rendering \
|
||||||
shaders/shaders_basic_lighting \
|
shaders/shaders_basic_lighting \
|
||||||
shaders/shaders_basic_pbr \
|
shaders/shaders_basic_pbr \
|
||||||
shaders/shaders_custom_uniform \
|
shaders/shaders_custom_uniform \
|
||||||
|
|
@ -642,6 +665,7 @@ SHADERS = \
|
||||||
shaders/shaders_hybrid_rendering \
|
shaders/shaders_hybrid_rendering \
|
||||||
shaders/shaders_julia_set \
|
shaders/shaders_julia_set \
|
||||||
shaders/shaders_lightmap_rendering \
|
shaders/shaders_lightmap_rendering \
|
||||||
|
shaders/shaders_mandelbrot_set \
|
||||||
shaders/shaders_mesh_instancing \
|
shaders/shaders_mesh_instancing \
|
||||||
shaders/shaders_model_shader \
|
shaders/shaders_model_shader \
|
||||||
shaders/shaders_multi_sample2d \
|
shaders/shaders_multi_sample2d \
|
||||||
|
|
@ -721,18 +745,33 @@ core/core_basic_screen_manager: core/core_basic_screen_manager.c
|
||||||
core/core_basic_window: core/core_basic_window.c
|
core/core_basic_window: core/core_basic_window.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_clipboard_text: core/core_clipboard_text.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_custom_frame_control: core/core_custom_frame_control.c
|
core/core_custom_frame_control: core/core_custom_frame_control.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_custom_logging: core/core_custom_logging.c
|
core/core_custom_logging: core/core_custom_logging.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_delta_time: core/core_delta_time.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_directory_files: core/core_directory_files.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_drop_files: core/core_drop_files.c
|
core/core_drop_files: core/core_drop_files.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_high_dpi: core/core_high_dpi.c
|
core/core_high_dpi: core/core_high_dpi.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_highdpi_testbed: core/core_highdpi_testbed.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_input_actions: core/core_input_actions.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_input_gamepad: core/core_input_gamepad.c
|
core/core_input_gamepad: core/core_input_gamepad.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file core/resources/ps3.png@resources/ps3.png \
|
--preload-file core/resources/ps3.png@resources/ps3.png \
|
||||||
|
|
@ -759,6 +798,9 @@ core/core_input_multitouch: core/core_input_multitouch.c
|
||||||
core/core_input_virtual_controls: core/core_input_virtual_controls.c
|
core/core_input_virtual_controls: core/core_input_virtual_controls.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_monitor_detector: core/core_monitor_detector.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_random_sequence: core/core_random_sequence.c
|
core/core_random_sequence: core/core_random_sequence.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -771,12 +813,19 @@ core/core_render_texture: core/core_render_texture.c
|
||||||
core/core_scissor_test: core/core_scissor_test.c
|
core/core_scissor_test: core/core_scissor_test.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_screen_recording: core/core_screen_recording.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_smooth_pixelperfect: core/core_smooth_pixelperfect.c
|
core/core_smooth_pixelperfect: core/core_smooth_pixelperfect.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
core/core_storage_values: core/core_storage_values.c
|
core/core_storage_values: core/core_storage_values.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
core/core_text_file_loading: core/core_text_file_loading.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file core/resources/text_file.txt@resources/text_file.txt
|
||||||
|
|
||||||
core/core_undo_redo: core/core_undo_redo.c
|
core/core_undo_redo: core/core_undo_redo.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -803,15 +852,24 @@ shapes/shapes_basic_shapes: shapes/shapes_basic_shapes.c
|
||||||
shapes/shapes_bouncing_ball: shapes/shapes_bouncing_ball.c
|
shapes/shapes_bouncing_ball: shapes/shapes_bouncing_ball.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_bullet_hell: shapes/shapes_bullet_hell.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_circle_sector_drawing: shapes/shapes_circle_sector_drawing.c
|
shapes/shapes_circle_sector_drawing: shapes/shapes_circle_sector_drawing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_clock_of_clocks: shapes/shapes_clock_of_clocks.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_collision_area: shapes/shapes_collision_area.c
|
shapes/shapes_collision_area: shapes/shapes_collision_area.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_colors_palette: shapes/shapes_colors_palette.c
|
shapes/shapes_colors_palette: shapes/shapes_colors_palette.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_dashed_line: shapes/shapes_dashed_line.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_digital_clock: shapes/shapes_digital_clock.c
|
shapes/shapes_digital_clock: shapes/shapes_digital_clock.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -830,6 +888,9 @@ shapes/shapes_easings_rectangles: shapes/shapes_easings_rectangles.c
|
||||||
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
|
shapes/shapes_following_eyes: shapes/shapes_following_eyes.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_kaleidoscope: shapes/shapes_kaleidoscope.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c
|
shapes/shapes_lines_bezier: shapes/shapes_lines_bezier.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
|
@ -839,24 +900,48 @@ shapes/shapes_logo_raylib: shapes/shapes_logo_raylib.c
|
||||||
shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c
|
shapes/shapes_logo_raylib_anim: shapes/shapes_logo_raylib_anim.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_pie_chart: shapes/shapes_pie_chart.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_rectangle_advanced: shapes/shapes_rectangle_advanced.c
|
shapes/shapes_rectangle_advanced: shapes/shapes_rectangle_advanced.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_rectangle_scaling: shapes/shapes_rectangle_scaling.c
|
shapes/shapes_rectangle_scaling: shapes/shapes_rectangle_scaling.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_recursive_tree: shapes/shapes_recursive_tree.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c
|
shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_rounded_rectangle_drawing: shapes/shapes_rounded_rectangle_drawing.c
|
shapes/shapes_rounded_rectangle_drawing: shapes/shapes_rounded_rectangle_drawing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_simple_particles: shapes/shapes_simple_particles.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_splines_drawing: shapes/shapes_splines_drawing.c
|
shapes/shapes_splines_drawing: shapes/shapes_splines_drawing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_starfield_effect: shapes/shapes_starfield_effect.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
shapes/shapes_top_down_lights: shapes/shapes_top_down_lights.c
|
shapes/shapes_top_down_lights: shapes/shapes_top_down_lights.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_triangle_strip: shapes/shapes_triangle_strip.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
shapes/shapes_vector_angle: shapes/shapes_vector_angle.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
# Compile TEXTURES examples
|
# Compile TEXTURES examples
|
||||||
textures/textures_background_scrolling: textures/textures_background_scrolling.c
|
textures/textures_background_scrolling: textures/textures_background_scrolling.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
|
@ -1020,23 +1105,38 @@ text/text_sprite_fonts: text/text_sprite_fonts.c
|
||||||
text/text_unicode_emojis: text/text_unicode_emojis.c
|
text/text_unicode_emojis: text/text_unicode_emojis.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file text/resources/dejavu.fnt@resources/dejavu.fnt \
|
--preload-file text/resources/dejavu.fnt@resources/dejavu.fnt \
|
||||||
|
--preload-file text/resources/dejavu.png@resources/dejavu.png \
|
||||||
--preload-file text/resources/noto_cjk.fnt@resources/noto_cjk.fnt \
|
--preload-file text/resources/noto_cjk.fnt@resources/noto_cjk.fnt \
|
||||||
--preload-file text/resources/symbola.fnt@resources/symbola.fnt
|
--preload-file text/resources/noto_cjk.png@resources/noto_cjk.png \
|
||||||
|
--preload-file text/resources/symbola.fnt@resources/symbola.fnt \
|
||||||
|
--preload-file text/resources/symbola.png@resources/symbola.png
|
||||||
|
|
||||||
text/text_unicode_ranges: text/text_unicode_ranges.c
|
text/text_unicode_ranges: text/text_unicode_ranges.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file text/resources/NotoSansTC-Regular.ttf@resources/NotoSansTC-Regular.ttf
|
--preload-file text/resources/NotoSansTC-Regular.ttf@resources/NotoSansTC-Regular.ttf
|
||||||
|
|
||||||
|
text/text_words_alignment: text/text_words_alignment.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
text/text_writing_anim: text/text_writing_anim.c
|
text/text_writing_anim: text/text_writing_anim.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
# Compile MODELS examples
|
# Compile MODELS examples
|
||||||
|
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 \
|
||||||
|
--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_playing: models/models_animation_playing.c
|
models/models_animation_playing: models/models_animation_playing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file models/resources/models/iqm/guy.iqm@resources/models/iqm/guy.iqm \
|
--preload-file models/resources/models/iqm/guy.iqm@resources/models/iqm/guy.iqm \
|
||||||
--preload-file models/resources/models/iqm/guytex.png@resources/models/iqm/guytex.png \
|
--preload-file models/resources/models/iqm/guytex.png@resources/models/iqm/guytex.png \
|
||||||
--preload-file models/resources/models/iqm/guyanim.iqm@resources/models/iqm/guyanim.iqm
|
--preload-file models/resources/models/iqm/guyanim.iqm@resources/models/iqm/guyanim.iqm
|
||||||
|
|
||||||
|
models/models_basic_voxel: models/models_basic_voxel.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
models/models_billboard_rendering: models/models_billboard_rendering.c
|
models/models_billboard_rendering: models/models_billboard_rendering.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file models/resources/billboard.png@resources/billboard.png
|
--preload-file models/resources/billboard.png@resources/billboard.png
|
||||||
|
|
@ -1064,12 +1164,6 @@ models/models_first_person_maze: models/models_first_person_maze.c
|
||||||
models/models_geometric_shapes: models/models_geometric_shapes.c
|
models/models_geometric_shapes: models/models_geometric_shapes.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
models/models_gpu_skinning: models/models_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 \
|
|
||||||
--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_heightmap_rendering: models/models_heightmap_rendering.c
|
models/models_heightmap_rendering: models/models_heightmap_rendering.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file models/resources/heightmap.png@resources/heightmap.png
|
--preload-file models/resources/heightmap.png@resources/heightmap.png
|
||||||
|
|
@ -1113,6 +1207,10 @@ models/models_point_rendering: models/models_point_rendering.c
|
||||||
models/models_rlgl_solar_system: models/models_rlgl_solar_system.c
|
models/models_rlgl_solar_system: models/models_rlgl_solar_system.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||||
|
|
||||||
|
models/models_rotating_cube: models/models_rotating_cube.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file models/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png
|
||||||
|
|
||||||
models/models_skybox_rendering: models/models_skybox_rendering.c
|
models/models_skybox_rendering: models/models_skybox_rendering.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file models/resources/shaders/glsl100/skybox.vs@resources/shaders/glsl100/skybox.vs \
|
--preload-file models/resources/shaders/glsl100/skybox.vs@resources/shaders/glsl100/skybox.vs \
|
||||||
|
|
@ -1138,6 +1236,12 @@ models/models_yaw_pitch_roll: models/models_yaw_pitch_roll.c
|
||||||
--preload-file models/resources/models/obj/plane_diffuse.png@resources/models/obj/plane_diffuse.png
|
--preload-file models/resources/models/obj/plane_diffuse.png@resources/models/obj/plane_diffuse.png
|
||||||
|
|
||||||
# Compile SHADERS examples
|
# Compile SHADERS examples
|
||||||
|
shaders/shaders_ascii_rendering: shaders/shaders_ascii_rendering.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file shaders/resources/fudesumi.png@resources/fudesumi.png \
|
||||||
|
--preload-file shaders/resources/raysan.png@resources/raysan.png \
|
||||||
|
--preload-file shaders/resources/shaders/glsl100/ascii.fs@resources/shaders/glsl100/ascii.fs
|
||||||
|
|
||||||
shaders/shaders_basic_lighting: shaders/shaders_basic_lighting.c
|
shaders/shaders_basic_lighting: shaders/shaders_basic_lighting.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs \
|
--preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs \
|
||||||
|
|
@ -1208,6 +1312,10 @@ shaders/shaders_lightmap_rendering: shaders/shaders_lightmap_rendering.c
|
||||||
--preload-file shaders/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png \
|
--preload-file shaders/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png \
|
||||||
--preload-file shaders/resources/spark_flame.png@resources/spark_flame.png
|
--preload-file shaders/resources/spark_flame.png@resources/spark_flame.png
|
||||||
|
|
||||||
|
shaders/shaders_mandelbrot_set: shaders/shaders_mandelbrot_set.c
|
||||||
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
|
--preload-file shaders/resources/shaders/glsl100/mandelbrot_set.fs@resources/shaders/glsl100/mandelbrot_set.fs
|
||||||
|
|
||||||
shaders/shaders_mesh_instancing: shaders/shaders_mesh_instancing.c
|
shaders/shaders_mesh_instancing: shaders/shaders_mesh_instancing.c
|
||||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||||
--preload-file shaders/resources/shaders/glsl100/lighting_instancing.vs@resources/shaders/glsl100/lighting_instancing.vs \
|
--preload-file shaders/resources/shaders/glsl100/lighting_instancing.vs@resources/shaders/glsl100/lighting_instancing.vs \
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,16 @@ 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 [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`)
|
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
|
||||||
|
|
||||||
## EXAMPLES COLLECTION [TOTAL: 163]
|
## EXAMPLES COLLECTION [TOTAL: 187]
|
||||||
|
|
||||||
### category: core [37]
|
### category: core [45]
|
||||||
|
|
||||||
Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality.
|
Examples using raylib[core](../src/rcore.c) platform functionality like window creation, inputs, drawing modes and system functionality.
|
||||||
|
|
||||||
| 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 |
|
||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
| [core_basic_window](core/core_basic_window.c) | <img src="core/core_basic_window.png" alt="core_basic_window" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_basic_window](core/core_basic_window.c) | <img src="core/core_basic_window.png" alt="core_basic_window" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
| [core_delta_time](core/core_delta_time.c) | <img src="core/core_delta_time.png" alt="core_delta_time" width="80"> | ⭐☆☆☆ | 5.5 | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
||||||
| [core_input_keys](core/core_input_keys.c) | <img src="core/core_input_keys.png" alt="core_input_keys" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_input_keys](core/core_input_keys.c) | <img src="core/core_input_keys.png" alt="core_input_keys" width="80"> | ⭐☆☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_input_mouse](core/core_input_mouse.c) | <img src="core/core_input_mouse.png" alt="core_input_mouse" width="80"> | ⭐☆☆☆ | 1.0 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_input_mouse](core/core_input_mouse.c) | <img src="core/core_input_mouse.png" alt="core_input_mouse" width="80"> | ⭐☆☆☆ | 1.0 | 5.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_input_mouse_wheel](core/core_input_mouse_wheel.c) | <img src="core/core_input_mouse_wheel.png" alt="core_input_mouse_wheel" width="80"> | ⭐☆☆☆ | 1.1 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_input_mouse_wheel](core/core_input_mouse_wheel.c) | <img src="core/core_input_mouse_wheel.png" alt="core_input_mouse_wheel" width="80"> | ⭐☆☆☆ | 1.1 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
|
@ -48,6 +49,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [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) |
|
| [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) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
| [core_monitor_detector](core/core_monitor_detector.c) | <img src="core/core_monitor_detector.png" alt="core_monitor_detector" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Maicon Santana](https://github.com/maiconpintoabreu) |
|
||||||
| [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) |
|
| [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) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
|
@ -62,8 +64,14 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
|
||||||
| [core_high_dpi](core/core_high_dpi.c) | <img src="core/core_high_dpi.png" alt="core_high_dpi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) |
|
| [core_high_dpi](core/core_high_dpi.c) | <img src="core/core_high_dpi.png" alt="core_high_dpi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.5 | [Jonathan Marler](https://github.com/marler8997) |
|
||||||
| [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_render_texture](core/core_render_texture.c) | <img src="core/core_render_texture.png" alt="core_render_texture" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [core_undo_redo](core/core_undo_redo.c) | <img src="core/core_undo_redo.png" alt="core_undo_redo" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [core_undo_redo](core/core_undo_redo.c) | <img src="core/core_undo_redo.png" alt="core_undo_redo" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
| [core_input_actions](core/core_input_actions.c) | <img src="core/core_input_actions.png" alt="core_input_actions" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) |
|
||||||
|
| [core_directory_files](core/core_directory_files.c) | <img src="core/core_directory_files.png" alt="core_directory_files" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
|
||||||
|
| [core_highdpi_testbed](core/core_highdpi_testbed.c) | <img src="core/core_highdpi_testbed.png" alt="core_highdpi_testbed" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
| [core_screen_recording](core/core_screen_recording.c) | <img src="core/core_screen_recording.png" alt="core_screen_recording" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
| [core_clipboard_text](core/core_clipboard_text.c) | <img src="core/core_clipboard_text.png" alt="core_clipboard_text" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
||||||
|
| [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) |
|
||||||
|
|
||||||
### category: shapes [20]
|
### category: shapes [32]
|
||||||
|
|
||||||
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
|
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
|
||||||
|
|
||||||
|
|
@ -71,6 +79,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
| [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐☆☆☆ | 1.0 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_basic_shapes](shapes/shapes_basic_shapes.c) | <img src="shapes/shapes_basic_shapes.png" alt="shapes_basic_shapes" width="80"> | ⭐☆☆☆ | 1.0 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
| [shapes_bullet_hell](shapes/shapes_bullet_hell.c) | <img src="shapes/shapes_bullet_hell.png" alt="shapes_bullet_hell" width="80"> | ⭐☆☆☆ | 5.6 | 5.6 | [Zero](https://github.com/zerohorsepower) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
|
@ -81,6 +90,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||||
| [shapes_easings_ball](shapes/shapes_easings_ball.c) | <img src="shapes/shapes_easings_ball.png" alt="shapes_easings_ball" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_easings_ball](shapes/shapes_easings_ball.c) | <img src="shapes/shapes_easings_ball.png" alt="shapes_easings_ball" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shapes_easings_box](shapes/shapes_easings_box.c) | <img src="shapes/shapes_easings_box.png" alt="shapes_easings_box" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_easings_box](shapes/shapes_easings_box.c) | <img src="shapes/shapes_easings_box.png" alt="shapes_easings_box" width="80"> | ⭐⭐☆☆ | 2.5 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shapes_easings_rectangles](shapes/shapes_easings_rectangles.c) | <img src="shapes/shapes_easings_rectangles.png" alt="shapes_easings_rectangles" width="80"> | ⭐⭐⭐☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_easings_rectangles](shapes/shapes_easings_rectangles.c) | <img src="shapes/shapes_easings_rectangles.png" alt="shapes_easings_rectangles" width="80"> | ⭐⭐⭐☆ | 2.0 | 2.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
| [shapes_recursive_tree](shapes/shapes_recursive_tree.c) | <img src="shapes/shapes_recursive_tree.png" alt="shapes_recursive_tree" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
||||||
| [shapes_ring_drawing](shapes/shapes_ring_drawing.c) | <img src="shapes/shapes_ring_drawing.png" alt="shapes_ring_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| [shapes_ring_drawing](shapes/shapes_ring_drawing.c) | <img src="shapes/shapes_ring_drawing.png" alt="shapes_ring_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| [shapes_circle_sector_drawing](shapes/shapes_circle_sector_drawing.c) | <img src="shapes/shapes_circle_sector_drawing.png" alt="shapes_circle_sector_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| [shapes_circle_sector_drawing](shapes/shapes_circle_sector_drawing.c) | <img src="shapes/shapes_circle_sector_drawing.png" alt="shapes_circle_sector_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| [shapes_rounded_rectangle_drawing](shapes/shapes_rounded_rectangle_drawing.c) | <img src="shapes/shapes_rounded_rectangle_drawing.png" alt="shapes_rounded_rectangle_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
| [shapes_rounded_rectangle_drawing](shapes/shapes_rounded_rectangle_drawing.c) | <img src="shapes/shapes_rounded_rectangle_drawing.png" alt="shapes_rounded_rectangle_drawing" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
|
|
@ -89,6 +99,15 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||||
| [shapes_splines_drawing](shapes/shapes_splines_drawing.c) | <img src="shapes/shapes_splines_drawing.png" alt="shapes_splines_drawing" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [shapes_splines_drawing](shapes/shapes_splines_drawing.c) | <img src="shapes/shapes_splines_drawing.png" alt="shapes_splines_drawing" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [shapes_digital_clock](shapes/shapes_digital_clock.c) | <img src="shapes/shapes_digital_clock.png" alt="shapes_digital_clock" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
| [shapes_digital_clock](shapes/shapes_digital_clock.c) | <img src="shapes/shapes_digital_clock.png" alt="shapes_digital_clock" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) |
|
||||||
| [shapes_double_pendulum](shapes/shapes_double_pendulum.c) | <img src="shapes/shapes_double_pendulum.png" alt="shapes_double_pendulum" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) |
|
| [shapes_double_pendulum](shapes/shapes_double_pendulum.c) | <img src="shapes/shapes_double_pendulum.png" alt="shapes_double_pendulum" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) |
|
||||||
|
| [shapes_dashed_line](shapes/shapes_dashed_line.c) | <img src="shapes/shapes_dashed_line.png" alt="shapes_dashed_line" width="80"> | ⭐☆☆☆ | 5.5 | 5.5 | [Luís Almeida](https://github.com/luis605) |
|
||||||
|
| [shapes_triangle_strip](shapes/shapes_triangle_strip.c) | <img src="shapes/shapes_triangle_strip.png" alt="shapes_triangle_strip" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Jopestpe](https://github.com/jopestpe) |
|
||||||
|
| [shapes_vector_angle](shapes/shapes_vector_angle.c) | <img src="shapes/shapes_vector_angle.png" alt="shapes_vector_angle" width="80"> | ⭐⭐☆☆ | 1.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
| [shapes_pie_chart](shapes/shapes_pie_chart.c) | <img src="shapes/shapes_pie_chart.png" alt="shapes_pie_chart" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.6 | [Gideon Serfontein](https://github.com/GideonSerf) |
|
||||||
|
| [shapes_kaleidoscope](shapes/shapes_kaleidoscope.c) | <img src="shapes/shapes_kaleidoscope.png" alt="shapes_kaleidoscope" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) |
|
||||||
|
| [shapes_clock_of_clocks](shapes/shapes_clock_of_clocks.c) | <img src="shapes/shapes_clock_of_clocks.png" alt="shapes_clock_of_clocks" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||||
|
| [shapes_mouse_trail](shapes/shapes_mouse_trail.c) | <img src="shapes/shapes_mouse_trail.png" alt="shapes_mouse_trail" width="80"> | ⭐☆☆☆ | 5.6 | 5.6-dev | [Balamurugan R](https://github.com/Bala050814) |
|
||||||
|
| [shapes_simple_particles](shapes/shapes_simple_particles.c) | <img src="shapes/shapes_simple_particles.png" alt="shapes_simple_particles" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||||
|
| [shapes_starfield_effect](shapes/shapes_starfield_effect.c) | <img src="shapes/shapes_starfield_effect.png" alt="shapes_starfield_effect" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||||
|
|
||||||
### category: textures [26]
|
### category: textures [26]
|
||||||
|
|
||||||
|
|
@ -123,7 +142,7 @@ Examples using raylib textures functionality, including image/textures loading/g
|
||||||
| [textures_image_rotate](textures/textures_image_rotate.c) | <img src="textures/textures_image_rotate.png" alt="textures_image_rotate" width="80"> | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [textures_image_rotate](textures/textures_image_rotate.c) | <img src="textures/textures_image_rotate.png" alt="textures_image_rotate" width="80"> | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
|
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||||
|
|
||||||
### category: text [14]
|
### category: text [15]
|
||||||
|
|
||||||
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
|
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
|
||||||
|
|
||||||
|
|
@ -139,12 +158,13 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [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) |
|
| [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) |
|
||||||
| [text_unicode_emojis](text/text_unicode_emojis.c) | <img src="text/text_unicode_emojis.png" alt="text_unicode_emojis" width="80"> | ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
| [text_unicode_emojis](text/text_unicode_emojis.c) | <img src="text/text_unicode_emojis.png" alt="text_unicode_emojis" width="80"> | ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| [text_unicode_ranges](text/text_unicode_ranges.c) | <img src="text/text_unicode_ranges.png" alt="text_unicode_ranges" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Vlad Adrian](https://github.com/demizdor) |
|
| [text_unicode_ranges](text/text_unicode_ranges.c) | <img src="text/text_unicode_ranges.png" alt="text_unicode_ranges" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Vadim Gunko](https://github.com/GuvaCode) |
|
||||||
| [text_3d_drawing](text/text_3d_drawing.c) | <img src="text/text_3d_drawing.png" alt="text_3d_drawing" width="80"> | ⭐⭐⭐⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
| [text_3d_drawing](text/text_3d_drawing.c) | <img src="text/text_3d_drawing.png" alt="text_3d_drawing" width="80"> | ⭐⭐⭐⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [text_inline_styling](text/text_inline_styling.c) | <img src="text/text_inline_styling.png" alt="text_inline_styling" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Wagner Barongello](https://github.com/SultansOfCode) |
|
| [text_inline_styling](text/text_inline_styling.c) | <img src="text/text_inline_styling.png" alt="text_inline_styling" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Wagner Barongello](https://github.com/SultansOfCode) |
|
||||||
|
| [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) |
|
||||||
|
|
||||||
### category: models [23]
|
### category: models [25]
|
||||||
|
|
||||||
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
|
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
|
||||||
|
|
||||||
|
|
@ -170,16 +190,19 @@ Examples using raylib models functionality, including models loading/generation
|
||||||
| [models_heightmap_rendering](models/models_heightmap_rendering.c) | <img src="models/models_heightmap_rendering.png" alt="models_heightmap_rendering" width="80"> | ⭐☆☆☆ | 1.8 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [models_heightmap_rendering](models/models_heightmap_rendering.c) | <img src="models/models_heightmap_rendering.png" alt="models_heightmap_rendering" width="80"> | ⭐☆☆☆ | 1.8 | 3.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [models_skybox_rendering](models/models_skybox_rendering.c) | <img src="models/models_skybox_rendering.png" alt="models_skybox_rendering" width="80"> | ⭐⭐☆☆ | 1.8 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [models_skybox_rendering](models/models_skybox_rendering.c) | <img src="models/models_skybox_rendering.png" alt="models_skybox_rendering" width="80"> | ⭐⭐☆☆ | 1.8 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [models_textured_cube](models/models_textured_cube.c) | <img src="models/models_textured_cube.png" alt="models_textured_cube" width="80"> | ⭐⭐☆☆ | 4.5 | 4.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [models_textured_cube](models/models_textured_cube.c) | <img src="models/models_textured_cube.png" alt="models_textured_cube" width="80"> | ⭐⭐☆☆ | 4.5 | 4.5 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [models_gpu_skinning](models/models_gpu_skinning.c) | <img src="models/models_gpu_skinning.png" alt="models_gpu_skinning" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Daniel Holden](https://github.com/orangeduck) |
|
| [models_animation_gpu_skinning](models/models_animation_gpu_skinning.c) | <img src="models/models_animation_gpu_skinning.png" alt="models_animation_gpu_skinning" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Daniel Holden](https://github.com/orangeduck) |
|
||||||
| [models_bone_socket](models/models_bone_socket.c) | <img src="models/models_bone_socket.png" alt="models_bone_socket" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
|
| [models_bone_socket](models/models_bone_socket.c) | <img src="models/models_bone_socket.png" alt="models_bone_socket" width="80"> | ⭐⭐⭐⭐️ | 4.5 | 4.5 | [iP](https://github.com/ipzaur) |
|
||||||
| [models_tesseract_view](models/models_tesseract_view.c) | <img src="models/models_tesseract_view.png" alt="models_tesseract_view" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) |
|
| [models_tesseract_view](models/models_tesseract_view.c) | <img src="models/models_tesseract_view.png" alt="models_tesseract_view" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Timothy van der Valk](https://github.com/arceryz) |
|
||||||
|
| [models_basic_voxel](models/models_basic_voxel.c) | <img src="models/models_basic_voxel.png" alt="models_basic_voxel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Tim Little](https://github.com/timlittle) |
|
||||||
|
| [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) |
|
||||||
|
|
||||||
### category: shaders [29]
|
### category: shaders [31]
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
| 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 |
|
||||||
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
|-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------|
|
||||||
|
| [shaders_ascii_rendering](shaders/shaders_ascii_rendering.c) | <img src="shaders/shaders_ascii_rendering.png" alt="shaders_ascii_rendering" width="80"> | ⭐⭐☆☆ | 5.5 | 5.6 | [Maicon Santana](https://github.com/maiconpintoabreu) |
|
||||||
| [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/chriscamacho) |
|
| [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/chriscamacho) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||||
|
|
@ -209,6 +232,7 @@ Examples using raylib shaders functionality, including shaders loading, paramete
|
||||||
| [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) | <img src="shaders/shaders_lightmap_rendering.png" alt="shaders_lightmap_rendering" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
|
| [shaders_lightmap_rendering](shaders/shaders_lightmap_rendering.c) | <img src="shaders/shaders_lightmap_rendering.png" alt="shaders_lightmap_rendering" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jussi Viitala](https://github.com/nullstare) |
|
||||||
| [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_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_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_mandelbrot_set](shaders/shaders_mandelbrot_set.c) | <img src="shaders/shaders_mandelbrot_set.png" alt="shaders_mandelbrot_set" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||||
|
|
||||||
### category: audio [8]
|
### category: audio [8]
|
||||||
|
|
||||||
|
|
@ -236,7 +260,7 @@ Examples showing raylib misc functionality that does not fit in other categories
|
||||||
| [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) |
|
| [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) |
|
| [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) |
|
| [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) |
|
||||||
| [raymath_vector_angle](others/raymath_vector_angle.c) | <img src="others/raymath_vector_angle.png" alt="raymath_vector_angle" width="80"> | ⭐⭐☆☆ | 1.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
| [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!
|
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!
|
Here is an[examples template](examples_template.c) with instructions to start with!
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ int main(void)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_FREE);
|
UpdateCamera(&camera, CAMERA_FREE);
|
||||||
|
|
||||||
float th = GetTime();
|
float th = (float)GetTime();
|
||||||
|
|
||||||
Vector3 spherePos = {
|
Vector3 spherePos = {
|
||||||
.x = 5.0f*cosf(th),
|
.x = 5.0f*cosf(th),
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,6 @@ int main(void)
|
||||||
// Some default standard keyboard/mouse inputs are hardcoded to simplify use
|
// Some default standard keyboard/mouse inputs are hardcoded to simplify use
|
||||||
// For advanced camera controls, it's recommended to compute camera movement manually
|
// For advanced camera controls, it's recommended to compute camera movement manually
|
||||||
UpdateCamera(&camera, cameraMode); // Update camera
|
UpdateCamera(&camera, cameraMode); // Update camera
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Camera PRO usage example (EXPERIMENTAL)
|
// Camera PRO usage example (EXPERIMENTAL)
|
||||||
// This new camera function allows custom movement/rotation values to be directly provided
|
// This new camera function allows custom movement/rotation values to be directly provided
|
||||||
|
|
|
||||||
|
|
@ -198,8 +198,8 @@ void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed
|
||||||
//PlaySound(fxJump);
|
//PlaySound(fxJump);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 front = (Vector3){ sin(rot), 0.f, cos(rot) };
|
Vector3 front = (Vector3){ sinf(rot), 0.f, cosf(rot) };
|
||||||
Vector3 right = (Vector3){ cos(-rot), 0.f, sin(-rot) };
|
Vector3 right = (Vector3){ cosf(-rot), 0.f, sinf(-rot) };
|
||||||
|
|
||||||
Vector3 desiredDir = (Vector3){ input.x*right.x + input.y*front.x, 0.0f, input.x*right.z + input.y*front.z, };
|
Vector3 desiredDir = (Vector3){ input.x*right.x + input.y*front.x, 0.0f, input.x*right.z + input.y*front.z, };
|
||||||
body->dir = Vector3Lerp(body->dir, desiredDir, CONTROL*delta);
|
body->dir = Vector3Lerp(body->dir, desiredDir, CONTROL*delta);
|
||||||
|
|
@ -267,8 +267,8 @@ static void UpdateCameraFPS(Camera *camera)
|
||||||
|
|
||||||
// Head animation
|
// Head animation
|
||||||
// Rotate up direction around forward axis
|
// Rotate up direction around forward axis
|
||||||
float headSin = sin(headTimer*PI);
|
float headSin = sinf(headTimer*PI);
|
||||||
float headCos = cos(headTimer*PI);
|
float headCos = cosf(headTimer*PI);
|
||||||
const float stepRotation = 0.01f;
|
const float stepRotation = 0.01f;
|
||||||
camera->up = Vector3RotateByAxisAngle(up, pitch, headSin*stepRotation + lean.x);
|
camera->up = Vector3RotateByAxisAngle(up, pitch, headSin*stepRotation + lean.x);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ int main(void)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
UpdateCamera(&camera, CAMERA_FREE);
|
UpdateCamera(&camera, CAMERA_FREE);
|
||||||
|
|
||||||
if (IsKeyPressed('Z')) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
if (IsKeyPressed(KEY_Z)) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
|
|
||||||
208
examples/core/core_clipboard_text.c
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - clipboard text
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Robin (@RobinsAviary)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - clipboard text");
|
||||||
|
|
||||||
|
const char* clipboardText = NULL;
|
||||||
|
|
||||||
|
// List of text the user can switch through and copy
|
||||||
|
const char* copyableText[] = {"raylib is fun", "hello, clipboard!", "potato chips"};
|
||||||
|
|
||||||
|
unsigned int textIndex = 0;
|
||||||
|
|
||||||
|
const char* popupText = NULL;
|
||||||
|
|
||||||
|
// Initialize timers
|
||||||
|
// The amount of time the pop-up text is on screen, before fading
|
||||||
|
const float maxTime = 3.0f;
|
||||||
|
float textTimer = 0.0f;
|
||||||
|
// The length of time text is offset
|
||||||
|
const float animMaxTime = 0.1f;
|
||||||
|
float pasteAnim = 0.0f;
|
||||||
|
float copyAnim = 0.0f;
|
||||||
|
int copyAnimMult = 1;
|
||||||
|
float textAnim = 0.0f;
|
||||||
|
float textAlpha = 0.0f;
|
||||||
|
// Offset amount for animations
|
||||||
|
const int offsetAmount = -4;
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Check if the user has pressed the copy/paste key combinations
|
||||||
|
bool pastePressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_V));
|
||||||
|
bool copyPressed = (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C));
|
||||||
|
|
||||||
|
// Update animation timers
|
||||||
|
if (textTimer > 0) textTimer -= GetFrameTime();
|
||||||
|
if (pasteAnim > 0) pasteAnim -= GetFrameTime();
|
||||||
|
if (copyAnim > 0) copyAnim -= GetFrameTime();
|
||||||
|
if (textAnim > 0) textAnim -= GetFrameTime();
|
||||||
|
|
||||||
|
// React to the user pressing paste
|
||||||
|
if (pastePressed)
|
||||||
|
{
|
||||||
|
// Most operating systems hide this information until the user presses Ctrl-V on the window.
|
||||||
|
|
||||||
|
// Check to see if the clipboard contains an image
|
||||||
|
// This function does nothing outside of Windows, as it directly calls the Windows API
|
||||||
|
Image image = GetClipboardImage();
|
||||||
|
|
||||||
|
if (IsImageValid(image))
|
||||||
|
{
|
||||||
|
// Unload the image
|
||||||
|
UnloadImage(image);
|
||||||
|
// Update visuals
|
||||||
|
popupText = "clipboard contains image";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get text from the user's clipboard
|
||||||
|
clipboardText = GetClipboardText();
|
||||||
|
|
||||||
|
// Update visuals
|
||||||
|
popupText = "text pasted";
|
||||||
|
pasteAnim = animMaxTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset animation values
|
||||||
|
textTimer = maxTime;
|
||||||
|
textAnim = animMaxTime;
|
||||||
|
textAlpha = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// React to the user pressing copy
|
||||||
|
if (copyPressed)
|
||||||
|
{
|
||||||
|
// Set the text on the user's clipboard
|
||||||
|
SetClipboardText(copyableText[textIndex]);
|
||||||
|
|
||||||
|
// Reset values
|
||||||
|
textTimer = maxTime;
|
||||||
|
textAnim = animMaxTime;
|
||||||
|
copyAnim = animMaxTime;
|
||||||
|
copyAnimMult = 1;
|
||||||
|
textAlpha = 1;
|
||||||
|
// Update the text that pops up at the bottom of the screen
|
||||||
|
popupText = "text copied";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch to the next item in the list when the user presses up
|
||||||
|
if (IsKeyPressed(KEY_UP))
|
||||||
|
{
|
||||||
|
// Reset animation
|
||||||
|
copyAnim = animMaxTime;
|
||||||
|
copyAnimMult = 1;
|
||||||
|
|
||||||
|
textIndex += 1;
|
||||||
|
|
||||||
|
if (textIndex >= sizeof(copyableText) / sizeof(const char*)) // Length of array
|
||||||
|
{
|
||||||
|
// Loop back to the other end
|
||||||
|
textIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch to the previous item in the list when the user presses down
|
||||||
|
if (IsKeyPressed(KEY_DOWN))
|
||||||
|
{
|
||||||
|
// Reset animation
|
||||||
|
copyAnim = animMaxTime;
|
||||||
|
copyAnimMult = -1;
|
||||||
|
|
||||||
|
if (textIndex == 0)
|
||||||
|
{
|
||||||
|
// Loop back to the other end
|
||||||
|
textIndex = (sizeof(copyableText) / sizeof(const char*)) - 1; // Length of array minus one
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textIndex -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// Draw the user's pasted text, if there is any yet
|
||||||
|
if (clipboardText)
|
||||||
|
{
|
||||||
|
// Offset animation
|
||||||
|
int offset = 0;
|
||||||
|
if (pasteAnim > 0) offset = offsetAmount;
|
||||||
|
|
||||||
|
// Draw the pasted text
|
||||||
|
DrawText("pasted clipboard:", 10, 10 + offset, 20, DARKGREEN);
|
||||||
|
DrawText(clipboardText, 10, 30 + offset, 20, DARKGRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset animation
|
||||||
|
int textOffset = 0;
|
||||||
|
if (copyAnim > 0) textOffset = offsetAmount;
|
||||||
|
|
||||||
|
// Draw copyable text and controls
|
||||||
|
DrawText(copyableText[textIndex], 10, 330 + (textOffset * copyAnimMult), 20, MAROON);
|
||||||
|
DrawText("up/down to change string, ctrl-c to copy, ctrl-v to paste", 10, 355, 20, DARKGRAY);
|
||||||
|
|
||||||
|
// Alpha / Offset animation
|
||||||
|
if (textAlpha > 0)
|
||||||
|
{
|
||||||
|
// Offset animation
|
||||||
|
int offset = 0;
|
||||||
|
if (textAnim > 0) offset = offsetAmount;
|
||||||
|
// Draw pop up text
|
||||||
|
DrawText(popupText, 10, 425 + offset, 20, ColorAlpha(DARKGREEN, textAlpha));
|
||||||
|
|
||||||
|
// Fade-out animation
|
||||||
|
if (textTimer < 0)
|
||||||
|
{
|
||||||
|
textAlpha -= GetFrameTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/core/core_clipboard_text.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
112
examples/core/core_delta_time.c
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - delta time
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Robin (@RobinsAviary)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - delta time");
|
||||||
|
|
||||||
|
int currentFps = 60;
|
||||||
|
|
||||||
|
// Store the position for the both of the circles
|
||||||
|
Vector2 deltaCircle = { 0, (float)screenHeight/3.0f };
|
||||||
|
Vector2 frameCircle = { 0, (float)screenHeight*(2.0f/3.0f) };
|
||||||
|
|
||||||
|
// The speed applied to both circles
|
||||||
|
const float speed = 10.0f;
|
||||||
|
const float circleRadius = 32.0f;
|
||||||
|
|
||||||
|
SetTargetFPS(currentFps);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Adjust the FPS target based on the mouse wheel
|
||||||
|
float mouseWheel = GetMouseWheelMove();
|
||||||
|
if (mouseWheel != 0)
|
||||||
|
{
|
||||||
|
currentFps += (int)mouseWheel;
|
||||||
|
if (currentFps < 0) currentFps = 0;
|
||||||
|
SetTargetFPS(currentFps);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFrameTime() returns the time it took to draw the last frame, in seconds (usually called delta time)
|
||||||
|
// Uses the delta time to make the circle look like it's moving at a "consistent" speed regardless of FPS
|
||||||
|
|
||||||
|
// Multiply by 6.0 (an arbitrary value) in order to make the speed
|
||||||
|
// visually closer to the other circle (at 60 fps), for comparison
|
||||||
|
deltaCircle.x += GetFrameTime()*6.0f*speed;
|
||||||
|
// This circle can move faster or slower visually depending on the FPS
|
||||||
|
frameCircle.x += 0.1f*speed;
|
||||||
|
|
||||||
|
// If either circle is off the screen, reset it back to the start
|
||||||
|
if (deltaCircle.x > screenWidth) deltaCircle.x = 0;
|
||||||
|
if (frameCircle.x > screenWidth) frameCircle.x = 0;
|
||||||
|
|
||||||
|
// Reset both circles positions
|
||||||
|
if (IsKeyPressed(KEY_R))
|
||||||
|
{
|
||||||
|
deltaCircle.x = 0;
|
||||||
|
frameCircle.x = 0;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// Draw both circles to the screen
|
||||||
|
DrawCircleV(deltaCircle, circleRadius, RED);
|
||||||
|
DrawCircleV(frameCircle, circleRadius, BLUE);
|
||||||
|
|
||||||
|
// Draw the help text
|
||||||
|
// Determine what help text to show depending on the current FPS target
|
||||||
|
const char *fpsText = 0;
|
||||||
|
if (currentFps <= 0) fpsText = TextFormat("FPS: unlimited (%i)", GetFPS());
|
||||||
|
else fpsText = TextFormat("FPS: %i (target: %i)", GetFPS(), currentFps);
|
||||||
|
DrawText(fpsText, 10, 10, 20, DARKGRAY);
|
||||||
|
DrawText(TextFormat("Frame time: %02.02f ms", GetFrameTime()), 10, 30, 20, DARKGRAY);
|
||||||
|
DrawText("Use the scroll wheel to change the fps limit, r to reset", 10, 50, 20, DARKGRAY);
|
||||||
|
|
||||||
|
// Draw the text above the circles
|
||||||
|
DrawText("FUNC: x += GetFrameTime()*speed", 10, 90, 20, RED);
|
||||||
|
DrawText("FUNC: x += speed", 10, 240, 20, BLUE);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/core/core_delta_time.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
103
examples/core/core_directory_files.c
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - directory files
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Hugo ARNAL (@hugoarnal) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Hugo ARNAL (@hugoarnal)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "raygui.h" // Required for GUI controls
|
||||||
|
|
||||||
|
#include <string.h> // Required for: strcpy()
|
||||||
|
|
||||||
|
#define MAX_FILEPATH_SIZE 2048
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - directory files");
|
||||||
|
|
||||||
|
char directory[MAX_FILEPATH_SIZE] = { 0 };
|
||||||
|
strcpy(directory, GetWorkingDirectory());
|
||||||
|
|
||||||
|
FilePathList files = LoadDirectoryFiles(directory);
|
||||||
|
|
||||||
|
int btnBackPressed = false;
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (btnBackPressed)
|
||||||
|
{
|
||||||
|
strcpy(directory, GetPrevDirectoryPath(directory));
|
||||||
|
UnloadDirectoryFiles(files);
|
||||||
|
files = LoadDirectoryFiles(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
DrawText(directory, 100, 40, 20, DARKGRAY);
|
||||||
|
|
||||||
|
btnBackPressed = GuiButton((Rectangle){ 40.0f, 40.0f, 20, 20 }, "<");
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)files.count; i++)
|
||||||
|
{
|
||||||
|
Color color = Fade(LIGHTGRAY, 0.3f);
|
||||||
|
|
||||||
|
if (!IsPathFile(files.paths[i]))
|
||||||
|
{
|
||||||
|
if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, ""))
|
||||||
|
{
|
||||||
|
strcpy(directory, files.paths[i]);
|
||||||
|
UnloadDirectoryFiles(files);
|
||||||
|
files = LoadDirectoryFiles(directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawRectangle(0, 85 + 40*i, screenWidth, 40, color);
|
||||||
|
DrawText(GetFileName(files.paths[i]), 120, 100 + 40*i, 10, GRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadDirectoryFiles(files);
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/core/core_directory_files.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
70
examples/core/core_highdpi_testbed.c
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - highdpi testbed
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by Ramon Santamaria (@raysan5) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
|
||||||
|
|
||||||
|
// TODO: Load resources / Initialize variables at this point
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// TODO: Update variables / Implement example logic at this point
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// TODO: Draw everything that requires to be drawn at this point
|
||||||
|
|
||||||
|
DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
|
||||||
|
DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
|
||||||
|
DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// TODO: Unload all loaded resources at this point
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/core/core_highdpi_testbed.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
197
examples/core/core_input_actions.c
Normal file
|
|
@ -0,0 +1,197 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - input actions
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Jett (@JettMonstersGoBoom) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Jett (@JettMonstersGoBoom)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
// Simple example for decoding input as actions, allowing remapping of input to different keys or gamepad buttons
|
||||||
|
// For example instead of using `IsKeyDown(KEY_LEFT)`, you can use `IsActionDown(ACTION_LEFT)`
|
||||||
|
// which can be reassigned to e.g. KEY_A and also assigned to a gamepad button. the action will trigger with either gamepad or keys
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef enum ActionType {
|
||||||
|
NO_ACTION = 0,
|
||||||
|
ACTION_UP,
|
||||||
|
ACTION_DOWN,
|
||||||
|
ACTION_LEFT,
|
||||||
|
ACTION_RIGHT,
|
||||||
|
ACTION_FIRE,
|
||||||
|
MAX_ACTION
|
||||||
|
} ActionType;
|
||||||
|
|
||||||
|
// Key and button inputs
|
||||||
|
typedef struct ActionInput {
|
||||||
|
int key;
|
||||||
|
int button;
|
||||||
|
} ActionInput;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Global Variables Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
static int gamepadIndex = 0; // Gamepad default index
|
||||||
|
static ActionInput actionInputs[MAX_ACTION] = { 0 };
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
static bool IsActionPressed(int action); // Check action key/button pressed
|
||||||
|
static bool IsActionReleased(int action); // Check action key/button released
|
||||||
|
static bool IsActionDown(int action); // Check action key/button down
|
||||||
|
|
||||||
|
static void SetActionsDefault(void); // Set the "default" keyset
|
||||||
|
static void SetActionsCursor(void); // Set the "alternate" keyset
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - input actions");
|
||||||
|
|
||||||
|
// Set default actions
|
||||||
|
char actionSet = 0;
|
||||||
|
SetActionsDefault();
|
||||||
|
|
||||||
|
Vector2 position = (Vector2){ 400.0f, 200.0f };
|
||||||
|
Vector2 size = (Vector2){ 40.0f, 40.0f };
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
gamepadIndex = 0; // set this to gamepad being checked
|
||||||
|
if (IsActionDown(ACTION_UP)) position.y -= 2;
|
||||||
|
if (IsActionDown(ACTION_DOWN)) position.y += 2;
|
||||||
|
if (IsActionDown(ACTION_LEFT)) position.x -= 2;
|
||||||
|
if (IsActionDown(ACTION_RIGHT)) position.x += 2;
|
||||||
|
if (IsActionPressed(ACTION_FIRE))
|
||||||
|
{
|
||||||
|
position.x = (screenWidth-size.x)/2;
|
||||||
|
position.y = (screenHeight-size.y)/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch control scheme by pressing TAB
|
||||||
|
if (IsKeyPressed(KEY_TAB))
|
||||||
|
{
|
||||||
|
actionSet = !actionSet;
|
||||||
|
if (actionSet == 0) SetActionsDefault();
|
||||||
|
else SetActionsCursor();
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(GRAY);
|
||||||
|
|
||||||
|
DrawRectangleV(position, size, RED);
|
||||||
|
|
||||||
|
DrawText((actionSet == 0)? "Current input set: WASD (default)" : "Current input set: Cursor", 10, 10, 20, WHITE);
|
||||||
|
DrawText("Use TAB key to toggles Actions keyset", 10, 50, 20, GREEN);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Check action key/button pressed
|
||||||
|
// NOTE: Combines key pressed and gamepad button pressed in one action
|
||||||
|
static bool IsActionPressed(int action)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (action < MAX_ACTION) result = (IsKeyPressed(actionInputs[action].key) || IsGamepadButtonPressed(gamepadIndex, actionInputs[action].button));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check action key/button released
|
||||||
|
// NOTE: Combines key released and gamepad button released in one action
|
||||||
|
static bool IsActionReleased(int action)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (action < MAX_ACTION) result = (IsKeyReleased(actionInputs[action].key) || IsGamepadButtonReleased(gamepadIndex, actionInputs[action].button));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check action key/button down
|
||||||
|
// NOTE: Combines key down and gamepad button down in one action
|
||||||
|
static bool IsActionDown(int action)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (action < MAX_ACTION) result = (IsKeyDown(actionInputs[action].key) || IsGamepadButtonDown(gamepadIndex, actionInputs[action].button));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the "default" keyset
|
||||||
|
// NOTE: Here WASD and gamepad buttons on the left side for movement
|
||||||
|
static void SetActionsDefault(void)
|
||||||
|
{
|
||||||
|
actionInputs[ACTION_UP].key = KEY_W;
|
||||||
|
actionInputs[ACTION_DOWN].key = KEY_S;
|
||||||
|
actionInputs[ACTION_LEFT].key = KEY_A;
|
||||||
|
actionInputs[ACTION_RIGHT].key = KEY_D;
|
||||||
|
actionInputs[ACTION_FIRE].key = KEY_SPACE;
|
||||||
|
|
||||||
|
actionInputs[ACTION_UP].button = GAMEPAD_BUTTON_LEFT_FACE_UP;
|
||||||
|
actionInputs[ACTION_DOWN].button = GAMEPAD_BUTTON_LEFT_FACE_DOWN;
|
||||||
|
actionInputs[ACTION_LEFT].button = GAMEPAD_BUTTON_LEFT_FACE_LEFT;
|
||||||
|
actionInputs[ACTION_RIGHT].button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT;
|
||||||
|
actionInputs[ACTION_FIRE].button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the "alternate" keyset
|
||||||
|
// NOTE: Here cursor keys and gamepad buttons on the right side for movement
|
||||||
|
static void SetActionsCursor(void)
|
||||||
|
{
|
||||||
|
actionInputs[ACTION_UP].key = KEY_UP;
|
||||||
|
actionInputs[ACTION_DOWN].key = KEY_DOWN;
|
||||||
|
actionInputs[ACTION_LEFT].key = KEY_LEFT;
|
||||||
|
actionInputs[ACTION_RIGHT].key = KEY_RIGHT;
|
||||||
|
actionInputs[ACTION_FIRE].key = KEY_SPACE;
|
||||||
|
|
||||||
|
actionInputs[ACTION_UP].button = GAMEPAD_BUTTON_RIGHT_FACE_UP;
|
||||||
|
actionInputs[ACTION_DOWN].button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN;
|
||||||
|
actionInputs[ACTION_LEFT].button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT;
|
||||||
|
actionInputs[ACTION_RIGHT].button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT;
|
||||||
|
actionInputs[ACTION_FIRE].button = GAMEPAD_BUTTON_LEFT_FACE_DOWN;
|
||||||
|
}
|
||||||
BIN
examples/core/core_input_actions.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -177,33 +177,33 @@ int main(void)
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
// Draw common elements
|
// Draw common elements
|
||||||
DrawText("*", messagePosition.x + 5, messagePosition.y + 5, 10, BLACK);
|
DrawText("*", (int)messagePosition.x + 5, (int)messagePosition.y + 5, 10, BLACK);
|
||||||
DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", messagePosition.x + 15, messagePosition.y + 5, 10, BLACK);
|
DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", (int)messagePosition.x + 15, (int)messagePosition.y + 5, 10, BLACK);
|
||||||
DrawText("*", messagePosition.x + 5, messagePosition.y + 35, 10, BLACK);
|
DrawText("*", (int)messagePosition.x + 5, (int)messagePosition.y + 35, 10, BLACK);
|
||||||
DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.", messagePosition.x + 15, messagePosition.y + 35, 10, BLACK);
|
DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.", (int)messagePosition.x + 15, (int)messagePosition.y + 35, 10, BLACK);
|
||||||
|
|
||||||
// Draw last gesture
|
// Draw last gesture
|
||||||
DrawText("Last gesture", lastGesturePosition.x + 33, lastGesturePosition.y - 47, 20, BLACK);
|
DrawText("Last gesture", (int)lastGesturePosition.x + 33, (int)lastGesturePosition.y - 47, 20, BLACK);
|
||||||
DrawText("Swipe Tap Pinch Touch", lastGesturePosition.x + 17, lastGesturePosition.y - 18, 10, BLACK);
|
DrawText("Swipe Tap Pinch Touch", (int)lastGesturePosition.x + 17, (int)lastGesturePosition.y - 18, 10, BLACK);
|
||||||
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y, 20, 20, lastGesture == GESTURE_SWIPE_UP ? RED : LIGHTGRAY);
|
DrawRectangle((int)lastGesturePosition.x + 20, (int)lastGesturePosition.y, 20, 20, lastGesture == GESTURE_SWIPE_UP ? RED : LIGHTGRAY);
|
||||||
DrawRectangle(lastGesturePosition.x, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_LEFT ? RED : LIGHTGRAY);
|
DrawRectangle((int)lastGesturePosition.x, (int)lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_LEFT ? RED : LIGHTGRAY);
|
||||||
DrawRectangle(lastGesturePosition.x + 40, lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_RIGHT ? RED : LIGHTGRAY);
|
DrawRectangle((int)lastGesturePosition.x + 40, (int)lastGesturePosition.y + 20, 20, 20, lastGesture == GESTURE_SWIPE_RIGHT ? RED : LIGHTGRAY);
|
||||||
DrawRectangle(lastGesturePosition.x + 20, lastGesturePosition.y + 40, 20, 20, lastGesture == GESTURE_SWIPE_DOWN ? RED : LIGHTGRAY);
|
DrawRectangle((int)lastGesturePosition.x + 20, (int)lastGesturePosition.y + 40, 20, 20, lastGesture == GESTURE_SWIPE_DOWN ? RED : LIGHTGRAY);
|
||||||
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 16, 10, lastGesture == GESTURE_TAP ? BLUE : LIGHTGRAY);
|
DrawCircle((int)lastGesturePosition.x + 80, (int)lastGesturePosition.y + 16, 10, lastGesture == GESTURE_TAP ? BLUE : LIGHTGRAY);
|
||||||
DrawRing( (Vector2){lastGesturePosition.x + 103, lastGesturePosition.y + 16}, 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == GESTURE_DRAG ? LIME : LIGHTGRAY);
|
DrawRing( (Vector2){lastGesturePosition.x + 103, lastGesturePosition.y + 16}, 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == GESTURE_DRAG ? LIME : LIGHTGRAY);
|
||||||
DrawCircle(lastGesturePosition.x + 80, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
|
DrawCircle((int)lastGesturePosition.x + 80, (int)lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
|
||||||
DrawCircle(lastGesturePosition.x + 103, lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
|
DrawCircle((int)lastGesturePosition.x + 103, (int)lastGesturePosition.y + 43, 10, lastGesture == GESTURE_DOUBLETAP ? SKYBLUE : LIGHTGRAY);
|
||||||
DrawTriangle((Vector2){ lastGesturePosition.x + 122, lastGesturePosition.y + 16 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 26 }, (Vector2){lastGesturePosition.x + 137, lastGesturePosition.y + 6 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
|
DrawTriangle((Vector2){ lastGesturePosition.x + 122, lastGesturePosition.y + 16 }, (Vector2){ lastGesturePosition.x + 137, lastGesturePosition.y + 26 }, (Vector2){lastGesturePosition.x + 137, lastGesturePosition.y + 6 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
|
||||||
DrawTriangle((Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 6 }, (Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 162, lastGesturePosition.y + 16 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
|
DrawTriangle((Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 6 }, (Vector2){ lastGesturePosition.x + 147, lastGesturePosition.y + 26 }, (Vector2){ lastGesturePosition.x + 162, lastGesturePosition.y + 16 }, lastGesture == GESTURE_PINCH_OUT? ORANGE : LIGHTGRAY);
|
||||||
DrawTriangle((Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 33 }, (Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 140, lastGesturePosition.y + 43 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
|
DrawTriangle((Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 33 }, (Vector2){ lastGesturePosition.x + 125, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 140, lastGesturePosition.y + 43 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
|
||||||
DrawTriangle((Vector2){ lastGesturePosition.x + 144, lastGesturePosition.y + 43 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 33 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
|
DrawTriangle((Vector2){ lastGesturePosition.x + 144, lastGesturePosition.y + 43 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 53 }, (Vector2){ lastGesturePosition.x + 159, lastGesturePosition.y + 33 }, lastGesture == GESTURE_PINCH_IN? VIOLET : LIGHTGRAY);
|
||||||
for (i = 0; i < 4; i++) DrawCircle(lastGesturePosition.x + 180, lastGesturePosition.y + 7 + i*15, 5, touchCount <= i? LIGHTGRAY : gestureColor);
|
for (i = 0; i < 4; i++) DrawCircle((int)lastGesturePosition.x + 180, (int)lastGesturePosition.y + 7 + i*15, 5, touchCount <= i? LIGHTGRAY : gestureColor);
|
||||||
|
|
||||||
// Draw gesture log
|
// Draw gesture log
|
||||||
DrawText("Log", gestureLogPosition.x, gestureLogPosition.y, 20, BLACK);
|
DrawText("Log", (int)gestureLogPosition.x, (int)gestureLogPosition.y, 20, BLACK);
|
||||||
|
|
||||||
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
|
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
|
||||||
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], gestureLogPosition.x, gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
|
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE) DrawText(gestureLog[ii], (int)gestureLogPosition.x, (int)gestureLogPosition.y + 410 - i*20, 20, (i == 0 ? gestureColor : LIGHTGRAY));
|
||||||
Color logButton1Color, logButton2Color;
|
Color logButton1Color, logButton2Color;
|
||||||
switch (logMode)
|
switch (logMode)
|
||||||
{
|
{
|
||||||
|
|
@ -213,31 +213,31 @@ int main(void)
|
||||||
default: logButton1Color=GRAY; logButton2Color=GRAY; break;
|
default: logButton1Color=GRAY; logButton2Color=GRAY; break;
|
||||||
}
|
}
|
||||||
DrawRectangleRec(logButton1, logButton1Color);
|
DrawRectangleRec(logButton1, logButton1Color);
|
||||||
DrawText("Hide", logButton1.x + 7, logButton1.y + 3, 10, WHITE);
|
DrawText("Hide", (int)logButton1.x + 7, (int)logButton1.y + 3, 10, WHITE);
|
||||||
DrawText("Repeat", logButton1.x + 7, logButton1.y + 13, 10, WHITE);
|
DrawText("Repeat", (int)logButton1.x + 7, (int)logButton1.y + 13, 10, WHITE);
|
||||||
DrawRectangleRec(logButton2, logButton2Color);
|
DrawRectangleRec(logButton2, logButton2Color);
|
||||||
DrawText("Hide", logButton1.x + 62, logButton1.y + 3, 10, WHITE);
|
DrawText("Hide", (int)logButton1.x + 62, (int)logButton1.y + 3, 10, WHITE);
|
||||||
DrawText("Hold", logButton1.x + 62, logButton1.y + 13, 10, WHITE);
|
DrawText("Hold", (int)logButton1.x + 62, (int)logButton1.y + 13, 10, WHITE);
|
||||||
|
|
||||||
// Draw protractor
|
// Draw protractor
|
||||||
DrawText("Angle", protractorPosition.x + 55, protractorPosition.y + 76, 10, BLACK);
|
DrawText("Angle", (int)protractorPosition.x + 55, (int)protractorPosition.y + 76, 10, BLACK);
|
||||||
const char *angleString = TextFormat("%f", currentAngleDegrees);
|
const char *angleString = TextFormat("%f", currentAngleDegrees);
|
||||||
const int angleStringDot = TextFindIndex(angleString, ".");
|
const int angleStringDot = TextFindIndex(angleString, ".");
|
||||||
const char *angleStringTrim = TextSubtext(angleString, 0, angleStringDot + 3);
|
const char *angleStringTrim = TextSubtext(angleString, 0, angleStringDot + 3);
|
||||||
DrawText( angleStringTrim, protractorPosition.x + 55, protractorPosition.y + 92, 20, gestureColor);
|
DrawText( angleStringTrim, (int)protractorPosition.x + 55, (int)protractorPosition.y + 92, 20, gestureColor);
|
||||||
DrawCircle(protractorPosition.x, protractorPosition.y, 80.0f, WHITE);
|
DrawCircleV(protractorPosition, 80.0f, WHITE);
|
||||||
DrawLineEx((Vector2){ protractorPosition.x - 90, protractorPosition.y }, (Vector2){ protractorPosition.x + 90, protractorPosition.y }, 3.0f, LIGHTGRAY);
|
DrawLineEx((Vector2){ protractorPosition.x - 90, protractorPosition.y }, (Vector2){ protractorPosition.x + 90, protractorPosition.y }, 3.0f, LIGHTGRAY);
|
||||||
DrawLineEx((Vector2){ protractorPosition.x, protractorPosition.y - 90 }, (Vector2){ protractorPosition.x, protractorPosition.y + 90 }, 3.0f, LIGHTGRAY);
|
DrawLineEx((Vector2){ protractorPosition.x, protractorPosition.y - 90 }, (Vector2){ protractorPosition.x, protractorPosition.y + 90 }, 3.0f, LIGHTGRAY);
|
||||||
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y - 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y + 45 }, 3.0f, GREEN);
|
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y - 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y + 45 }, 3.0f, GREEN);
|
||||||
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y + 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y - 45 }, 3.0f, GREEN);
|
DrawLineEx((Vector2){ protractorPosition.x - 80, protractorPosition.y + 45 }, (Vector2){ protractorPosition.x + 80, protractorPosition.y - 45 }, 3.0f, GREEN);
|
||||||
DrawText("0", protractorPosition.x + 96, protractorPosition.y - 9, 20, BLACK);
|
DrawText("0", (int)protractorPosition.x + 96, (int)protractorPosition.y - 9, 20, BLACK);
|
||||||
DrawText("30", protractorPosition.x + 74, protractorPosition.y - 68, 20, BLACK);
|
DrawText("30", (int)protractorPosition.x + 74, (int)protractorPosition.y - 68, 20, BLACK);
|
||||||
DrawText("90", protractorPosition.x - 11, protractorPosition.y - 110, 20, BLACK);
|
DrawText("90", (int)protractorPosition.x - 11, (int)protractorPosition.y - 110, 20, BLACK);
|
||||||
DrawText("150", protractorPosition.x - 100, protractorPosition.y - 68, 20, BLACK);
|
DrawText("150", (int)protractorPosition.x - 100, (int)protractorPosition.y - 68, 20, BLACK);
|
||||||
DrawText("180", protractorPosition.x - 124, protractorPosition.y - 9, 20, BLACK);
|
DrawText("180", (int)protractorPosition.x - 124, (int)protractorPosition.y - 9, 20, BLACK);
|
||||||
DrawText("210", protractorPosition.x - 100, protractorPosition.y + 50, 20, BLACK);
|
DrawText("210", (int)protractorPosition.x - 100, (int)protractorPosition.y + 50, 20, BLACK);
|
||||||
DrawText("270", protractorPosition.x - 18, protractorPosition.y + 92, 20, BLACK);
|
DrawText("270", (int)protractorPosition.x - 18, (int)protractorPosition.y + 92, 20, BLACK);
|
||||||
DrawText("330", protractorPosition.x + 72, protractorPosition.y + 50, 20, BLACK);
|
DrawText("330", (int)protractorPosition.x + 72, (int)protractorPosition.y + 50, 20, BLACK);
|
||||||
if (currentAngleDegrees != 0.0f) DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
|
if (currentAngleDegrees != 0.0f) DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
|
||||||
|
|
||||||
// Draw touch and mouse pointer points
|
// Draw touch and mouse pointer points
|
||||||
|
|
@ -251,7 +251,7 @@ int main(void)
|
||||||
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
|
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (touchCount == 2) DrawLineEx(touchPosition[0], touchPosition[1], ((currentGesture == 512)? 8 : 12), gestureColor);
|
if (touchCount == 2) DrawLineEx(touchPosition[0], touchPosition[1], ((currentGesture == 512)? 8.0f : 12.0f), gestureColor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ int main(void)
|
||||||
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);
|
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);
|
||||||
DrawText("Press 'H' to toggle cursor visibility", 10, 30, 20, DARKGRAY);
|
DrawText("Press 'H' to toggle cursor visibility", 10, 30, 20, DARKGRAY);
|
||||||
|
|
||||||
if (!IsCursorHidden()) DrawText("CURSOR HIDDEN", 20, 60, 20, RED);
|
if (IsCursorHidden()) DrawText("CURSOR HIDDEN", 20, 60, 20, RED);
|
||||||
else DrawText("CURSOR VISIBLE", 20, 60, 20, LIME);
|
else DrawText("CURSOR VISIBLE", 20, 60, 20, LIME);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|
|
||||||
169
examples/core/core_monitor_detector.c
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - monitor detector
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Maicon Santana (@maiconpintoabreu) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Maicon Santana (@maiconpintoabreu)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#define MAX_MONITORS 10
|
||||||
|
|
||||||
|
// Monitor info
|
||||||
|
typedef struct MonitorInfo {
|
||||||
|
Vector2 position;
|
||||||
|
const char *name;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int physicalWidth;
|
||||||
|
int physicalHeight;
|
||||||
|
int refreshRate;
|
||||||
|
} MonitorInfo;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
MonitorInfo monitors[MAX_MONITORS] = { 0 };
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - monitor detector");
|
||||||
|
|
||||||
|
int currentMonitorIndex = GetCurrentMonitor();
|
||||||
|
int monitorCount = 0;
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Variables to find the max x and Y to calculate the scale
|
||||||
|
int maxWidth = 1;
|
||||||
|
int maxHeight = 1;
|
||||||
|
|
||||||
|
// Monitor offset is to fix when monitor position x is negative
|
||||||
|
int monitorOffsetX = 0;
|
||||||
|
|
||||||
|
// Rebuild monitors array every frame
|
||||||
|
monitorCount = GetMonitorCount();
|
||||||
|
for (int i = 0; i < monitorCount; i++)
|
||||||
|
{
|
||||||
|
monitors[i] = (MonitorInfo){
|
||||||
|
GetMonitorPosition(i),
|
||||||
|
GetMonitorName(i),
|
||||||
|
GetMonitorWidth(i),
|
||||||
|
GetMonitorHeight(i),
|
||||||
|
GetMonitorPhysicalWidth(i),
|
||||||
|
GetMonitorPhysicalHeight(i),
|
||||||
|
GetMonitorRefreshRate(i)
|
||||||
|
};
|
||||||
|
if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = (int)monitors[i].position.x*-1;
|
||||||
|
|
||||||
|
const int width = (int)monitors[i].position.x + monitors[i].width;
|
||||||
|
const int height = (int)monitors[i].position.y + monitors[i].height;
|
||||||
|
|
||||||
|
if (maxWidth < width) maxWidth = width;
|
||||||
|
if (maxHeight < height) maxHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_ENTER) && monitorCount > 1)
|
||||||
|
{
|
||||||
|
currentMonitorIndex += 1;
|
||||||
|
|
||||||
|
// Set index to 0 if the last one
|
||||||
|
if(currentMonitorIndex == monitorCount) currentMonitorIndex = 0;
|
||||||
|
|
||||||
|
SetWindowMonitor(currentMonitorIndex); // Move window to currentMonitorIndex
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get currentMonitorIndex if manually moved
|
||||||
|
currentMonitorIndex = GetCurrentMonitor();
|
||||||
|
}
|
||||||
|
|
||||||
|
float monitorScale = 0.6f;
|
||||||
|
|
||||||
|
if(maxHeight > maxWidth + monitorOffsetX) monitorScale *= ((float)screenHeight/(float)maxHeight);
|
||||||
|
else monitorScale *= ((float)screenWidth/(float)(maxWidth + monitorOffsetX));
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
DrawText("Press [Enter] to move window to next monitor available", 20, 20, 20, DARKGRAY);
|
||||||
|
|
||||||
|
DrawRectangleLines(20, 60, screenWidth - 40, screenHeight - 100, DARKGRAY);
|
||||||
|
|
||||||
|
// Draw Monitor Rectangles with information inside
|
||||||
|
for (int i = 0; i < monitorCount; i++)
|
||||||
|
{
|
||||||
|
// Calculate retangle position and size using monitorScale
|
||||||
|
const Rectangle rec = (Rectangle){
|
||||||
|
(monitors[i].position.x + monitorOffsetX) * monitorScale + 140,
|
||||||
|
monitors[i].position.y * monitorScale + 80,
|
||||||
|
monitors[i].width * monitorScale,
|
||||||
|
monitors[i].height * monitorScale
|
||||||
|
};
|
||||||
|
|
||||||
|
// Draw monitor name and information inside the rectangle
|
||||||
|
DrawText(TextFormat("[%i] %s", i, monitors[i].name), (int)rec.x + 10, (int)rec.y + (int)(100*monitorScale), (int)(120*monitorScale), BLUE);
|
||||||
|
DrawText(
|
||||||
|
TextFormat("Resolution: [%ipx x %ipx]\nRefreshRate: [%ihz]\nPhysical Size: [%imm x %imm]\nPosition: %3.0f x %3.0f",
|
||||||
|
monitors[i].width,
|
||||||
|
monitors[i].height,
|
||||||
|
monitors[i].refreshRate,
|
||||||
|
monitors[i].physicalWidth,
|
||||||
|
monitors[i].physicalHeight,
|
||||||
|
monitors[i].position.x,
|
||||||
|
monitors[i].position.y
|
||||||
|
), (int)rec.x + 10, (int)rec.y + (int)(200*monitorScale), (int)(120*monitorScale), DARKGRAY);
|
||||||
|
|
||||||
|
// Highlight current monitor
|
||||||
|
if (i == currentMonitorIndex)
|
||||||
|
{
|
||||||
|
DrawRectangleLinesEx(rec, 5, RED);
|
||||||
|
Vector2 windowPosition = (Vector2){ (GetWindowPosition().x + monitorOffsetX)*monitorScale + 140, GetWindowPosition().y*monitorScale + 80 };
|
||||||
|
|
||||||
|
// Draw window position based on monitors
|
||||||
|
DrawRectangleV(windowPosition, (Vector2){screenWidth * monitorScale, screenHeight * monitorScale}, Fade(GREEN, 0.5));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawRectangleLinesEx(rec, 5, GRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/core/core_monitor_detector.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
|
@ -65,6 +65,7 @@ int main(void)
|
||||||
|
|
||||||
ClearBackground(SKYBLUE);
|
ClearBackground(SKYBLUE);
|
||||||
|
|
||||||
|
DrawRectangle(0, 0, 20, 20, RED);
|
||||||
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
|
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
|
||||||
|
|
||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
|
|
@ -75,11 +76,12 @@ int main(void)
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
// Draw our render texture with rotation applied
|
// Draw our render texture with rotation applied
|
||||||
// NOTE: We set the origin of the texture to the center of the render texture
|
// NOTE 1: We set the origin of the texture to the center of the render texture
|
||||||
|
// NOTE 2: We flip vertically the texture setting negative source rectangle height
|
||||||
DrawTexturePro(target.texture,
|
DrawTexturePro(target.texture,
|
||||||
(Rectangle){ 0, 0, target.texture.width, -target.texture.height },
|
(Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height },
|
||||||
(Rectangle){ screenWidth/2, screenHeight/2, target.texture.width, -target.texture.height },
|
(Rectangle){ screenWidth/2.0f, screenHeight/2.0f, (float)target.texture.width, (float)target.texture.height },
|
||||||
(Vector2){ target.texture.width/2, target.texture.height/2 }, rotation, WHITE);
|
(Vector2){ target.texture.width/2.0f, target.texture.height/2.0f }, rotation, WHITE);
|
||||||
|
|
||||||
DrawText("DRAWING BOUNCING BALL INSIDE RENDER TEXTURE!", 10, screenHeight - 40, 20, BLACK);
|
DrawText("DRAWING BOUNCING BALL INSIDE RENDER TEXTURE!", 10, screenHeight - 40, 20, BLACK);
|
||||||
|
|
||||||
|
|
|
||||||
70
examples/core/core_screen_recording.c
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - screen recording
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by Ramon Santamaria (@raysan5) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - screen recording");
|
||||||
|
|
||||||
|
// TODO: Load resources / Initialize variables at this point
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// TODO: Update variables / Implement example logic at this point
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// TODO: Draw everything that requires to be drawn at this point
|
||||||
|
|
||||||
|
DrawLineEx((Vector2){ 0, 0 }, (Vector2){ screenWidth, screenHeight }, 2.0f, RED);
|
||||||
|
DrawLineEx((Vector2){ 0, screenHeight }, (Vector2){ screenWidth, 0 }, 2.0f, RED);
|
||||||
|
DrawText("example base code template", 260, 400, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// TODO: Unload all loaded resources at this point
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/core/core_screen_recording.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
164
examples/core/core_text_file_loading.c
Normal file
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - text file loading
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Aanjishnu Bhattacharyya (@NimComPoo-04) 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) 0 Aanjishnu Bhattacharyya (@NimComPoo-04)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include "raymath.h" // Required for: Lerp()
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - text file loading");
|
||||||
|
|
||||||
|
// Setting up the camera
|
||||||
|
Camera2D cam = {
|
||||||
|
.offset = {0, 0},
|
||||||
|
.target = {0, 0},
|
||||||
|
.rotation = 0,
|
||||||
|
.zoom = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Loading text file from resources/text_file.txt
|
||||||
|
const char *fileName = "resources/text_file.txt";
|
||||||
|
char *text = LoadFileText(fileName);
|
||||||
|
|
||||||
|
// Loading all the text lines
|
||||||
|
int lineCount = 0;
|
||||||
|
char **lines = LoadTextLines(text, &lineCount);
|
||||||
|
|
||||||
|
// Stylistic choises
|
||||||
|
int fontSize = 20;
|
||||||
|
int textTop = 25 + fontSize; // Top of the screen from where the text is rendered
|
||||||
|
int wrapWidth = screenWidth - 20;
|
||||||
|
|
||||||
|
// Wrap the lines as needed
|
||||||
|
for (int i = 0; i < lineCount; i++)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
int lastSpace = 0; // Keeping track of last valid space to insert '\n'
|
||||||
|
int lastWrapStart = 0; // Keeping track of the start of this wrapped line.
|
||||||
|
|
||||||
|
while (lines[i][j] != '\0')
|
||||||
|
{
|
||||||
|
if (lines[i][j] == ' ')
|
||||||
|
{
|
||||||
|
// Making a C Style string by adding a '\0' at the required location so that we can use the MeasureText function
|
||||||
|
lines[i][j] = '\0';
|
||||||
|
|
||||||
|
// Checking if the text has crossed the wrapWidth, then going back and inserting a newline
|
||||||
|
if (MeasureText(lines[i] + lastWrapStart, fontSize) > wrapWidth)
|
||||||
|
{
|
||||||
|
lines[i][lastSpace] = '\n';
|
||||||
|
|
||||||
|
// Since we added a newline the place of wrap changed so we update our lastWrapStart
|
||||||
|
lastWrapStart = lastSpace + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines[i][j] = ' '; // Resetting the space back
|
||||||
|
lastSpace = j; // Since we encountered a new space we update our last encountered space location
|
||||||
|
}
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculating the total height so that we can show a scrollbar
|
||||||
|
int textHeight = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < lineCount; i++)
|
||||||
|
{
|
||||||
|
Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], (float)fontSize, 2);
|
||||||
|
textHeight += (int)size.y + 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A simple scrollbar on the side to show how far we have red into the file
|
||||||
|
Rectangle scrollBar = {
|
||||||
|
.x = (float)screenWidth - 5,
|
||||||
|
.y = 0,
|
||||||
|
.width = 5,
|
||||||
|
.height = screenHeight*100.0f/(textHeight - screenHeight) // Scrollbar height is just a percentage
|
||||||
|
};
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
float scroll = GetMouseWheelMove();
|
||||||
|
cam.target.y -= scroll*fontSize*1.5f; // Choosing an arbitrary speed for scroll
|
||||||
|
|
||||||
|
if (cam.target.y < 0) cam.target.y = 0; // Snapping to 0 if we go too far back
|
||||||
|
|
||||||
|
// Ensuring that the camera does not scroll past all text
|
||||||
|
if (cam.target.y > textHeight - screenHeight + textTop)
|
||||||
|
cam.target.y = (float)textHeight - screenHeight + textTop;
|
||||||
|
|
||||||
|
// Computing the position of the scrollBar depending on the percentage of text covered
|
||||||
|
scrollBar.y = Lerp((float)textTop, (float)screenHeight - scrollBar.height, (float)(cam.target.y - textTop)/(textHeight - screenHeight));
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode2D(cam);
|
||||||
|
// Going through all the read lines
|
||||||
|
for (int i = 0, t = textTop; i < lineCount; i++)
|
||||||
|
{
|
||||||
|
// Each time we go through and calculate the height of the text to move the cursor appropriately
|
||||||
|
Vector2 size = MeasureTextEx(GetFontDefault(), lines[i], (float)fontSize, 2);
|
||||||
|
|
||||||
|
DrawText(lines[i], 10, t, fontSize, RED);
|
||||||
|
|
||||||
|
// Inserting extra space for real newlines,
|
||||||
|
// wrapped lines are rendered closer together
|
||||||
|
t += (int)size.y + 10;
|
||||||
|
}
|
||||||
|
EndMode2D();
|
||||||
|
|
||||||
|
// Header displaying which file is being read currently
|
||||||
|
DrawRectangle(0, 0, screenWidth, textTop - 10, BEIGE);
|
||||||
|
DrawText(TextFormat("File: %s", fileName), 10, 10, fontSize, MAROON);
|
||||||
|
|
||||||
|
DrawRectangleRec(scrollBar, MAROON);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadTextLines(lines, lineCount);
|
||||||
|
UnloadFileText(text);
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/core/core_text_file_loading.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
|
@ -187,42 +187,42 @@ int main(void)
|
||||||
if (lastUndoIndex > firstUndoIndex)
|
if (lastUndoIndex > firstUndoIndex)
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
||||||
DrawRectangle(gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
|
DrawRectangleRec((Rectangle){gridPosition.x + states[i].cell.x * GRID_CELL_SIZE, gridPosition.y + states[i].cell.y * GRID_CELL_SIZE,
|
||||||
GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
|
GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY);
|
||||||
}
|
}
|
||||||
else if (firstUndoIndex > lastUndoIndex)
|
else if (firstUndoIndex > lastUndoIndex)
|
||||||
{
|
{
|
||||||
if ((currentUndoIndex < MAX_UNDO_STATES) && (currentUndoIndex > lastUndoIndex))
|
if ((currentUndoIndex < MAX_UNDO_STATES) && (currentUndoIndex > lastUndoIndex))
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
||||||
DrawRectangle(gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
|
DrawRectangleRec((Rectangle) { gridPosition.x + states[i].cell.x * GRID_CELL_SIZE, gridPosition.y + states[i].cell.y * GRID_CELL_SIZE,
|
||||||
GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
|
GRID_CELL_SIZE, GRID_CELL_SIZE }, LIGHTGRAY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
|
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
|
||||||
DrawRectangle(gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
|
DrawRectangle((int)gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, (int)gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
|
||||||
GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
|
GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
|
||||||
for (int i = 0; i < currentUndoIndex; i++)
|
for (int i = 0; i < currentUndoIndex; i++)
|
||||||
DrawRectangle(gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
|
DrawRectangle((int)gridPosition.x + states[i].cell.x*GRID_CELL_SIZE, (int)gridPosition.y + states[i].cell.y*GRID_CELL_SIZE,
|
||||||
GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
|
GRID_CELL_SIZE, GRID_CELL_SIZE, LIGHTGRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw game grid
|
// Draw game grid
|
||||||
for (int y = 0; y <= MAX_GRID_CELLS_Y; y++)
|
for (int y = 0; y <= MAX_GRID_CELLS_Y; y++)
|
||||||
DrawLine(gridPosition.x, gridPosition.y + y*GRID_CELL_SIZE,
|
DrawLine((int)gridPosition.x, (int)gridPosition.y + y*GRID_CELL_SIZE,
|
||||||
gridPosition.x + MAX_GRID_CELLS_X*GRID_CELL_SIZE, gridPosition.y + y*GRID_CELL_SIZE, GRAY);
|
(int)gridPosition.x + MAX_GRID_CELLS_X*GRID_CELL_SIZE, (int)gridPosition.y + y*GRID_CELL_SIZE, GRAY);
|
||||||
for (int x = 0; x <= MAX_GRID_CELLS_X; x++)
|
for (int x = 0; x <= MAX_GRID_CELLS_X; x++)
|
||||||
DrawLine(gridPosition.x + x*GRID_CELL_SIZE, gridPosition.y,
|
DrawLine((int)gridPosition.x + x*GRID_CELL_SIZE, (int)gridPosition.y,
|
||||||
gridPosition.x + x*GRID_CELL_SIZE, gridPosition.y + MAX_GRID_CELLS_Y*GRID_CELL_SIZE, GRAY);
|
(int)gridPosition.x + x*GRID_CELL_SIZE, (int)gridPosition.y + MAX_GRID_CELLS_Y*GRID_CELL_SIZE, GRAY);
|
||||||
|
|
||||||
// Draw player
|
// Draw player
|
||||||
DrawRectangle(gridPosition.x + player.cell.x*GRID_CELL_SIZE, gridPosition.y + player.cell.y*GRID_CELL_SIZE,
|
DrawRectangle((int)gridPosition.x + player.cell.x*GRID_CELL_SIZE, (int)gridPosition.y + player.cell.y*GRID_CELL_SIZE,
|
||||||
GRID_CELL_SIZE + 1, GRID_CELL_SIZE + 1, player.color);
|
GRID_CELL_SIZE + 1, GRID_CELL_SIZE + 1, player.color);
|
||||||
|
|
||||||
// Draw undo system buffer info
|
// Draw undo system buffer info
|
||||||
DrawText("UNDO STATES:", undoInfoPos.x - 85, undoInfoPos.y + 9, 10, DARKGRAY);
|
DrawText("UNDO STATES:", (int)undoInfoPos.x - 85, (int)undoInfoPos.y + 9, 10, DARKGRAY);
|
||||||
DrawUndoBuffer(undoInfoPos, firstUndoIndex, lastUndoIndex, currentUndoIndex, 24);
|
DrawUndoBuffer(undoInfoPos, firstUndoIndex, lastUndoIndex, currentUndoIndex, 24);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|
@ -247,15 +247,15 @@ int main(void)
|
||||||
static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoIndex, int currentUndoIndex, int slotSize)
|
static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoIndex, int currentUndoIndex, int slotSize)
|
||||||
{
|
{
|
||||||
// Draw index marks
|
// Draw index marks
|
||||||
DrawRectangle(position.x + 8 + slotSize*currentUndoIndex, position.y - 10, 8, 8, RED);
|
DrawRectangle((int)position.x + 8 + slotSize*currentUndoIndex, (int)position.y - 10, 8, 8, RED);
|
||||||
DrawRectangleLines(position.x + 2 + slotSize*firstUndoIndex, position.y + 27, 8, 8, BLACK);
|
DrawRectangleLines((int)position.x + 2 + slotSize*firstUndoIndex, (int)position.y + 27, 8, 8, BLACK);
|
||||||
DrawRectangle(position.x + 14 + slotSize*lastUndoIndex, position.y + 27, 8, 8, BLACK);
|
DrawRectangle((int)position.x + 14 + slotSize*lastUndoIndex, (int)position.y + 27, 8, 8, BLACK);
|
||||||
|
|
||||||
// Draw background gray slots
|
// Draw background gray slots
|
||||||
for (int i = 0; i < MAX_UNDO_STATES; i++)
|
for (int i = 0; i < MAX_UNDO_STATES; i++)
|
||||||
{
|
{
|
||||||
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, LIGHTGRAY);
|
DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, LIGHTGRAY);
|
||||||
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, GRAY);
|
DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, GRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw occupied slots: firstUndoIndex --> lastUndoIndex
|
// Draw occupied slots: firstUndoIndex --> lastUndoIndex
|
||||||
|
|
@ -263,22 +263,22 @@ static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoInd
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < lastUndoIndex + 1; i++)
|
for (int i = firstUndoIndex; i < lastUndoIndex + 1; i++)
|
||||||
{
|
{
|
||||||
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
|
DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, SKYBLUE);
|
||||||
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
|
DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, BLUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lastUndoIndex < firstUndoIndex)
|
else if (lastUndoIndex < firstUndoIndex)
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
|
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
|
||||||
{
|
{
|
||||||
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
|
DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, SKYBLUE);
|
||||||
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
|
DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, BLUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < lastUndoIndex + 1; i++)
|
for (int i = 0; i < lastUndoIndex + 1; i++)
|
||||||
{
|
{
|
||||||
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, SKYBLUE);
|
DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, SKYBLUE);
|
||||||
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, BLUE);
|
DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, BLUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,26 +287,26 @@ static void DrawUndoBuffer(Vector2 position, int firstUndoIndex, int lastUndoInd
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
||||||
{
|
{
|
||||||
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
|
DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, GREEN);
|
||||||
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
|
DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, LIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (currentUndoIndex < firstUndoIndex)
|
else if (currentUndoIndex < firstUndoIndex)
|
||||||
{
|
{
|
||||||
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
|
for (int i = firstUndoIndex; i < MAX_UNDO_STATES; i++)
|
||||||
{
|
{
|
||||||
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
|
DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, GREEN);
|
||||||
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
|
DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, LIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < currentUndoIndex; i++)
|
for (int i = 0; i < currentUndoIndex; i++)
|
||||||
{
|
{
|
||||||
DrawRectangle(position.x + slotSize*i, position.y, slotSize, slotSize, GREEN);
|
DrawRectangle((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, GREEN);
|
||||||
DrawRectangleLines(position.x + slotSize*i, position.y, slotSize, slotSize, LIME);
|
DrawRectangleLines((int)position.x + slotSize*i, (int)position.y, slotSize, slotSize, LIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw current selected UNDO slot
|
// Draw current selected UNDO slot
|
||||||
DrawRectangle(position.x + slotSize*currentUndoIndex, position.y, slotSize, slotSize, GOLD);
|
DrawRectangle((int)position.x + slotSize*currentUndoIndex, (int)position.y, slotSize, slotSize, GOLD);
|
||||||
DrawRectangleLines(position.x + slotSize*currentUndoIndex, position.y, slotSize, slotSize, ORANGE);
|
DrawRectangleLines((int)position.x + slotSize*currentUndoIndex, (int)position.y, slotSize, slotSize, ORANGE);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5757
examples/core/raygui.h
Normal file
18
examples/core/resources/text_file.txt
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
Starting of the Lorem ipsum dolor sit amet file
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at interdum ex, et iaculis quam. Mauris consectetur, magna vel malesuada aliquam, mauris enim venenatis arcu, nec cursus orci ante a massa. Curabitur libero elit, cursus eu odio eget, suscipit rhoncus nibh. Nam justo elit, ullamcorper eget dolor et, ullamcorper tristique nulla. Nullam sagittis dolor in tristique tincidunt. Duis ac porttitor erat, a molestie sapien. Aliquam finibus in ipsum quis venenatis.
|
||||||
|
Mauris odio lorem, pharetra ut egestas quis, tristique eu mauris. Cras sed gravida velit. Suspendisse potenti. Suspendisse lobortis eleifend fermentum. Donec eu dolor est. Etiam ac felis eu ligula auctor feugiat eu quis diam. Sed eleifend id nibh porta viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi at tristique dui, nec pretium est. Mauris mollis massa quis massa aliquet efficitur. Phasellus posuere, elit id tempus consequat, massa ante scelerisque odio, finibus gravida elit tellus eget lectus.
|
||||||
|
Donec rutrum sagittis ligula a auctor. Aliquam aliquet tincidunt pulvinar. Aenean a porta ex. Aenean at sagittis nulla. Morbi congue luctus est nec gravida. In hac habitasse platea dictumst. Praesent commodo efficitur congue. Duis interdum enim in pharetra dapibus. Proin vestibulum finibus mauris vitae mollis.
|
||||||
|
Sed ultricies sed enim vel interdum. Nullam nec sagittis est, quis lobortis nunc. Donec auctor elementum velit vel pulvinar. Sed quis efficitur felis, at mollis elit. Integer id elit ante. Ut gravida ante vitae erat scelerisque scelerisque vel in massa. Praesent varius massa eu purus feugiat, non venenatis urna rhoncus. Pellentesque vehicula, tellus eu venenatis efficitur, libero eros lobortis justo, at ultricies lacus diam non libero. Sed metus nulla, consectetur in justo vitae, mollis maximus orci. Vestibulum dapibus ultrices leo, et facilisis odio molestie a. Phasellus facilisis vitae lorem quis viverra. Etiam imperdiet urna dolor, quis interdum ligula tristique id. Aliquam id dapibus enim.
|
||||||
|
Curabitur congue elit in magna tristique, sit amet porta quam viverra. Integer nec placerat libero. Praesent sem dolor, tristique eu augue non, ultricies mollis nibh. Fusce finibus, lorem sollicitudin eleifend gravida, eros quam tempus leo, ut iaculis libero ex vitae libero. Sed placerat fringilla accumsan. Nulla laoreet cursus justo nec elementum. Proin facilisis lobortis velit, a sollicitudin leo mollis eu. Aenean et leo est.
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at interdum ex, et iaculis quam. Mauris consectetur, magna vel malesuada aliquam, mauris enim venenatis arcu, nec cursus orci ante a massa. Curabitur libero elit, cursus eu odio eget, suscipit rhoncus nibh. Nam justo elit, ullamcorper eget dolor et, ullamcorper tristique nulla. Nullam sagittis dolor in tristique tincidunt. Duis ac porttitor erat, a molestie sapien. Aliquam finibus in ipsum quis venenatis.
|
||||||
|
Mauris odio lorem, pharetra ut egestas quis, tristique eu mauris. Cras sed gravida velit. Suspendisse potenti. Suspendisse lobortis eleifend fermentum. Donec eu dolor est. Etiam ac felis eu ligula auctor feugiat eu quis diam. Sed eleifend id nibh porta viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi at tristique dui, nec pretium est. Mauris mollis massa quis massa aliquet efficitur. Phasellus posuere, elit id tempus consequat, massa ante scelerisque odio, finibus gravida elit tellus eget lectus.
|
||||||
|
Donec rutrum sagittis ligula a auctor. Aliquam aliquet tincidunt pulvinar. Aenean a porta ex. Aenean at sagittis nulla. Morbi congue luctus est nec gravida. In hac habitasse platea dictumst. Praesent commodo efficitur congue. Duis interdum enim in pharetra dapibus. Proin vestibulum finibus mauris vitae mollis.
|
||||||
|
Sed ultricies sed enim vel interdum. Nullam nec sagittis est, quis lobortis nunc. Donec auctor elementum velit vel pulvinar. Sed quis efficitur felis, at mollis elit. Integer id elit ante. Ut gravida ante vitae erat scelerisque scelerisque vel in massa. Praesent varius massa eu purus feugiat, non venenatis urna rhoncus. Pellentesque vehicula, tellus eu venenatis efficitur, libero eros lobortis justo, at ultricies lacus diam non libero. Sed metus nulla, consectetur in justo vitae, mollis maximus orci. Vestibulum dapibus ultrices leo, et facilisis odio molestie a. Phasellus facilisis vitae lorem quis viverra. Etiam imperdiet urna dolor, quis interdum ligula tristique id. Aliquam id dapibus enim.
|
||||||
|
wrapping text from the last available space wrapping text from the last available space wrapping text from the last available space
|
||||||
|
Curabitur congue elit in magna tristique, sit amet porta quam viverra. Integer nec placerat libero. Praesent sem dolor, tristique eu augue non, ultricies mollis nibh. Fusce finibus, lorem sollicitudin eleifend gravida, eros quam tempus leo, ut iaculis libero ex vitae libero. Sed placerat fringilla accumsan. Nulla laoreet cursus justo nec elementum. Proin facilisis lobortis velit, a sollicitudin leo mollis eu. Aenean et leo est.
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque at interdum ex, et iaculis quam. Mauris consectetur, magna vel malesuada aliquam, mauris enim venenatis arcu, nec cursus orci ante a massa. Curabitur libero elit, cursus eu odio eget, suscipit rhoncus nibh. Nam justo elit, ullamcorper eget dolor et, ullamcorper tristique nulla. Nullam sagittis dolor in tristique tincidunt. Duis ac porttitor erat, a molestie sapien. Aliquam finibus in ipsum quis venenatis.
|
||||||
|
Mauris odio lorem, pharetra ut egestas quis, tristique eu mauris. Cras sed gravida velit. Suspendisse potenti. Suspendisse lobortis eleifend fermentum. Donec eu dolor est. Etiam ac felis eu ligula auctor feugiat eu quis diam. Sed eleifend id nibh porta viverra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Morbi at tristique dui, nec pretium est. Mauris mollis massa quis massa aliquet efficitur. Phasellus posuere, elit id tempus consequat, massa ante scelerisque odio, finibus gravida elit tellus eget lectus.
|
||||||
|
Donec rutrum sagittis ligula a auctor. Aliquam aliquet tincidunt pulvinar. Aenean a porta ex. Aenean at sagittis nulla. Morbi congue luctus est nec gravida. In hac habitasse platea dictumst. Praesent commodo efficitur congue. Duis interdum enim in pharetra dapibus. Proin vestibulum finibus mauris vitae mollis.
|
||||||
|
Sed ultricies sed enim vel interdum. Nullam nec sagittis est, quis lobortis nunc. Donec auctor elementum velit vel pulvinar. Sed quis efficitur felis, at mollis elit. Integer id elit ante. Ut gravida ante vitae erat scelerisque scelerisque vel in massa. Praesent varius massa eu purus feugiat, non venenatis urna rhoncus. Pellentesque vehicula, tellus eu venenatis efficitur, libero eros lobortis justo, at ultricies lacus diam non libero. Sed metus nulla, consectetur in justo vitae, mollis maximus orci. Vestibulum dapibus ultrices leo, et facilisis odio molestie a. Phasellus facilisis vitae lorem quis viverra. Etiam imperdiet urna dolor, quis interdum ligula tristique id. Aliquam id dapibus enim.
|
||||||
|
Curabitur congue elit in magna tristique, sit amet porta quam viverra. Integer nec placerat libero. Praesent sem dolor, tristique eu augue non, ultricies mollis nibh. Fusce finibus, lorem sollicitudin eleifend gravida, eros quam tempus leo, ut iaculis libero ex vitae libero. Sed placerat fringilla accumsan. Nulla laoreet cursus justo nec elementum. Proin facilisis lobortis velit, a sollicitudin leo mollis eu. Aenean et leo est.
|
||||||
|
Ending of the Lorem ipsum dolor sit amet file
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
# WARNING: List is not ordered by example name but by the display order on web
|
# WARNING: List is not ordered by example name but by the display order on web
|
||||||
#
|
#
|
||||||
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
|
core;core_basic_window;★☆☆☆;1.0;1.0;2013;2025;"Ramon Santamaria";@raysan5
|
||||||
|
core;core_delta_time;★☆☆☆;5.5;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||||
core;core_input_keys;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
core;core_input_keys;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_input_mouse;★☆☆☆;1.0;5.5;2014;2025;"Ramon Santamaria";@raysan5
|
core;core_input_mouse;★☆☆☆;1.0;5.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_input_mouse_wheel;★☆☆☆;1.1;1.3;2014;2025;"Ramon Santamaria";@raysan5
|
core;core_input_mouse_wheel;★☆☆☆;1.1;1.3;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -30,6 +31,7 @@ core;core_world_screen;★★☆☆;1.3;1.4;2015;2025;"Ramon Santamaria";@raysan
|
||||||
core;core_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
core;core_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_window_letterbox;★★☆☆;2.5;4.0;2019;2025;"Anata";@anatagawa
|
core;core_window_letterbox;★★☆☆;2.5;4.0;2019;2025;"Anata";@anatagawa
|
||||||
core;core_window_should_close;★☆☆☆;4.2;4.2;2013;2025;"Ramon Santamaria";@raysan5
|
core;core_window_should_close;★☆☆☆;4.2;4.2;2013;2025;"Ramon Santamaria";@raysan5
|
||||||
|
core;core_monitor_detector;★☆☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
|
||||||
core;core_custom_logging;★★★☆;2.5;2.5;2018;2025;"Pablo Marcos Oltra";@pamarcos
|
core;core_custom_logging;★★★☆;2.5;2.5;2018;2025;"Pablo Marcos Oltra";@pamarcos
|
||||||
core;core_drop_files;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
core;core_drop_files;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_random_values;★☆☆☆;1.1;1.1;2014;2025;"Ramon Santamaria";@raysan5
|
core;core_random_values;★☆☆☆;1.1;1.1;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -44,8 +46,15 @@ core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@r
|
||||||
core;core_high_dpi;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
|
core;core_high_dpi;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
|
||||||
core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
core;core_render_texture;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
|
core;core_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
|
core;core_input_actions;★★☆☆;5.5;5.6;2025;2025;"Jett";@JettMonstersGoBoom
|
||||||
|
core;core_directory_files;★☆☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
|
||||||
|
core;core_highdpi_testbed;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
|
core;core_screen_recording;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||||
|
core;core_clipboard_text;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||||
|
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
|
||||||
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;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_bouncing_ball;★☆☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@raysan5
|
||||||
|
shapes;shapes_bullet_hell;★☆☆☆;5.6;5.6;2025;2025;"Zero";@zerohorsepower
|
||||||
shapes;shapes_colors_palette;★★☆☆;1.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_colors_palette;★★☆☆;1.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_logo_raylib_anim;★★☆☆;2.5;4.0;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_logo_raylib_anim;★★☆☆;2.5;4.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -56,6 +65,7 @@ shapes;shapes_following_eyes;★★☆☆;2.5;2.5;2013;2025;"Ramon Santamaria";@
|
||||||
shapes;shapes_easings_ball;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_easings_ball;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_easings_box;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_easings_box;★★☆☆;2.5;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_easings_rectangles;★★★☆;2.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_easings_rectangles;★★★☆;2.0;2.5;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
|
shapes;shapes_recursive_tree;★★★☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||||
shapes;shapes_ring_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
shapes;shapes_ring_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
||||||
shapes;shapes_circle_sector_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
shapes;shapes_circle_sector_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
||||||
shapes;shapes_rounded_rectangle_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
shapes;shapes_rounded_rectangle_drawing;★★★☆;2.5;2.5;2018;2025;"Vlad Adrian";@demizdor
|
||||||
|
|
@ -64,6 +74,16 @@ shapes;shapes_rectangle_advanced;★★★★;5.5;5.5;2024;2025;"Everton Jr.";@e
|
||||||
shapes;shapes_splines_drawing;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
shapes;shapes_splines_drawing;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
||||||
shapes;shapes_digital_clock;★★★★;5.5;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
shapes;shapes_digital_clock;★★★★;5.5;5.6;2025;2025;"Hamza RAHAL";@hmz-rhl
|
||||||
shapes;shapes_double_pendulum;★★☆☆;5.5;5.5;2025;2025;"JoeCheong";@Joecheong2006
|
shapes;shapes_double_pendulum;★★☆☆;5.5;5.5;2025;2025;"JoeCheong";@Joecheong2006
|
||||||
|
shapes;shapes_dashed_line;★☆☆☆;5.5;5.5;2025;2025;"Luís Almeida";@luis605
|
||||||
|
shapes;shapes_triangle_strip;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||||
|
shapes;shapes_vector_angle;★★☆☆;1.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
||||||
|
shapes;shapes_pie_chart;★★★☆;5.5;5.6;2025;2025;"Gideon Serfontein";@GideonSerf
|
||||||
|
shapes;shapes_kaleidoscope;★★☆☆;5.5;5.6;2025;2025;"Hugo ARNAL";@hugoarnal
|
||||||
|
shapes;shapes_clock_of_clocks;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
|
shapes;shapes_math_sine_cosine;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||||
|
shapes;shapes_mouse_trail;★☆☆☆;5.6;5.6-dev;2025;2025;"Balamurugan R";@Bala050814
|
||||||
|
shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||||
|
shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
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_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -100,10 +120,11 @@ text;text_input_box;★★☆☆;1.7;3.5;2017;2025;"Ramon Santamaria";@raysan5
|
||||||
text;text_writing_anim;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
text;text_writing_anim;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
||||||
text;text_rectangle_bounds;★★★★;2.5;4.0;2018;2025;"Vlad Adrian";@demizdor
|
text;text_rectangle_bounds;★★★★;2.5;4.0;2018;2025;"Vlad Adrian";@demizdor
|
||||||
text;text_unicode_emojis;★★★★;2.5;4.0;2019;2025;"Vlad Adrian";@demizdor
|
text;text_unicode_emojis;★★★★;2.5;4.0;2019;2025;"Vlad Adrian";@demizdor
|
||||||
text;text_unicode_ranges;★★★★;5.5;5.6;2025;2025;"Vlad Adrian";@demizdor
|
text;text_unicode_ranges;★★★★;5.5;5.6;2025;2025;"Vadim Gunko";@GuvaCode
|
||||||
text;text_3d_drawing;★★★★;3.5;4.0;2021;2025;"Vlad Adrian";@demizdor
|
text;text_3d_drawing;★★★★;3.5;4.0;2021;2025;"Vlad Adrian";@demizdor
|
||||||
text;text_codepoints_loading;★★★☆;4.2;4.2;2022;2025;"Ramon Santamaria";@raysan5
|
text;text_codepoints_loading;★★★☆;4.2;4.2;2022;2025;"Ramon Santamaria";@raysan5
|
||||||
text;text_inline_styling;★★★☆;5.6-dev;5.6-dev;2025;2025;"Wagner Barongello";@SultansOfCode
|
text;text_inline_styling;★★★☆;5.6-dev;5.6-dev;2025;2025;"Wagner Barongello";@SultansOfCode
|
||||||
|
text;text_words_alignment;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||||
models;models_animation_playing;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant
|
models;models_animation_playing;★★☆☆;2.5;3.5;2019;2025;"Culacant";@culacant
|
||||||
models;models_billboard_rendering;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
models;models_billboard_rendering;★★★☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
models;models_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
models;models_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -124,9 +145,12 @@ models;models_waving_cubes;★★★☆;2.5;3.7;2019;2025;"Codecat";@codecat
|
||||||
models;models_heightmap_rendering;★☆☆☆;1.8;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
models;models_heightmap_rendering;★☆☆☆;1.8;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
models;models_skybox_rendering;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria";@raysan5
|
models;models_skybox_rendering;★★☆☆;1.8;4.0;2017;2025;"Ramon Santamaria";@raysan5
|
||||||
models;models_textured_cube;★★☆☆;4.5;4.5;2022;2025;"Ramon Santamaria";@raysan5
|
models;models_textured_cube;★★☆☆;4.5;4.5;2022;2025;"Ramon Santamaria";@raysan5
|
||||||
models;models_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Holden";@orangeduck
|
models;models_animation_gpu_skinning;★★★☆;4.5;4.5;2024;2025;"Daniel Holden";@orangeduck
|
||||||
models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur
|
models;models_bone_socket;★★★★;4.5;4.5;2024;2025;"iP";@ipzaur
|
||||||
models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz
|
models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van der Valk";@arceryz
|
||||||
|
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
|
||||||
|
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_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
|
||||||
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
|
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
shaders;shaders_shapes_textures;★★☆☆;1.7;3.7;2015;2025;"Ramon Santamaria";@raysan5
|
shaders;shaders_shapes_textures;★★☆☆;1.7;3.7;2015;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
@ -138,6 +162,7 @@ shaders;shaders_texture_rendering;★★☆☆;2.0;3.7;2019;2025;"Michał Ciesie
|
||||||
shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff";@GoldenThumbs
|
shaders;shaders_texture_outline;★★★☆;4.0;4.0;2021;2025;"Serenity Skiff";@GoldenThumbs
|
||||||
shaders;shaders_texture_waves;★★☆☆;2.5;3.7;2019;2025;"Anata";@anatagawa
|
shaders;shaders_texture_waves;★★☆☆;2.5;3.7;2019;2025;"Anata";@anatagawa
|
||||||
shaders;shaders_julia_set;★★★☆;2.5;4.0;2019;2025;"Josh Colclough";@joshcol9232
|
shaders;shaders_julia_set;★★★☆;2.5;4.0;2019;2025;"Josh Colclough";@joshcol9232
|
||||||
|
shaders;shaders_mandelbrot_set;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||||
shaders;shaders_eratosthenes_sieve;★★★☆;2.5;4.0;2019;2025;"ProfJski";@ProfJski
|
shaders;shaders_eratosthenes_sieve;★★★☆;2.5;4.0;2019;2025;"ProfJski";@ProfJski
|
||||||
shaders;shaders_fog_rendering;★★★☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
shaders;shaders_fog_rendering;★★★☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
||||||
shaders;shaders_simple_mask;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
shaders;shaders_simple_mask;★★☆☆;2.5;3.7;2019;2025;"Chris Camacho";@chriscamacho
|
||||||
|
|
@ -169,4 +194,4 @@ others;rlgl_compute_shader;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake4
|
||||||
others;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flashback-fx
|
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;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;embedded_files_loading;★★☆☆;3.0;3.5;2020;2025;"Kristian Holmgren";@defutura
|
||||||
others;raymath_vector_angle;★★☆☆;1.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
others;web_basic_window;★☆☆☆;5.6-dev;5.6-dev;2014;2025;"Ramon Santamaria";@raysan5
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,9 @@
|
||||||
|
|
||||||
10. Have fun!
|
10. Have fun!
|
||||||
|
|
||||||
The following files should be updated when adding a new example, it's planned to create some
|
The following files must be updated when adding a new example,
|
||||||
script to automatize this process but not available yet
|
but it can be automatically done using the raylib provided tool: rexm
|
||||||
|
So, no worries if just the .c/.png are provided when adding the example.
|
||||||
|
|
||||||
- raylib/examples/<category>/<category>_example_name.c
|
- raylib/examples/<category>/<category>_example_name.c
|
||||||
- raylib/examples/<category>/<category>_example_name.png
|
- raylib/examples/<category>/<category>_example_name.png
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
*
|
*
|
||||||
* raylib [models] example - gpu skinning
|
* raylib [models] example - animation gpu skinning
|
||||||
*
|
*
|
||||||
* Example complexity rating: [★★★☆] 3/4
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
*
|
*
|
||||||
|
|
@ -37,7 +37,7 @@ int main(void)
|
||||||
const int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - gpu skinning");
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - animation gpu skinning");
|
||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
152
examples/models/models_basic_voxel.c
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - basic voxel
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||||
|
*
|
||||||
|
* Example contributed by Tim Little (@timlittle) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Tim Little (@timlittle)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#define WORLD_SIZE 8 // Size of our voxel world (8x8x8 cubes)
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - basic voxel");
|
||||||
|
|
||||||
|
DisableCursor(); // Lock mouse to window center
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world (first person)
|
||||||
|
Camera3D camera = { 0 };
|
||||||
|
camera.position = (Vector3){ -2.0f, 0.0f, -2.0f }; // Camera position at ground level
|
||||||
|
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||||
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector
|
||||||
|
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||||
|
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||||
|
|
||||||
|
// Create a cube model
|
||||||
|
Mesh cubeMesh = GenMeshCube(1.0f, 1.0f, 1.0f); // Create a unit cube mesh
|
||||||
|
Model cubeModel = LoadModelFromMesh(cubeMesh); // Convert mesh to a model
|
||||||
|
cubeModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = BEIGE;
|
||||||
|
|
||||||
|
// Initialize voxel world - fill with voxels
|
||||||
|
bool voxels[WORLD_SIZE][WORLD_SIZE][WORLD_SIZE] = { false };
|
||||||
|
for (int x = 0; x < WORLD_SIZE; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < WORLD_SIZE; y++)
|
||||||
|
{
|
||||||
|
for (int z = 0; z < WORLD_SIZE; z++)
|
||||||
|
{
|
||||||
|
voxels[x][y][z] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
UpdateCamera(&camera, CAMERA_FIRST_PERSON);
|
||||||
|
|
||||||
|
// Handle voxel removal with mouse click
|
||||||
|
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||||
|
{
|
||||||
|
// Cast a ray from the screen center (where crosshair would be)
|
||||||
|
Vector2 screenCenter = { screenWidth/2.0f, screenHeight/2.0f };
|
||||||
|
Ray ray = GetMouseRay(screenCenter, camera);
|
||||||
|
|
||||||
|
// Check ray collision with all voxels
|
||||||
|
bool voxelRemoved = false;
|
||||||
|
for (int x = 0; (x < WORLD_SIZE) && !voxelRemoved; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; (y < WORLD_SIZE) && !voxelRemoved; y++)
|
||||||
|
{
|
||||||
|
for (int z = 0; (z < WORLD_SIZE) && !voxelRemoved; z++)
|
||||||
|
{
|
||||||
|
if (!voxels[x][y][z]) continue; // Skip empty voxels
|
||||||
|
|
||||||
|
// Build a bounding box for this voxel
|
||||||
|
Vector3 position = { (float)x, (float)y, (float)z };
|
||||||
|
BoundingBox box = {
|
||||||
|
(Vector3){ position.x - 0.5f, position.y - 0.5f, position.z - 0.5f },
|
||||||
|
(Vector3){ position.x + 0.5f, position.y + 0.5f, position.z + 0.5f }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check ray-box collision
|
||||||
|
RayCollision collision = GetRayCollisionBox(ray, box);
|
||||||
|
if (collision.hit)
|
||||||
|
{
|
||||||
|
voxels[x][y][z] = false; // Remove this voxel
|
||||||
|
voxelRemoved = true; // Exit all loops
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode3D(camera);
|
||||||
|
|
||||||
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
|
// Draw all voxels
|
||||||
|
for (int x = 0; x < WORLD_SIZE; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < WORLD_SIZE; y++)
|
||||||
|
{
|
||||||
|
for (int z = 0; z < WORLD_SIZE; z++)
|
||||||
|
{
|
||||||
|
if (!voxels[x][y][z]) continue;
|
||||||
|
|
||||||
|
Vector3 position = { (float)x, (float)y, (float)z };
|
||||||
|
DrawModel(cubeModel, position, 1.0f, BEIGE);
|
||||||
|
DrawCubeWires(position, 1.0f, 1.0f, 1.0f, BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
DrawText("Left-click a voxel to remove it!", 10, 10, 20, DARKGRAY);
|
||||||
|
DrawText("WASD to move, mouse to look around", 10, 35, 10, GRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadModel(cubeModel);
|
||||||
|
CloseWindow();
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/models/models_basic_voxel.png
Normal file
|
After Width: | Height: | Size: 341 KiB |
538
examples/models/models_decals.c
Normal file
|
|
@ -0,0 +1,538 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - decals
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★★★] 4/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
* Based on previous work by @mrdoob
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 JP Mortiboys (@themushroompirates) and Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#include <string.h> // Required for: memcpy()
|
||||||
|
|
||||||
|
#undef FLT_MAX
|
||||||
|
#define FLT_MAX 340282346638528859811704183484516925440.0f // Maximum value of a float, from bit pattern 01111111011111111111111111111111
|
||||||
|
|
||||||
|
#define MAX_DECALS 256
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef struct MeshBuilder {
|
||||||
|
int vertexCount;
|
||||||
|
int vertexCapacity;
|
||||||
|
Vector3 *vertices;
|
||||||
|
Vector2 *uvs;
|
||||||
|
} MeshBuilder;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3]);
|
||||||
|
static void FreeMeshBuilder(MeshBuilder *mb);
|
||||||
|
static Mesh BuildMesh(MeshBuilder *mb);
|
||||||
|
static Mesh GenMeshDecal(Mesh inputMesh, Ray ray);
|
||||||
|
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - decals");
|
||||||
|
|
||||||
|
// 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, 1.0f, 0.0f }; // Camera looking at point
|
||||||
|
camera.up = (Vector3){ 0.0f, 1.6f, 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 character model
|
||||||
|
Model model = LoadModel("resources/models/obj/character.obj");
|
||||||
|
|
||||||
|
// Apply character skin
|
||||||
|
Texture2D modelTexture = LoadTexture("resources/models/obj/character_diffuse.png");
|
||||||
|
SetTextureFilter(modelTexture, TEXTURE_FILTER_BILINEAR);
|
||||||
|
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = modelTexture;
|
||||||
|
|
||||||
|
BoundingBox modelBBox = GetMeshBoundingBox(model.meshes[0]); // Get mesh bounding box
|
||||||
|
|
||||||
|
camera.target = Vector3Lerp(modelBBox.min, modelBBox.max, 0.5f);
|
||||||
|
camera.position = Vector3Scale(modelBBox.max, 1.0f);
|
||||||
|
camera.position.x *= 0.1f;
|
||||||
|
|
||||||
|
float modelSize = fminf(
|
||||||
|
fminf(fabsf(modelBBox.max.x - modelBBox.min.x), fabsf(modelBBox.max.y - modelBBox.min.y)),
|
||||||
|
fabsf(modelBBox.max.z - modelBBox.min.z));
|
||||||
|
|
||||||
|
camera.position = (Vector3){ 0.0f, modelBBox.max.y*1.2f, modelSize*3.0f };
|
||||||
|
|
||||||
|
float decalSize = modelSize*0.25f;
|
||||||
|
float decalOffset = 0.01f;
|
||||||
|
|
||||||
|
Model placementCube = LoadModelFromMesh(GenMeshCube(decalSize, decalSize, decalSize));
|
||||||
|
placementCube.materials[0].maps[0].color = LIME;
|
||||||
|
|
||||||
|
Material decalMaterial = LoadMaterialDefault();
|
||||||
|
decalMaterial.maps[0].color = YELLOW;
|
||||||
|
|
||||||
|
Image decalImage = LoadImage("resources/raylib_logo.png");
|
||||||
|
ImageResizeNN(&decalImage, decalImage.width/4, decalImage.height/4);
|
||||||
|
Texture decalTexture = LoadTextureFromImage(decalImage);
|
||||||
|
UnloadImage(decalImage);
|
||||||
|
|
||||||
|
SetTextureFilter(decalTexture, TEXTURE_FILTER_BILINEAR);
|
||||||
|
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].texture = decalTexture;
|
||||||
|
decalMaterial.maps[MATERIAL_MAP_DIFFUSE].color = RAYWHITE;
|
||||||
|
|
||||||
|
// We're going to use these to build up our decal meshes
|
||||||
|
// They'll resize automatically as we go, we'll free them at the end
|
||||||
|
MeshBuilder meshBuilders[2] = { 0 };
|
||||||
|
|
||||||
|
bool showModel = true;
|
||||||
|
Model decalModels[MAX_DECALS] = { 0 };
|
||||||
|
int decalCount = 0;
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) UpdateCamera(&camera, CAMERA_THIRD_PERSON);
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) showModel = !showModel;
|
||||||
|
|
||||||
|
// Display information about closest hit
|
||||||
|
RayCollision collision = { 0 };
|
||||||
|
collision.distance = FLT_MAX;
|
||||||
|
collision.hit = false;
|
||||||
|
|
||||||
|
// Get mouse ray
|
||||||
|
Ray ray = GetScreenToWorldRay(GetMousePosition(), camera);
|
||||||
|
|
||||||
|
// Check ray collision against bounding box first, before trying the full ray-mesh test
|
||||||
|
RayCollision boxHitInfo = GetRayCollisionBox(ray, modelBBox);
|
||||||
|
|
||||||
|
if ((boxHitInfo.hit) && (decalCount < MAX_DECALS))
|
||||||
|
{
|
||||||
|
// Check ray collision against model meshes
|
||||||
|
RayCollision meshHitInfo = { 0 };
|
||||||
|
for (int m = 0; m < model.meshCount; m++)
|
||||||
|
{
|
||||||
|
// NOTE: We consider the model.transform for the collision check but
|
||||||
|
// it can be checked against any transform Matrix, used when checking against same
|
||||||
|
// model drawn multiple times with multiple transforms
|
||||||
|
meshHitInfo = GetRayCollisionMesh(ray, model.meshes[m], model.transform);
|
||||||
|
if (meshHitInfo.hit)
|
||||||
|
{
|
||||||
|
// Save the closest hit mesh
|
||||||
|
if (!collision.hit || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meshHitInfo.hit) collision = meshHitInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add decal to mesh on hit point
|
||||||
|
if (collision.hit && IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && (decalCount < MAX_DECALS))
|
||||||
|
{
|
||||||
|
// Create the transformation to project the decal
|
||||||
|
Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f));
|
||||||
|
Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){ 0.0f, 1.0f, 0.0f });
|
||||||
|
|
||||||
|
// Spin the placement around a bit
|
||||||
|
splat = MatrixMultiply(splat, MatrixRotateZ(DEG2RAD*((float)GetRandomValue(-180, 180))));
|
||||||
|
Matrix splatInv = MatrixInvert(splat);
|
||||||
|
|
||||||
|
// Reset the mesh builders
|
||||||
|
meshBuilders[0].vertexCount = 0;
|
||||||
|
meshBuilders[1].vertexCount = 0;
|
||||||
|
|
||||||
|
// We'll be flip-flopping between the two mesh builders
|
||||||
|
// Reading from one and writing to the other, then swapping
|
||||||
|
int mbIndex = 0;
|
||||||
|
|
||||||
|
// First pass, just get any triangle inside the bounding box (for each mesh of the model)
|
||||||
|
for (int meshIndex = 0; meshIndex < model.meshCount; meshIndex++)
|
||||||
|
{
|
||||||
|
Mesh mesh = model.meshes[meshIndex];
|
||||||
|
for (int tri = 0; tri < mesh.triangleCount; tri++)
|
||||||
|
{
|
||||||
|
Vector3 vertices[3] = { 0 };
|
||||||
|
|
||||||
|
// The way we calculate the vertices of the mesh triangle
|
||||||
|
// depend on whether the mesh vertices are indexed or not
|
||||||
|
if (mesh.indices == 0)
|
||||||
|
{
|
||||||
|
for (int v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
vertices[v] = (Vector3){
|
||||||
|
mesh.vertices[3*3*tri + 3*v + 0],
|
||||||
|
mesh.vertices[3*3*tri + 3*v + 1],
|
||||||
|
mesh.vertices[3*3*tri + 3*v + 2]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int v = 0; v < 3; v++)
|
||||||
|
{
|
||||||
|
vertices[v] = (Vector3){
|
||||||
|
mesh.vertices[ 3*mesh.indices[3*tri+0] + v],
|
||||||
|
mesh.vertices[ 3*mesh.indices[3*tri+1] + v],
|
||||||
|
mesh.vertices[ 3*mesh.indices[3*tri+2] + v]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform all 3 vertices of the triangle
|
||||||
|
// and check if they are inside our decal box
|
||||||
|
int insideCount = 0;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
// To splat space
|
||||||
|
Vector3 v = Vector3Transform(vertices[i], splat);
|
||||||
|
|
||||||
|
if ((fabsf(v.x) < decalSize) || (fabsf(v.y) <= decalSize) || (fabsf(v.z) <= decalSize)) insideCount++;
|
||||||
|
|
||||||
|
// We need to keep the transformed vertex
|
||||||
|
vertices[i] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If any of them are inside, we add the triangle - we'll clip it later
|
||||||
|
if (insideCount > 0) AddTriangleToMeshBuilder(&meshBuilders[mbIndex], vertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clipping time! We need to clip against all 6 directions
|
||||||
|
Vector3 planes[6] = {
|
||||||
|
{ 1, 0, 0 },
|
||||||
|
{ -1, 0, 0 },
|
||||||
|
{ 0, 1, 0 },
|
||||||
|
{ 0, -1, 0 },
|
||||||
|
{ 0, 0, 1 },
|
||||||
|
{ 0, 0, -1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int face = 0; face < 6; face++)
|
||||||
|
{
|
||||||
|
// Swap current model builder (so we read from the one we just wrote to)
|
||||||
|
mbIndex = 1 - mbIndex;
|
||||||
|
|
||||||
|
MeshBuilder *inMesh = &meshBuilders[1 - mbIndex];
|
||||||
|
MeshBuilder *outMesh = &meshBuilders[mbIndex];
|
||||||
|
|
||||||
|
// Reset write builder
|
||||||
|
outMesh->vertexCount = 0;
|
||||||
|
|
||||||
|
float s = 0.5f*decalSize;
|
||||||
|
|
||||||
|
for (int i = 0; i < inMesh->vertexCount; i += 3)
|
||||||
|
{
|
||||||
|
Vector3 nV1, nV2, nV3, nV4;
|
||||||
|
|
||||||
|
float d1 = Vector3DotProduct(inMesh->vertices[ i + 0 ], planes[face] ) - s;
|
||||||
|
float d2 = Vector3DotProduct(inMesh->vertices[ i + 1 ], planes[face] ) - s;
|
||||||
|
float d3 = Vector3DotProduct(inMesh->vertices[ i + 2 ], planes[face] ) - s;
|
||||||
|
|
||||||
|
int v1Out = (d1 > 0);
|
||||||
|
int v2Out = (d2 > 0);
|
||||||
|
int v3Out = (d3 > 0);
|
||||||
|
|
||||||
|
// Calculate, how many vertices of the face lie outside of the clipping plane
|
||||||
|
int total = v1Out + v2Out + v3Out;
|
||||||
|
|
||||||
|
switch (total)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
// The entire face lies inside of the plane, no clipping needed
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){inMesh->vertices[i], inMesh->vertices[i+1], inMesh->vertices[i+2]});
|
||||||
|
} break;
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// One vertex lies outside of the plane, perform clipping
|
||||||
|
if (v1Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i + 1];
|
||||||
|
nV2 = inMesh->vertices[i + 2];
|
||||||
|
nV3 = ClipSegment(inMesh->vertices[i], nV1, planes[face], s);
|
||||||
|
nV4 = ClipSegment(inMesh->vertices[i], nV2, planes[face], s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v2Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i];
|
||||||
|
nV2 = inMesh->vertices[i + 2];
|
||||||
|
nV3 = ClipSegment(inMesh->vertices[i + 1], nV1, planes[face], s);
|
||||||
|
nV4 = ClipSegment(inMesh->vertices[i + 1], nV2, planes[face], s);
|
||||||
|
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV3, nV2, nV1});
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV2, nV3, nV4});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v3Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i];
|
||||||
|
nV2 = inMesh->vertices[i + 1];
|
||||||
|
nV3 = ClipSegment(inMesh->vertices[i + 2], nV1, planes[face], s);
|
||||||
|
nV4 = ClipSegment(inMesh->vertices[i + 2], nV2, planes[face], s);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV4, nV3, nV2});
|
||||||
|
} break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// Two vertices lies outside of the plane, perform clipping
|
||||||
|
if (!v1Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i];
|
||||||
|
nV2 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s);
|
||||||
|
nV3 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s);
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v2Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i + 1];
|
||||||
|
nV2 = ClipSegment(nV1, inMesh->vertices[i + 2], planes[face], s);
|
||||||
|
nV3 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s);
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!v3Out)
|
||||||
|
{
|
||||||
|
nV1 = inMesh->vertices[i + 2];
|
||||||
|
nV2 = ClipSegment(nV1, inMesh->vertices[i], planes[face], s);
|
||||||
|
nV3 = ClipSegment(nV1, inMesh->vertices[i + 1], planes[face], s);
|
||||||
|
AddTriangleToMeshBuilder(outMesh, (Vector3[3]){nV1, nV2, nV3});
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case 3: // The entire face lies outside of the plane, so let's discard the corresponding vertices
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we just need to re-transform the vertices
|
||||||
|
MeshBuilder *theMesh = &meshBuilders[mbIndex];
|
||||||
|
|
||||||
|
// Allocate room for UVs
|
||||||
|
if (theMesh->vertexCount > 0)
|
||||||
|
{
|
||||||
|
theMesh->uvs = (Vector2 *)MemAlloc(sizeof(Vector2)*theMesh->vertexCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < theMesh->vertexCount; i++)
|
||||||
|
{
|
||||||
|
// Calculate the UVs based on the projected coords
|
||||||
|
// They are clipped to (-decalSize .. decalSize) and we want them (0..1)
|
||||||
|
theMesh->uvs[i].x = (theMesh->vertices[i].x/decalSize + 0.5f);
|
||||||
|
theMesh->uvs[i].y = (theMesh->vertices[i].y/decalSize + 0.5f);
|
||||||
|
|
||||||
|
// From splat space to world space
|
||||||
|
theMesh->vertices[i] = Vector3Transform(theMesh->vertices[i], splatInv);
|
||||||
|
|
||||||
|
// Tiny nudge in the normal direction so it renders properly over the mesh
|
||||||
|
theMesh->vertices[i] = Vector3Add(theMesh->vertices[i], Vector3Scale(collision.normal, decalOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decal model data ready, create it and add it
|
||||||
|
int decalIndex = decalCount++;
|
||||||
|
decalModels[decalIndex] = LoadModelFromMesh(BuildMesh(theMesh));
|
||||||
|
decalModels[decalIndex].materials[0] = decalMaterial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode3D(camera);
|
||||||
|
// Draw the model at the origin and default scale
|
||||||
|
if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE);
|
||||||
|
|
||||||
|
// Draw the decal models
|
||||||
|
for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){0}, 1.0f, WHITE);
|
||||||
|
|
||||||
|
// If we hit the mesh, draw the box for the decal
|
||||||
|
if (collision.hit)
|
||||||
|
{
|
||||||
|
Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f));
|
||||||
|
Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0});
|
||||||
|
placementCube.transform = MatrixInvert(splat);
|
||||||
|
DrawModel(placementCube, (Vector3){0}, 1.0f, Fade(WHITE, 0.5f));
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawGrid(10, 10.0f);
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
float yPos = 10;
|
||||||
|
float x0 = GetScreenWidth() - 300;
|
||||||
|
float x1 = x0 + 100;
|
||||||
|
float x2 = x1 + 100;
|
||||||
|
|
||||||
|
DrawText("Vertices", x1, yPos, 10, LIME);
|
||||||
|
DrawText("Triangles", x2, yPos, 10, LIME);
|
||||||
|
yPos += 15;
|
||||||
|
|
||||||
|
int vertexCount = 0;
|
||||||
|
int triangleCount = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < model.meshCount; i++)
|
||||||
|
{
|
||||||
|
vertexCount += model.meshes[i].vertexCount;
|
||||||
|
triangleCount += model.meshes[i].triangleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawText("Main model", x0, yPos, 10, LIME);
|
||||||
|
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME);
|
||||||
|
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME);
|
||||||
|
yPos += 15;
|
||||||
|
|
||||||
|
for (int i = 0; i < decalCount; i++)
|
||||||
|
{
|
||||||
|
DrawText(TextFormat("Decal #%d", i+1), x0, yPos, 10, LIME);
|
||||||
|
DrawText(TextFormat("%d", decalModels[i].meshes[0].vertexCount), x1, yPos, 10, LIME);
|
||||||
|
DrawText(TextFormat("%d", decalModels[i].meshes[0].triangleCount), x2, yPos, 10, LIME);
|
||||||
|
|
||||||
|
vertexCount += decalModels[i].meshes[0].vertexCount;
|
||||||
|
triangleCount += decalModels[i].meshes[0].triangleCount;
|
||||||
|
yPos += 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawText("TOTAL", x0, yPos, 10, LIME);
|
||||||
|
DrawText(TextFormat("%d", vertexCount), x1, yPos, 10, LIME);
|
||||||
|
DrawText(TextFormat("%d", triangleCount), x2, yPos, 10, LIME);
|
||||||
|
yPos += 15;
|
||||||
|
|
||||||
|
DrawText("Hold RMB to move camera", 10, 430, 10, GRAY);
|
||||||
|
DrawText("(c) Character model and texture from kenney.nl", screenWidth - 260, screenHeight - 20, 10, GRAY);
|
||||||
|
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadModel(model);
|
||||||
|
UnloadTexture(modelTexture);
|
||||||
|
|
||||||
|
// TODO: WARNING: This line crashes program on closing
|
||||||
|
//for (int i = 0; i < decalCount; i++) UnloadModel(decalModels[i]);
|
||||||
|
|
||||||
|
UnloadTexture(decalTexture);
|
||||||
|
|
||||||
|
FreeMeshBuilder(&meshBuilders[0]);
|
||||||
|
FreeMeshBuilder(&meshBuilders[1]);
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Add triangles to mesh builder (dynamic array manager)
|
||||||
|
static void AddTriangleToMeshBuilder(MeshBuilder *mb, Vector3 vertices[3])
|
||||||
|
{
|
||||||
|
// Reallocate and copy if we need to
|
||||||
|
if (mb->vertexCapacity <= (mb->vertexCount + 3))
|
||||||
|
{
|
||||||
|
int newVertexCapacity = (1 + (mb->vertexCapacity/256))*256;
|
||||||
|
Vector3 *newVertices = (Vector3 *)MemAlloc(newVertexCapacity*sizeof(Vector3));
|
||||||
|
|
||||||
|
if (mb->vertexCapacity > 0)
|
||||||
|
{
|
||||||
|
memcpy(newVertices, mb->vertices, mb->vertexCount*sizeof(Vector3));
|
||||||
|
MemFree(mb->vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
mb->vertices = newVertices;
|
||||||
|
mb->vertexCapacity = newVertexCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add 3 vertices
|
||||||
|
int index = mb->vertexCount;
|
||||||
|
mb->vertexCount += 3;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) mb->vertices[index+i] = vertices[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free mesh builder
|
||||||
|
static void FreeMeshBuilder(MeshBuilder *mb)
|
||||||
|
{
|
||||||
|
MemFree(mb->vertices);
|
||||||
|
if (mb->uvs) MemFree(mb->uvs);
|
||||||
|
*mb = (MeshBuilder){ 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a Mesh from MeshBuilder data
|
||||||
|
static Mesh BuildMesh(MeshBuilder *mb)
|
||||||
|
{
|
||||||
|
Mesh outMesh = { 0 };
|
||||||
|
|
||||||
|
outMesh.vertexCount = mb->vertexCount;
|
||||||
|
outMesh.triangleCount = mb->vertexCount/3;
|
||||||
|
outMesh.vertices = MemAlloc(outMesh.vertexCount*3*sizeof(float));
|
||||||
|
if (mb->uvs) outMesh.texcoords = MemAlloc(outMesh.vertexCount*2*sizeof(float));
|
||||||
|
|
||||||
|
for (int i = 0; i < mb->vertexCount; i++)
|
||||||
|
{
|
||||||
|
outMesh.vertices[3*i+0] = mb->vertices[i].x;
|
||||||
|
outMesh.vertices[3*i+1] = mb->vertices[i].y;
|
||||||
|
outMesh.vertices[3*i+2] = mb->vertices[i].z;
|
||||||
|
|
||||||
|
if (mb->uvs)
|
||||||
|
{
|
||||||
|
outMesh.texcoords[2*i+0] = mb->uvs[i].x;
|
||||||
|
outMesh.texcoords[2*i+1] = mb->uvs[i].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadMesh(&outMesh, false);
|
||||||
|
|
||||||
|
return outMesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clip segment
|
||||||
|
static Vector3 ClipSegment(Vector3 v0, Vector3 v1, Vector3 p, float s)
|
||||||
|
{
|
||||||
|
float d0 = Vector3DotProduct(v0, p) - s;
|
||||||
|
float d1 = Vector3DotProduct(v1, p) - s;
|
||||||
|
float s0 = d0/(d0 - d1);
|
||||||
|
|
||||||
|
Vector3 position = Vector3Lerp(v0, v1, s0);
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
BIN
examples/models/models_decals.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
94
examples/models/models_rotating_cube.c
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [models] example - rotating cube
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by Jopestpe (@jopestpe)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Jopestpe (@jopestpe)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - rotating cube");
|
||||||
|
|
||||||
|
// Define the camera to look into our 3d world
|
||||||
|
Camera camera = { 0 };
|
||||||
|
camera.position = (Vector3){ 0.0f, 3.0f, 3.0f };
|
||||||
|
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||||
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||||
|
camera.fovy = 45.0f;
|
||||||
|
camera.projection = CAMERA_PERSPECTIVE;
|
||||||
|
|
||||||
|
// Load image to create texture for the cube
|
||||||
|
Model model = LoadModelFromMesh(GenMeshCube(1.0f, 1.0f, 1.0f));
|
||||||
|
Image img = LoadImage("resources/cubicmap_atlas.png");
|
||||||
|
Image crop = ImageFromImage(img, (Rectangle){0, img.height/2.0f, img.width/2.0f, img.height/2.0f});
|
||||||
|
Texture2D texture = LoadTextureFromImage(crop);
|
||||||
|
UnloadImage(img);
|
||||||
|
UnloadImage(crop);
|
||||||
|
|
||||||
|
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
|
||||||
|
|
||||||
|
float rotation = 0.0f;
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
rotation += 1.0f;
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode3D(camera);
|
||||||
|
|
||||||
|
// Draw model defining: position, size, rotation-axis, rotation (degrees), size, and tint-color
|
||||||
|
DrawModelEx(model, (Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.5f, 1.0f, 0.0f },
|
||||||
|
rotation, (Vector3){ 1.0f, 1.0f, 1.0f }, WHITE);
|
||||||
|
|
||||||
|
DrawGrid(10, 1.0f);
|
||||||
|
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadTexture(texture); // Unload texture
|
||||||
|
UnloadModel(model); // Unload model
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/models/models_rotating_cube.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
|
|
@ -65,7 +65,7 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
rotation = DEG2RAD*45.0f*GetTime();
|
rotation = DEG2RAD*45.0f*(float)GetTime();
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
12
examples/models/resources/models/obj/character.mtl
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Blender MTL File: 'None'
|
||||||
|
# Material Count: 1
|
||||||
|
|
||||||
|
newmtl skin
|
||||||
|
Ns 86.470579
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Kd 0.800000 0.800000 0.800000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.450000
|
||||||
|
d 0.000000
|
||||||
|
illum 9
|
||||||
3454
examples/models/resources/models/obj/character.obj
Normal file
BIN
examples/models/resources/models/obj/character_diffuse.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
examples/models/resources/raylib_logo.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
|
@ -59,7 +59,7 @@ int main(void)
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [others] example - compute shader");
|
InitWindow(screenWidth, screenHeight, "raylib [others] example - compute shader");
|
||||||
|
|
||||||
const Vector2 resolution = { screenWidth, screenHeight };
|
const Vector2 resolution = { (float)screenWidth, (float)screenHeight };
|
||||||
unsigned int brushSize = 8;
|
unsigned int brushSize = 8;
|
||||||
|
|
||||||
// Game of Life logic compute shader
|
// Game of Life logic compute shader
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,18 @@
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
*
|
*
|
||||||
* raylib [others] example - Basic window (adapted for HTML5 platform)
|
* raylib [others] example - basic window
|
||||||
*
|
*
|
||||||
* This example is prepared to compile for PLATFORM_WEB and PLATFORM_DESKTOP
|
* 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...
|
* As you will notice, code structure is slightly different to the other examples
|
||||||
* To compile it for PLATFORM_WEB just uncomment #define PLATFORM_WEB at beginning
|
|
||||||
*
|
*
|
||||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
* Example originally created with raylib 1.3, last time updated with raylib 5.5
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
|
|
|
||||||
BIN
examples/others/web_basic_window.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
80
examples/shaders/resources/shaders/glsl100/ascii.fs
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
#version 100
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
// Input from the vertex shader
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
|
||||||
|
// Output color for the screen
|
||||||
|
varying vec4 finalColor;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
|
||||||
|
// Fontsize less then 9 may be not complete
|
||||||
|
uniform float fontSize;
|
||||||
|
|
||||||
|
float GreyScale(in vec3 col)
|
||||||
|
{
|
||||||
|
return dot(col, vec3(0.2126, 0.7152, 0.0722));
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetCharacter(float n, vec2 p)
|
||||||
|
{
|
||||||
|
p = floor(p*vec2(-4.0, 4.0) + 2.5);
|
||||||
|
|
||||||
|
// Check if the calculated coordinate is inside the 5x5 grid (from 0.0 to 4.0)
|
||||||
|
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
|
||||||
|
{
|
||||||
|
float a = floor(p.x + 0.5) + 5.0*floor(p.y + 0.5);
|
||||||
|
|
||||||
|
// This checked if the 'a'-th bit of 'n' was set
|
||||||
|
float shiftedN = floor(n/pow(2.0, a));
|
||||||
|
|
||||||
|
if (mod(shiftedN, 2.0) == 1.0)
|
||||||
|
{
|
||||||
|
return 1.0; // The bit is on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0; // The bit is off, or we are outside the grid
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Main shader logic
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 charPixelSize = vec2(fontSize, fontSize);
|
||||||
|
vec2 uvCellSize = charPixelSize/resolution;
|
||||||
|
|
||||||
|
// The cell size is based on the fontSize set by application
|
||||||
|
vec2 cellUV = floor(fragTexCoord/uvCellSize)*uvCellSize;
|
||||||
|
|
||||||
|
vec3 cellColor = texture2D(texture0, cellUV).rgb;
|
||||||
|
|
||||||
|
// Gray is used to define what character will be selected to draw
|
||||||
|
float gray = GreyScale(cellColor);
|
||||||
|
|
||||||
|
float n = 4096.0;
|
||||||
|
|
||||||
|
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||||
|
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||||
|
if (gray > 0.2) n = 65600.0; // :
|
||||||
|
if (gray > 0.3) n = 18725316.0; // v
|
||||||
|
if (gray > 0.4) n = 15255086.0; // o
|
||||||
|
if (gray > 0.5) n = 13121101.0; // &
|
||||||
|
if (gray > 0.6) n = 15252014.0; // 8
|
||||||
|
if (gray > 0.7) n = 13195790.0; // @
|
||||||
|
if (gray > 0.8) n = 11512810.0; // #
|
||||||
|
|
||||||
|
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
|
||||||
|
|
||||||
|
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
|
||||||
|
|
||||||
|
// cellColor and charShape will define the color of the char
|
||||||
|
vec3 color = cellColor*GetCharacter(n, p);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(color, 1.0);
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#version 100
|
#version 100
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
// Input vertex attributes (from vertex shader)
|
// Input vertex attributes (from vertex shader)
|
||||||
varying vec2 fragTexCoord;
|
varying vec2 fragTexCoord;
|
||||||
|
|
||||||
|
|
@ -14,8 +16,7 @@ void main()
|
||||||
{
|
{
|
||||||
// Handle potential Y-flipping
|
// Handle potential Y-flipping
|
||||||
vec2 texCoord = fragTexCoord;
|
vec2 texCoord = fragTexCoord;
|
||||||
if (flipY)
|
if (flipY) texCoord.y = 1.0 - texCoord.y;
|
||||||
texCoord.y = 1.0 - texCoord.y;
|
|
||||||
|
|
||||||
// Sample depth texture
|
// Sample depth texture
|
||||||
float depth = texture2D(depthTexture, texCoord).r;
|
float depth = texture2D(depthTexture, texCoord).r;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
#version 100
|
#version 100
|
||||||
|
|
||||||
#extension GL_EXT_frag_depth : enable
|
#extension GL_EXT_frag_depth : enable
|
||||||
|
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
varying vec2 fragTexCoord;
|
varying vec2 fragTexCoord;
|
||||||
varying vec4 fragColor;
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
uniform sampler2D texture0;
|
uniform sampler2D texture0;
|
||||||
uniform vec4 colDiffuse;
|
uniform vec4 colDiffuse;
|
||||||
|
|
||||||
|
|
|
||||||
62
examples/shaders/resources/shaders/glsl100/mandelbrot_set.fs
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
#version 100
|
||||||
|
|
||||||
|
#define PI 3.1415926535897932384626433832795
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
uniform vec2 offset; // Offset of the scale
|
||||||
|
uniform float zoom; // Zoom of the scale
|
||||||
|
// NOTE: Maximum number of shader for-loop iterations depend on GPU,
|
||||||
|
// For example, on RasperryPi for this examply only supports up to 60
|
||||||
|
uniform int maxIterations; // Max iterations per pixel
|
||||||
|
|
||||||
|
const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
|
||||||
|
const float max2 = max*max; // Square of max to avoid computing square root
|
||||||
|
|
||||||
|
// WebGL shaders for loop iteration limit only const
|
||||||
|
const int maxIterationsLimit = 20000;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// The pixel coordinates are scaled so they are on the mandelbrot scale
|
||||||
|
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
|
||||||
|
vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
|
||||||
|
c.x += offset.x;
|
||||||
|
c.y += offset.y;
|
||||||
|
float a = 0.0;
|
||||||
|
float b = 0.0;
|
||||||
|
|
||||||
|
// The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
|
||||||
|
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
|
||||||
|
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
|
||||||
|
|
||||||
|
for (int iter = 0; iter < maxIterationsLimit; ++iter)
|
||||||
|
{
|
||||||
|
float aa = a*a;
|
||||||
|
float bb = b*b;
|
||||||
|
if (iter >= maxIterations)
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (aa + bb > max2)
|
||||||
|
{
|
||||||
|
float normR = float(iter - (iter/55)*55)/55.0;
|
||||||
|
float normG = float(iter - (iter/69)*69)/69.0;
|
||||||
|
float normB = float(iter - (iter/40)*40)/40.0;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float twoab = 2.0*a*b;
|
||||||
|
a = aa - bb + c.x;
|
||||||
|
b = twoab + c.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
@ -23,15 +23,15 @@ uniform float specularExponent;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 texelColor = texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y));
|
vec4 texelColor = texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y));
|
||||||
vec3 specular = vec3(0.0);
|
vec3 specular = vec3(0.0);
|
||||||
vec3 viewDir = normalize(viewPos - fragPosition);
|
vec3 viewDir = normalize(viewPos - fragPosition);
|
||||||
vec3 lightDir = normalize(lightPos - fragPosition);
|
vec3 lightDir = normalize(lightPos - fragPosition);
|
||||||
|
|
||||||
vec3 normal;
|
vec3 normal = vec3(0.0);
|
||||||
if (useNormalMap)
|
if (useNormalMap)
|
||||||
{
|
{
|
||||||
normal = texture(normalMap, vec2(fragTexCoord.x, fragTexCoord.y)).rgb;
|
normal = texture2D(normalMap, vec2(fragTexCoord.x, fragTexCoord.y)).rgb;
|
||||||
|
|
||||||
// Transform normal values to the range -1.0 ... 1.0
|
// Transform normal values to the range -1.0 ... 1.0
|
||||||
normal = normalize(normal*2.0 - 1.0);
|
normal = normalize(normal*2.0 - 1.0);
|
||||||
|
|
@ -56,7 +56,7 @@ void main()
|
||||||
|
|
||||||
specular += specCo;
|
specular += specCo;
|
||||||
|
|
||||||
finalColor = (texelColor*((tint + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
|
vec4 finalColor = (texelColor*((tint + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
|
||||||
finalColor += texelColor*(vec4(1.0, 1.0, 1.0, 1.0)/40.0)*tint;
|
finalColor += texelColor*(vec4(1.0, 1.0, 1.0, 1.0)/40.0)*tint;
|
||||||
|
|
||||||
// Gamma correction
|
// Gamma correction
|
||||||
|
|
|
||||||
78
examples/shaders/resources/shaders/glsl120/ascii.fs
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
// Input from the vertex shader
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
|
||||||
|
// Output color for the screen
|
||||||
|
varying vec4 finalColor;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
|
||||||
|
// Fontsize less then 9 may be not complete
|
||||||
|
uniform float fontSize;
|
||||||
|
|
||||||
|
float GreyScale(in vec3 col)
|
||||||
|
{
|
||||||
|
return dot(col, vec3(0.2126, 0.7152, 0.0722));
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetCharacter(float n, vec2 p)
|
||||||
|
{
|
||||||
|
p = floor(p*vec2(-4.0, 4.0) + 2.5);
|
||||||
|
|
||||||
|
// Check if the calculated coordinate is inside the 5x5 grid (from 0.0 to 4.0)
|
||||||
|
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
|
||||||
|
{
|
||||||
|
float a = floor(p.x + 0.5) + 5.0*floor(p.y + 0.5);
|
||||||
|
|
||||||
|
// This checked if the 'a'-th bit of 'n' was set
|
||||||
|
float shiftedN = floor(n/pow(2.0, a));
|
||||||
|
|
||||||
|
if (mod(shiftedN, 2.0) == 1.0)
|
||||||
|
{
|
||||||
|
return 1.0; // The bit is on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0; // The bit is off, or we are outside the grid
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Main shader logic
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 charPixelSize = vec2(fontSize, fontSize);
|
||||||
|
vec2 uvCellSize = charPixelSize / resolution;
|
||||||
|
|
||||||
|
// The cell size is based on the fontSize set by application
|
||||||
|
vec2 cellUV = floor(fragTexCoord / uvCellSize)*uvCellSize;
|
||||||
|
|
||||||
|
vec3 cellColor = texture2D(texture0, cellUV).rgb;
|
||||||
|
|
||||||
|
// Gray is used to define what character will be selected to draw
|
||||||
|
float gray = GreyScale(cellColor);
|
||||||
|
|
||||||
|
float n = 4096.0;
|
||||||
|
|
||||||
|
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||||
|
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||||
|
if (gray > 0.2) n = 65600.0; // :
|
||||||
|
if (gray > 0.3) n = 18725316.0; // v
|
||||||
|
if (gray > 0.4) n = 15255086.0; // o
|
||||||
|
if (gray > 0.5) n = 13121101.0; // &
|
||||||
|
if (gray > 0.6) n = 15252014.0; // 8
|
||||||
|
if (gray > 0.7) n = 13195790.0; // @
|
||||||
|
if (gray > 0.8) n = 11512810.0; // #
|
||||||
|
|
||||||
|
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
|
||||||
|
|
||||||
|
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
|
||||||
|
|
||||||
|
// cellColor and charShape will define the color of the char
|
||||||
|
vec3 color = cellColor*GetCharacter(n, p);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(color, 1.0);
|
||||||
|
}
|
||||||
59
examples/shaders/resources/shaders/glsl120/mandelbrot_set.fs
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
#define PI 3.1415926535897932384626433832795
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
varying vec2 fragTexCoord;
|
||||||
|
varying vec4 fragColor;
|
||||||
|
|
||||||
|
uniform vec2 offset; // Offset of the scale
|
||||||
|
uniform float zoom; // Zoom of the scale
|
||||||
|
// NOTE: Maximum number of shader for-loop iterations depend on GPU,
|
||||||
|
// For example, on RasperryPi for this examply only supports up to 60
|
||||||
|
uniform int maxIterations; // Max iterations per pixel
|
||||||
|
|
||||||
|
const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
|
||||||
|
const float max2 = max*max; // Square of max to avoid computing square root
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// The pixel coordinates are scaled so they are on the mandelbrot scale
|
||||||
|
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
|
||||||
|
vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
|
||||||
|
c.x += offset.x;
|
||||||
|
c.y += offset.y;
|
||||||
|
float a = 0.0;
|
||||||
|
float b = 0.0;
|
||||||
|
|
||||||
|
// The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
|
||||||
|
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
|
||||||
|
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
|
||||||
|
|
||||||
|
int iter = 0;
|
||||||
|
while (iter < maxIterations)
|
||||||
|
{
|
||||||
|
float aa = a*a;
|
||||||
|
float bb = b*b;
|
||||||
|
if (aa + bb > max2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
float twoab = 2.0*a*b;
|
||||||
|
a = aa - bb + c.x;
|
||||||
|
b = twoab + c.y;
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter >= maxIterations)
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float normR = float(iter - (iter/55)*55)/55.0;
|
||||||
|
float normG = float(iter - (iter/69)*69)/69.0;
|
||||||
|
float normB = float(iter - (iter/40)*40)/40.0;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
73
examples/shaders/resources/shaders/glsl330/ascii.fs
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
// Input from the vertex shader
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
|
||||||
|
// Output color for the screen
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
|
||||||
|
// Fontsize less then 9 may be not complete
|
||||||
|
uniform float fontSize;
|
||||||
|
|
||||||
|
float GreyScale(in vec3 col)
|
||||||
|
{
|
||||||
|
return dot(col, vec3(0.2126, 0.7152, 0.0722));
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetCharacter(int n, vec2 p)
|
||||||
|
{
|
||||||
|
p = floor(p*vec2(-4.0, 4.0) + 2.5);
|
||||||
|
|
||||||
|
// Check if the coordinate is inside the 5x5 grid (0 to 4)
|
||||||
|
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
|
||||||
|
{
|
||||||
|
int a = int(round(p.x) + 5.0*round(p.y));
|
||||||
|
if (((n >> a) & 1) == 1)
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0; // The bit is off, or we are outside the grid
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Main shader logic
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 charPixelSize = vec2(fontSize, fontSize);
|
||||||
|
vec2 uvCellSize = charPixelSize/resolution;
|
||||||
|
|
||||||
|
// The cell size is based on the fontSize set by application
|
||||||
|
vec2 cellUV = floor(fragTexCoord/uvCellSize)*uvCellSize;
|
||||||
|
|
||||||
|
vec3 cellColor = texture(texture0, cellUV).rgb;
|
||||||
|
|
||||||
|
// Gray is used to define what character will be selected to draw
|
||||||
|
float gray = GreyScale(cellColor);
|
||||||
|
|
||||||
|
int n = 4096;
|
||||||
|
|
||||||
|
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||||
|
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||||
|
if (gray > 0.2) n = 65600; // :
|
||||||
|
if (gray > 0.3) n = 18725316; // v
|
||||||
|
if (gray > 0.4) n = 15255086; // o
|
||||||
|
if (gray > 0.5) n = 13121101; // &
|
||||||
|
if (gray > 0.6) n = 15252014; // 8
|
||||||
|
if (gray > 0.7) n = 13195790; // @
|
||||||
|
if (gray > 0.8) n = 11512810; // #
|
||||||
|
|
||||||
|
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
|
||||||
|
|
||||||
|
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
|
||||||
|
|
||||||
|
vec3 color = cellColor*GetCharacter(n, p);
|
||||||
|
|
||||||
|
finalColor = vec4(color, 1.0);
|
||||||
|
}
|
||||||
58
examples/shaders/resources/shaders/glsl330/mandelbrot_set.fs
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
#define PI 3.1415926535897932384626433832795
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
|
||||||
|
// Output fragment color
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
uniform vec2 offset; // Offset of the scale
|
||||||
|
uniform float zoom; // Zoom of the scale
|
||||||
|
uniform int maxIterations; // Max iterations per pixel
|
||||||
|
|
||||||
|
const float max = 4.0; // We consider infinite as 4.0: if a point reaches a distance of 4.0 it will escape to infinity
|
||||||
|
const float max2 = max*max; // Square of max to avoid computing square root
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// The pixel coordinates are scaled so they are on the mandelbrot scale
|
||||||
|
// NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
|
||||||
|
vec2 c = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
|
||||||
|
c.x += offset.x;
|
||||||
|
c.y += offset.y;
|
||||||
|
float a = 0.0;
|
||||||
|
float b = 0.0;
|
||||||
|
|
||||||
|
// The Mandelbrot set is a two-dimensional set defined in the complex plane on which the iteration of the function
|
||||||
|
// Fc(z) = z^2 + c on the complex numbers c from the plane does not diverge to infinity starting at z = 0
|
||||||
|
// Here: z = a + bi. Iterations: z -> z^2 + c = (a + bi)^2 + (c.x + c.yi) = (a^2 - b^2 + c.x) + (2ab + c.y)i
|
||||||
|
|
||||||
|
int iter = 0;
|
||||||
|
for (iter = 0; iter < maxIterations; ++iter)
|
||||||
|
{
|
||||||
|
float aa = a*a;
|
||||||
|
float bb = b*b;
|
||||||
|
if (aa + bb > max2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
float twoab = 2.0*a*b;
|
||||||
|
a = aa - bb + c.x;
|
||||||
|
b = twoab + c.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter >= maxIterations)
|
||||||
|
{
|
||||||
|
finalColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float normR = float(iter%55)/55.0;
|
||||||
|
float normG = float(iter%69)/69.0;
|
||||||
|
float normB = float(iter%40)/40.0;
|
||||||
|
|
||||||
|
finalColor = vec4(sin(normR*PI), sin(normG*PI), sin(normB*PI), 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ out vec4 finalColor;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Texel color fetching from texture sampler
|
// Texel color fetching from texture sampler
|
||||||
// NOTE: The texel is actually the a GRAYSCALE index color
|
// NOTE: The texel is actually the GRAYSCALE index color
|
||||||
vec4 texelColor = texture(texture0, fragTexCoord)*fragColor;
|
vec4 texelColor = texture(texture0, fragTexCoord)*fragColor;
|
||||||
|
|
||||||
// Convert the (normalized) texel color RED component (GB would work, too)
|
// Convert the (normalized) texel color RED component (GB would work, too)
|
||||||
|
|
|
||||||
121
examples/shaders/shaders_ascii_rendering.c
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shaders] example - ascii rendering
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Maicon Santana (@maiconpintoabreu) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Maicon Santana (@maiconpintoabreu)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
#define GLSL_VERSION 330
|
||||||
|
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||||
|
#define GLSL_VERSION 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - ascii rendering");
|
||||||
|
|
||||||
|
// Texture to test static drawing
|
||||||
|
Texture2D fudesumi = LoadTexture("resources/fudesumi.png");
|
||||||
|
// Texture to test moving drawing
|
||||||
|
Texture2D raysan = LoadTexture("resources/raysan.png");
|
||||||
|
|
||||||
|
// Load shader to be used on postprocessing
|
||||||
|
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/ascii.fs", GLSL_VERSION));
|
||||||
|
|
||||||
|
// These locations are used to send data to the GPU
|
||||||
|
int resolutionLoc = GetShaderLocation(shader, "resolution");
|
||||||
|
int fontSizeLoc = GetShaderLocation(shader, "fontSize");
|
||||||
|
|
||||||
|
// Set the character size for the ASCII effect
|
||||||
|
// Fontsize should be 9 or more
|
||||||
|
float fontSize = 9.0f;
|
||||||
|
|
||||||
|
// Send the updated values to the shader
|
||||||
|
float resolution[2] = { (float)screenWidth, (float)screenHeight };
|
||||||
|
SetShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2);
|
||||||
|
|
||||||
|
Vector2 circlePos = (Vector2){40.0f, (float)screenHeight*0.5f};
|
||||||
|
float circleSpeed = 1.0f;
|
||||||
|
|
||||||
|
// RenderTexture to apply the postprocessing later
|
||||||
|
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
circlePos.x += circleSpeed;
|
||||||
|
if ((circlePos.x > 200.0f) || (circlePos.x < 40.0f)) circleSpeed *= -1; // Revert speed
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_LEFT) && (fontSize > 9.0)) fontSize -= 1; // Reduce fontSize
|
||||||
|
if (IsKeyPressed(KEY_RIGHT) && (fontSize < 15.0)) fontSize += 1; // Increase fontSize
|
||||||
|
|
||||||
|
// Set fontsize for the shader
|
||||||
|
SetShaderValue(shader, fontSizeLoc, &fontSize, SHADER_UNIFORM_FLOAT);
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginTextureMode(target);
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
|
||||||
|
// Draw scene in our render texture
|
||||||
|
DrawTexture(fudesumi, 500, -30, WHITE);
|
||||||
|
DrawTextureV(raysan, circlePos, WHITE);
|
||||||
|
EndTextureMode();
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
BeginShaderMode(shader);
|
||||||
|
// Draw the scene texture (that we rendered earlier) to the screen
|
||||||
|
// The shader will process every pixel of this texture
|
||||||
|
DrawTextureRec(target.texture,
|
||||||
|
(Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height },
|
||||||
|
(Vector2){ 0, 0 }, WHITE);
|
||||||
|
EndShaderMode();
|
||||||
|
|
||||||
|
DrawRectangle(0, 0, screenWidth, 40, BLACK);
|
||||||
|
DrawText(TextFormat("Ascii effect - FontSize:%2.0f - [Left] -1 [Right] +1 ", fontSize), 120, 10, 20, LIGHTGRAY);
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadRenderTexture(target); // Unload render texture
|
||||||
|
|
||||||
|
UnloadShader(shader); // Unload shader
|
||||||
|
UnloadTexture(fudesumi); // Unload texture
|
||||||
|
UnloadTexture(raysan); // Unload texture
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shaders/shaders_ascii_rendering.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
|
@ -252,7 +252,11 @@ int main()
|
||||||
// Draw spheres to show the lights positions
|
// Draw spheres to show the lights positions
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||||
{
|
{
|
||||||
Color lightColor = (Color){ lights[i].color[0]*255, lights[i].color[1]*255, lights[i].color[2]*255, lights[i].color[3]*255 };
|
Color lightColor = (Color){
|
||||||
|
(unsigned char)(lights[i].color[0]*255),
|
||||||
|
(unsigned char)(lights[i].color[1] * 255),
|
||||||
|
(unsigned char)(lights[i].color[2] * 255),
|
||||||
|
(unsigned char)(lights[i].color[3] * 255) };
|
||||||
|
|
||||||
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lightColor);
|
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lightColor);
|
||||||
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lightColor, 0.3f));
|
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lightColor, 0.3f));
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ int main(void)
|
||||||
BeginBlendMode(BLEND_ADDITIVE);
|
BeginBlendMode(BLEND_ADDITIVE);
|
||||||
DrawTexturePro(
|
DrawTexturePro(
|
||||||
light,
|
light,
|
||||||
(Rectangle){ 0, 0, light.width, light.height },
|
(Rectangle){ 0, 0, (float)light.width, (float)light.height },
|
||||||
(Rectangle){ 0, 0, 20, 20 },
|
(Rectangle){ 0, 0, 20, 20 },
|
||||||
(Vector2){ 10.0, 10.0 },
|
(Vector2){ 10.0, 10.0 },
|
||||||
0.0,
|
0.0,
|
||||||
|
|
@ -110,7 +110,7 @@ int main(void)
|
||||||
);
|
);
|
||||||
DrawTexturePro(
|
DrawTexturePro(
|
||||||
light,
|
light,
|
||||||
(Rectangle){ 0, 0, light.width, light.height },
|
(Rectangle){ 0, 0, (float)light.width, (float)light.height },
|
||||||
(Rectangle){ 8, 4, 20, 20 },
|
(Rectangle){ 8, 4, 20, 20 },
|
||||||
(Vector2){ 10.0, 10.0 },
|
(Vector2){ 10.0, 10.0 },
|
||||||
0.0,
|
0.0,
|
||||||
|
|
@ -118,7 +118,7 @@ int main(void)
|
||||||
);
|
);
|
||||||
DrawTexturePro(
|
DrawTexturePro(
|
||||||
light,
|
light,
|
||||||
(Rectangle){ 0, 0, light.width, light.height },
|
(Rectangle){ 0, 0, (float)light.width, (float)light.height },
|
||||||
(Rectangle){ 8, 8, 10, 10 },
|
(Rectangle){ 8, 8, 10, 10 },
|
||||||
(Vector2){ 5.0, 5.0 },
|
(Vector2){ 5.0, 5.0 },
|
||||||
0.0,
|
0.0,
|
||||||
|
|
@ -152,7 +152,7 @@ int main(void)
|
||||||
DrawTexturePro(
|
DrawTexturePro(
|
||||||
lightmap.texture,
|
lightmap.texture,
|
||||||
(Rectangle){ 0, 0, -MAP_SIZE, -MAP_SIZE },
|
(Rectangle){ 0, 0, -MAP_SIZE, -MAP_SIZE },
|
||||||
(Rectangle){ GetRenderWidth() - MAP_SIZE*8 - 10, 10, MAP_SIZE*8, MAP_SIZE*8 },
|
(Rectangle){ (float)GetRenderWidth() - MAP_SIZE*8 - 10, 10, (float)MAP_SIZE*8, (float)MAP_SIZE*8 },
|
||||||
(Vector2){ 0.0, 0.0 },
|
(Vector2){ 0.0, 0.0 },
|
||||||
0.0,
|
0.0,
|
||||||
WHITE);
|
WHITE);
|
||||||
|
|
|
||||||
229
examples/shaders/shaders_mandelbrot_set.c
Normal file
|
|
@ -0,0 +1,229 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shaders] example - mandelbrot set
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
|
*
|
||||||
|
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
|
||||||
|
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version
|
||||||
|
*
|
||||||
|
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3)
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Jordi Santonja (@JordSant)
|
||||||
|
* Based on previous work by Josh Colclough (@joshcol9232)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Jordi Santonja (@JordSant)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
#define GLSL_VERSION 330
|
||||||
|
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||||
|
#define GLSL_VERSION 100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// A few good interesting places
|
||||||
|
const float pointsOfInterest[6][3] =
|
||||||
|
{
|
||||||
|
{ -1.76826775f, -0.00422996283f, 28435.9238f },
|
||||||
|
{ 0.322004497f, -0.0357099883f, 56499.7266f },
|
||||||
|
{ -0.748880744f, -0.0562955774f, 9237.59082f },
|
||||||
|
{ -1.78385007f, -0.0156200649f, 14599.5283f },
|
||||||
|
{ -0.0985441282f, -0.924688697f, 26259.8535f },
|
||||||
|
{ 0.317785531f, -0.0322612226f, 29297.9258f },
|
||||||
|
};
|
||||||
|
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
const float zoomSpeed = 1.01f;
|
||||||
|
const float offsetSpeedMul = 2.0f;
|
||||||
|
|
||||||
|
const float startingZoom = 0.6f;
|
||||||
|
const float startingOffset[2] = { -0.5f, 0.0f };
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - mandelbrot set");
|
||||||
|
|
||||||
|
// Load mandelbrot set shader
|
||||||
|
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
|
||||||
|
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/mandelbrot_set.fs", GLSL_VERSION));
|
||||||
|
|
||||||
|
// Create a RenderTexture2D to be used for render to texture
|
||||||
|
RenderTexture2D target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
|
||||||
|
// Offset and zoom to draw the mandelbrot set at. (centered on screen and default size)
|
||||||
|
float offset[2] = { startingOffset[0], startingOffset[1] };
|
||||||
|
float zoom = startingZoom;
|
||||||
|
// Depending on the zoom the mximum number of iterations must be adapted to get more detail as we zzoom in
|
||||||
|
// The solution is not perfect, so a control has been added to increase/decrease the number of iterations with UP/DOWN keys
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
int maxIterations = 333;
|
||||||
|
float maxIterationsMultiplier = 166.5f;
|
||||||
|
#else
|
||||||
|
int maxIterations = 43;
|
||||||
|
float maxIterationsMultiplier = 22.0f;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get variable (uniform) locations on the shader to connect with the program
|
||||||
|
// NOTE: If uniform variable could not be found in the shader, function returns -1
|
||||||
|
int zoomLoc = GetShaderLocation(shader, "zoom");
|
||||||
|
int offsetLoc = GetShaderLocation(shader, "offset");
|
||||||
|
int maxIterationsLoc = GetShaderLocation(shader, "maxIterations");
|
||||||
|
|
||||||
|
// Upload the shader uniform values!
|
||||||
|
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
||||||
|
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
||||||
|
SetShaderValue(shader, maxIterationsLoc, &maxIterations, SHADER_UNIFORM_INT);
|
||||||
|
|
||||||
|
bool showControls = true; // Show controls
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
bool updateShader = false;
|
||||||
|
|
||||||
|
// Press [1 - 6] to reset c to a point of interest
|
||||||
|
if (IsKeyPressed(KEY_ONE) ||
|
||||||
|
IsKeyPressed(KEY_TWO) ||
|
||||||
|
IsKeyPressed(KEY_THREE) ||
|
||||||
|
IsKeyPressed(KEY_FOUR) ||
|
||||||
|
IsKeyPressed(KEY_FIVE) ||
|
||||||
|
IsKeyPressed(KEY_SIX))
|
||||||
|
{
|
||||||
|
int interestIndex = 0;
|
||||||
|
if (IsKeyPressed(KEY_ONE)) interestIndex = 0;
|
||||||
|
else if (IsKeyPressed(KEY_TWO)) interestIndex = 1;
|
||||||
|
else if (IsKeyPressed(KEY_THREE)) interestIndex = 2;
|
||||||
|
else if (IsKeyPressed(KEY_FOUR)) interestIndex = 3;
|
||||||
|
else if (IsKeyPressed(KEY_FIVE)) interestIndex = 4;
|
||||||
|
else if (IsKeyPressed(KEY_SIX)) interestIndex = 5;
|
||||||
|
|
||||||
|
offset[0] = pointsOfInterest[interestIndex][0];
|
||||||
|
offset[1] = pointsOfInterest[interestIndex][1];
|
||||||
|
zoom = pointsOfInterest[interestIndex][2];
|
||||||
|
updateShader = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If "R" is pressed, reset zoom and offset
|
||||||
|
if (IsKeyPressed(KEY_R))
|
||||||
|
{
|
||||||
|
offset[0] = startingOffset[0];
|
||||||
|
offset[1] = startingOffset[1];
|
||||||
|
zoom = startingZoom;
|
||||||
|
updateShader = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_F1)) showControls = !showControls; // Toggle whether or not to show controls
|
||||||
|
|
||||||
|
// Change number of max iterations with UP and DOWN keys
|
||||||
|
// WARNING: Increasing the number of max iterations greatly impacts performance
|
||||||
|
if (IsKeyPressed(KEY_UP))
|
||||||
|
{
|
||||||
|
maxIterationsMultiplier *= 1.4f;
|
||||||
|
updateShader = true;
|
||||||
|
}
|
||||||
|
else if (IsKeyPressed(KEY_DOWN))
|
||||||
|
{
|
||||||
|
maxIterationsMultiplier /= 1.4f;
|
||||||
|
updateShader = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If either left or right button is pressed, zoom in/out
|
||||||
|
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) || IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
|
||||||
|
{
|
||||||
|
// Change zoom. If Mouse left -> zoom in. Mouse right -> zoom out
|
||||||
|
zoom *= IsMouseButtonDown(MOUSE_BUTTON_LEFT)? zoomSpeed : (1.0f/zoomSpeed);
|
||||||
|
|
||||||
|
const Vector2 mousePos = GetMousePosition();
|
||||||
|
Vector2 offsetVelocity;
|
||||||
|
// Find the velocity at which to change the camera. Take the distance of the mouse
|
||||||
|
// From the center of the screen as the direction, and adjust magnitude based on the current zoom
|
||||||
|
offsetVelocity.x = (mousePos.x/(float)screenWidth - 0.5f)*offsetSpeedMul/zoom;
|
||||||
|
offsetVelocity.y = (mousePos.y/(float)screenHeight - 0.5f)*offsetSpeedMul/zoom;
|
||||||
|
|
||||||
|
// Apply move velocity to camera
|
||||||
|
offset[0] += GetFrameTime()*offsetVelocity.x;
|
||||||
|
offset[1] += GetFrameTime()*offsetVelocity.y;
|
||||||
|
|
||||||
|
updateShader = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case a parameter has been changed, update the shader values
|
||||||
|
if (updateShader)
|
||||||
|
{
|
||||||
|
// As we zoom in, increase the number of max iterations to get more detail
|
||||||
|
// Aproximate formula, but it works-ish
|
||||||
|
maxIterations = (int)(sqrtf(2.0f*sqrtf(fabsf(1.0f - sqrtf(37.5f*zoom))))*maxIterationsMultiplier);
|
||||||
|
|
||||||
|
// Update the shader uniform values!
|
||||||
|
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
||||||
|
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
||||||
|
SetShaderValue(shader, maxIterationsLoc, &maxIterations, SHADER_UNIFORM_INT);
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Using a render texture to draw Mandelbrot set
|
||||||
|
BeginTextureMode(target); // Enable drawing to texture
|
||||||
|
ClearBackground(BLACK); // Clear the render texture
|
||||||
|
|
||||||
|
// Draw a rectangle in shader mode to be used as shader canvas
|
||||||
|
// NOTE: Rectangle uses font white character texture coordinates,
|
||||||
|
// So shader can not be applied here directly because input vertexTexCoord
|
||||||
|
// Do not represent full screen coordinates (space where want to apply shader)
|
||||||
|
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
|
||||||
|
EndTextureMode();
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(BLACK); // Clear screen background
|
||||||
|
|
||||||
|
// Draw the saved texture and rendered mandelbrot set with shader
|
||||||
|
// NOTE: We do not invert texture on Y, already considered inside shader
|
||||||
|
BeginShaderMode(shader);
|
||||||
|
// WARNING: If FLAG_WINDOW_HIGHDPI is enabled, HighDPI monitor scaling should be considered
|
||||||
|
// When rendering the RenderTexture2D to fit in the HighDPI scaled Window
|
||||||
|
DrawTextureEx(target.texture, (Vector2){ 0.0f, 0.0f }, 0.0f, 1.0f, WHITE);
|
||||||
|
EndShaderMode();
|
||||||
|
|
||||||
|
if (showControls)
|
||||||
|
{
|
||||||
|
DrawText("Press Mouse buttons right/left to zoom in/out and move", 10, 15, 10, RAYWHITE);
|
||||||
|
DrawText("Press F1 to toggle these controls", 10, 30, 10, RAYWHITE);
|
||||||
|
DrawText("Press [1 - 6] to change point of interest", 10, 45, 10, RAYWHITE);
|
||||||
|
DrawText("Press UP | DOWN to change number of iterations", 10, 60, 10, RAYWHITE);
|
||||||
|
DrawText("Press R to recenter the camera", 10, 75, 10, RAYWHITE);
|
||||||
|
}
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadShader(shader); // Unload shader
|
||||||
|
UnloadRenderTexture(target); // Unload render texture
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shaders/shaders_mandelbrot_set.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
|
|
@ -113,7 +113,7 @@ int main(void)
|
||||||
if (IsKeyPressed(KEY_N)) useNormalMap = !useNormalMap;
|
if (IsKeyPressed(KEY_N)) useNormalMap = !useNormalMap;
|
||||||
|
|
||||||
// Spin plane model at a constant rate
|
// Spin plane model at a constant rate
|
||||||
plane.transform = MatrixRotateY(GetTime()*0.5f);
|
plane.transform = MatrixRotateY((float)GetTime()*0.5f);
|
||||||
|
|
||||||
// Update shader values
|
// Update shader values
|
||||||
float lightPos[3] = {lightPosition.x, lightPosition.y, lightPosition.z};
|
float lightPos[3] = {lightPosition.x, lightPosition.y, lightPosition.z};
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
*
|
*
|
||||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||||
*
|
*
|
||||||
|
* Example contributed by Ramon Santamaria (@raysan5), reviewed by Jopestpe (@jopestpe)
|
||||||
|
*
|
||||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
* BSD-like license that allows static linking with closed source software
|
* BSD-like license that allows static linking with closed source software
|
||||||
*
|
*
|
||||||
|
|
@ -31,7 +33,9 @@ int main(void)
|
||||||
Vector2 ballPosition = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
Vector2 ballPosition = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||||
Vector2 ballSpeed = { 5.0f, 4.0f };
|
Vector2 ballSpeed = { 5.0f, 4.0f };
|
||||||
int ballRadius = 20;
|
int ballRadius = 20;
|
||||||
|
float gravity = 0.2f;
|
||||||
|
|
||||||
|
bool useGravity = true;
|
||||||
bool pause = 0;
|
bool pause = 0;
|
||||||
int framesCounter = 0;
|
int framesCounter = 0;
|
||||||
|
|
||||||
|
|
@ -43,6 +47,7 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
if (IsKeyPressed(KEY_G)) useGravity = !useGravity;
|
||||||
if (IsKeyPressed(KEY_SPACE)) pause = !pause;
|
if (IsKeyPressed(KEY_SPACE)) pause = !pause;
|
||||||
|
|
||||||
if (!pause)
|
if (!pause)
|
||||||
|
|
@ -50,9 +55,11 @@ int main(void)
|
||||||
ballPosition.x += ballSpeed.x;
|
ballPosition.x += ballSpeed.x;
|
||||||
ballPosition.y += ballSpeed.y;
|
ballPosition.y += ballSpeed.y;
|
||||||
|
|
||||||
|
if (useGravity) ballSpeed.y += gravity;
|
||||||
|
|
||||||
// Check walls collision for bouncing
|
// Check walls collision for bouncing
|
||||||
if ((ballPosition.x >= (GetScreenWidth() - ballRadius)) || (ballPosition.x <= ballRadius)) ballSpeed.x *= -1.0f;
|
if ((ballPosition.x >= (GetScreenWidth() - ballRadius)) || (ballPosition.x <= ballRadius)) ballSpeed.x *= -1.0f;
|
||||||
if ((ballPosition.y >= (GetScreenHeight() - ballRadius)) || (ballPosition.y <= ballRadius)) ballSpeed.y *= -1.0f;
|
if ((ballPosition.y >= (GetScreenHeight() - ballRadius)) || (ballPosition.y <= ballRadius)) ballSpeed.y *= -0.95f;
|
||||||
}
|
}
|
||||||
else framesCounter++;
|
else framesCounter++;
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
|
|
@ -66,6 +73,9 @@ int main(void)
|
||||||
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
|
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
|
||||||
DrawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, GetScreenHeight() - 25, 20, LIGHTGRAY);
|
DrawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, GetScreenHeight() - 25, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
if (useGravity) DrawText("GRAVITY: ON (Press G to disable)", 10, GetScreenHeight() - 50, 20, DARKGREEN);
|
||||||
|
else DrawText("GRAVITY: OFF (Press G to enable)", 10, GetScreenHeight() - 50, 20, RED);
|
||||||
|
|
||||||
// On pause, we draw a blinking message
|
// On pause, we draw a blinking message
|
||||||
if (pause && ((framesCounter/30)%2)) DrawText("PAUSED", 350, 200, 30, GRAY);
|
if (pause && ((framesCounter/30)%2)) DrawText("PAUSED", 350, 200, 30, GRAY);
|
||||||
|
|
||||||
|
|
|
||||||
248
examples/shapes/shapes_bullet_hell.c
Normal file
|
|
@ -0,0 +1,248 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - bullet hell
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Zero (@zerohorsepower) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Zero (@zerohorsepower)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <stdlib.h> // Required for: calloc(), free()
|
||||||
|
#include <math.h> // Required for: cosf(), sinf()
|
||||||
|
|
||||||
|
#define MAX_BULLETS 500000 // Max bullets to be processed
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef struct Bullet {
|
||||||
|
Vector2 position; // Bullet position on screen
|
||||||
|
Vector2 acceleration; // Amount of pixels to be incremented to position every frame
|
||||||
|
bool disabled; // Skip processing and draw case out of screen
|
||||||
|
Color color; // Bullet color
|
||||||
|
} Bullet;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - bullet hell");
|
||||||
|
|
||||||
|
// Bullets definition
|
||||||
|
Bullet *bullets = (Bullet *)RL_CALLOC(MAX_BULLETS, sizeof(Bullet)); // Bullets array
|
||||||
|
int bulletCount = 0;
|
||||||
|
int bulletDisabledCount = 0; // Used to calculate how many bullets are on screen
|
||||||
|
int bulletRadius = 10;
|
||||||
|
float bulletSpeed = 3.0f;
|
||||||
|
int bulletRows = 6;
|
||||||
|
Color bulletColor[2] = { RED, BLUE };
|
||||||
|
|
||||||
|
// Spawner variables
|
||||||
|
float baseDirection = 0;
|
||||||
|
int angleIncrement = 5; // After spawn all bullet rows, increment this value on the baseDirection for next the frame
|
||||||
|
float spawnCooldown = 2;
|
||||||
|
float spawnCooldownTimer = spawnCooldown;
|
||||||
|
|
||||||
|
// Magic circle
|
||||||
|
float magicCircleRotation = 0;
|
||||||
|
|
||||||
|
// Used on performance drawing
|
||||||
|
RenderTexture bulletTexture = LoadRenderTexture(24, 24);
|
||||||
|
|
||||||
|
// Draw circle to bullet texture, then draw bullet using DrawTexture()
|
||||||
|
// NOTE: This is done to improve the performance, since DrawCircle() is very slow
|
||||||
|
BeginTextureMode(bulletTexture);
|
||||||
|
DrawCircle(12, 12, (float)bulletRadius, WHITE);
|
||||||
|
DrawCircleLines(12, 12, (float)bulletRadius, BLACK);
|
||||||
|
EndTextureMode();
|
||||||
|
|
||||||
|
bool drawInPerformanceMode = true; // Switch between DrawCircle() and DrawTexture()
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Reset the bullet index
|
||||||
|
// New bullets will replace the old ones that are already disabled due to out-of-screen
|
||||||
|
if (bulletCount >= MAX_BULLETS)
|
||||||
|
{
|
||||||
|
bulletCount = 0;
|
||||||
|
bulletDisabledCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spawnCooldownTimer--;
|
||||||
|
if (spawnCooldownTimer < 0)
|
||||||
|
{
|
||||||
|
spawnCooldownTimer = spawnCooldown;
|
||||||
|
|
||||||
|
// Spawn bullets
|
||||||
|
float degreesPerRow = 360.0f/bulletRows;
|
||||||
|
for (int row = 0; row < bulletRows; row++)
|
||||||
|
{
|
||||||
|
if (bulletCount < MAX_BULLETS)
|
||||||
|
{
|
||||||
|
bullets[bulletCount].position = (Vector2){(float) screenWidth/2, (float) screenHeight/2};
|
||||||
|
bullets[bulletCount].disabled = false;
|
||||||
|
bullets[bulletCount].color = bulletColor[row%2];
|
||||||
|
|
||||||
|
float bulletDirection = baseDirection + (degreesPerRow*row);
|
||||||
|
|
||||||
|
// Bullet speed * bullet direction, this will determine how much pixels will be incremented/decremented
|
||||||
|
// from the bullet position every frame. Since the bullets doesn't change its direction and speed,
|
||||||
|
// only need to calculate it at the spawning time
|
||||||
|
// 0 degrees = right, 90 degrees = down, 180 degrees = left and 270 degrees = up, basically clockwise
|
||||||
|
// Case you want it to be anti-clockwise, add "* -1" at the y acceleration
|
||||||
|
bullets[bulletCount].acceleration = (Vector2){
|
||||||
|
bulletSpeed*cosf(bulletDirection*DEG2RAD),
|
||||||
|
bulletSpeed*sinf(bulletDirection*DEG2RAD)
|
||||||
|
};
|
||||||
|
|
||||||
|
bulletCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
baseDirection += angleIncrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update bullets position based on its acceleration
|
||||||
|
for (int i = 0; i < bulletCount; i++)
|
||||||
|
{
|
||||||
|
// Only update bullet if inside the screen
|
||||||
|
if (!bullets[i].disabled)
|
||||||
|
{
|
||||||
|
bullets[i].position.x += bullets[i].acceleration.x;
|
||||||
|
bullets[i].position.y += bullets[i].acceleration.y;
|
||||||
|
|
||||||
|
// Disable bullet if out of screen
|
||||||
|
if ((bullets[i].position.x < -bulletRadius*2) ||
|
||||||
|
(bullets[i].position.x > screenWidth + bulletRadius*2) ||
|
||||||
|
(bullets[i].position.y < -bulletRadius*2) ||
|
||||||
|
(bullets[i].position.y > screenHeight + bulletRadius*2))
|
||||||
|
{
|
||||||
|
bullets[i].disabled = true;
|
||||||
|
bulletDisabledCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input logic
|
||||||
|
if ((IsKeyPressed(KEY_RIGHT) || IsKeyPressed(KEY_D)) && (bulletRows < 359)) bulletRows++;
|
||||||
|
if ((IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_A)) && (bulletRows > 1)) bulletRows--;
|
||||||
|
if (IsKeyPressed(KEY_UP) || IsKeyPressed(KEY_W)) bulletSpeed += 0.25f;
|
||||||
|
if ((IsKeyPressed(KEY_DOWN) || IsKeyPressed(KEY_S)) && (bulletSpeed > 0.50f)) bulletSpeed -= 0.25f;
|
||||||
|
if (IsKeyPressed(KEY_Z) && (spawnCooldown > 1)) spawnCooldown--;
|
||||||
|
if (IsKeyPressed(KEY_X)) spawnCooldown++;
|
||||||
|
if (IsKeyPressed(KEY_ENTER)) drawInPerformanceMode = !drawInPerformanceMode;
|
||||||
|
|
||||||
|
if (IsKeyDown(KEY_SPACE))
|
||||||
|
{
|
||||||
|
angleIncrement += 1;
|
||||||
|
angleIncrement %= 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_C))
|
||||||
|
{
|
||||||
|
bulletCount = 0;
|
||||||
|
bulletDisabledCount = 0;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// Draw magic circle
|
||||||
|
magicCircleRotation++;
|
||||||
|
DrawRectanglePro((Rectangle){ (float)screenWidth/2, (float)screenHeight/2, 120, 120 },
|
||||||
|
(Vector2){ 60.0f, 60.0f }, magicCircleRotation, PURPLE);
|
||||||
|
DrawRectanglePro((Rectangle){ (float)screenWidth/2, (float)screenHeight/2, 120, 120 },
|
||||||
|
(Vector2){ 60.0f, 60.0f }, magicCircleRotation + 45, PURPLE);
|
||||||
|
DrawCircleLines(screenWidth/2, screenHeight/2, 70, BLACK);
|
||||||
|
DrawCircleLines(screenWidth/2, screenHeight/2, 50, BLACK);
|
||||||
|
DrawCircleLines(screenWidth/2, screenHeight/2, 30, BLACK);
|
||||||
|
|
||||||
|
// Draw bullets
|
||||||
|
if (drawInPerformanceMode)
|
||||||
|
{
|
||||||
|
// Draw bullets using pre-rendered texture containing circle
|
||||||
|
for (int i = 0; i < bulletCount; i++)
|
||||||
|
{
|
||||||
|
// Do not draw disabled bullets (out of screen)
|
||||||
|
if (!bullets[i].disabled)
|
||||||
|
{
|
||||||
|
DrawTexture(bulletTexture.texture,
|
||||||
|
(int)(bullets[i].position.x - bulletTexture.texture.width*0.5f),
|
||||||
|
(int)(bullets[i].position.y - bulletTexture.texture.height*0.5f),
|
||||||
|
bullets[i].color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Draw bullets using DrawCircle(), less performant
|
||||||
|
for (int i = 0; i < bulletCount; i++)
|
||||||
|
{
|
||||||
|
// Do not draw disabled bullets (out of screen)
|
||||||
|
if (!bullets[i].disabled)
|
||||||
|
{
|
||||||
|
DrawCircleV(bullets[i].position, (float)bulletRadius, bullets[i].color);
|
||||||
|
DrawCircleLinesV(bullets[i].position, (float)bulletRadius, BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw UI
|
||||||
|
DrawRectangle(10, 10, 280, 150, (Color){0,0, 0, 200 });
|
||||||
|
DrawText("Controls:", 20, 20, 10, LIGHTGRAY);
|
||||||
|
DrawText("- Right/Left or A/D: Change rows number", 40, 40, 10, LIGHTGRAY);
|
||||||
|
DrawText("- Up/Down or W/S: Change bullet speed", 40, 60, 10, LIGHTGRAY);
|
||||||
|
DrawText("- Z or X: Change spawn cooldown", 40, 80, 10, LIGHTGRAY);
|
||||||
|
DrawText("- Space (Hold): Change the angle increment", 40, 100, 10, LIGHTGRAY);
|
||||||
|
DrawText("- Enter: Switch draw method (Performance)", 40, 120, 10, LIGHTGRAY);
|
||||||
|
DrawText("- C: Clear bullets", 40, 140, 10, LIGHTGRAY);
|
||||||
|
|
||||||
|
DrawRectangle(610, 10, 170, 30, (Color){0,0, 0, 200 });
|
||||||
|
if (drawInPerformanceMode) DrawText("Draw method: DrawTexture(*)", 620, 20, 10, GREEN);
|
||||||
|
else DrawText("Draw method: DrawCircle(*)", 620, 20, 10, RED);
|
||||||
|
|
||||||
|
DrawRectangle(135, 410, 530, 30, (Color){0,0, 0, 200 });
|
||||||
|
DrawText(TextFormat("[ FPS: %d, Bullets: %d, Rows: %d, Bullet speed: %.2f, Angle increment per frame: %d, Cooldown: %.0f ]",
|
||||||
|
GetFPS(), bulletCount - bulletDisabledCount, bulletRows, bulletSpeed, angleIncrement, spawnCooldown),
|
||||||
|
155, 420, 10, GREEN);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadRenderTexture(bulletTexture); // Unload bullet texture
|
||||||
|
|
||||||
|
RL_FREE(bullets); // Free bullets array data
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_bullet_hell.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
230
examples/shapes/shapes_clock_of_clocks.c
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - clock of clocks
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 JP Mortiboys (@themushroompirates)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
#if defined(WIN32)
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include "raymath.h" // Required for: Lerp()
|
||||||
|
#include <time.h> // Required for: time(), localtime()
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - clock of clocks");
|
||||||
|
|
||||||
|
const Color bgColor = ColorLerp(DARKBLUE, BLACK, 0.75f);
|
||||||
|
const Color handsColor = ColorLerp(YELLOW, RAYWHITE, .25f);
|
||||||
|
|
||||||
|
const float clockFaceSize = 24;
|
||||||
|
const float clockFaceSpacing = 8.0f;
|
||||||
|
const float sectionSpacing = 16.0f;
|
||||||
|
|
||||||
|
const Vector2 TL = (Vector2){ 0.0f, 90.0f }; // Top-left corner
|
||||||
|
const Vector2 TR = (Vector2){ 90.0f, 180.0f }; // Top-right corner
|
||||||
|
const Vector2 BR = (Vector2){ 180.0f, 270.0f }; // Bottom-right corner
|
||||||
|
const Vector2 BL = (Vector2){ 0.0f, 270.0f }; // Bottom-left corner
|
||||||
|
const Vector2 HH = (Vector2){ 0.0f, 180.0f }; // Horizontal line
|
||||||
|
const Vector2 VV = (Vector2){ 90.0f, 270.0f }; // Vertical line
|
||||||
|
const Vector2 ZZ = (Vector2){ 135.0f, 135.0f }; // Not relevant
|
||||||
|
|
||||||
|
const Vector2 digitAngles[10][24] = {
|
||||||
|
/* 0 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,VV,VV,VV,/* */ VV,VV,VV,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
|
||||||
|
/* 1 */ { TL,HH,TR,ZZ, /* */ BL,TR,VV,ZZ,/* */ ZZ,VV,VV,ZZ,/* */ ZZ,VV,VV,ZZ,/* */ TL,BR,BL,TR,/* */ BL,HH,HH,BR },
|
||||||
|
/* 2 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ BL,HH,HH,BR },
|
||||||
|
/* 3 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
|
||||||
|
/* 4 */ { TL,TR,TL,TR, /* */ VV,VV,VV,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,TR,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,BL,BR },
|
||||||
|
/* 5 */ { TL,HH,HH,TR, /* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
|
||||||
|
/* 6 */ { TL,HH,HH,TR, /* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
|
||||||
|
/* 7 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,BL,BR },
|
||||||
|
/* 8 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
|
||||||
|
/* 9 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
|
||||||
|
};
|
||||||
|
// Time for the hands to move to the new position (in seconds); this must be <1s
|
||||||
|
const float handsMoveDuration = .5f;
|
||||||
|
|
||||||
|
// We store the previous seconds value so we can see if the time has changed
|
||||||
|
int prevSeconds = -1;
|
||||||
|
|
||||||
|
// This represents the real position where the hands are right now
|
||||||
|
Vector2 currentAngles[6][24] = { 0 };
|
||||||
|
|
||||||
|
// This is the position where the hands were moving from
|
||||||
|
Vector2 srcAngles[6][24] = { 0 };
|
||||||
|
// This is the position where the hands are moving to
|
||||||
|
Vector2 dstAngles[6][24] = { 0 };
|
||||||
|
|
||||||
|
// Current animation timer
|
||||||
|
float handsMoveTimer = 0.0f;
|
||||||
|
|
||||||
|
// 12 or 24 hour mode
|
||||||
|
int hourMode = 24;
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Get the current time
|
||||||
|
time_t rawtime;
|
||||||
|
struct tm *timeinfo;
|
||||||
|
|
||||||
|
time(&rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
|
||||||
|
if (timeinfo->tm_sec != prevSeconds) {
|
||||||
|
// The time has changed, so we need to move the hands to the new positions
|
||||||
|
prevSeconds = timeinfo->tm_sec;
|
||||||
|
|
||||||
|
// Format the current time so we can access the individual digits
|
||||||
|
const char *clockDigits = TextFormat("%02d%02d%02d", timeinfo->tm_hour % hourMode, timeinfo->tm_min, timeinfo->tm_sec);
|
||||||
|
|
||||||
|
// Fetch where we want all the hands to be
|
||||||
|
for (int digit = 0; digit < 6; digit++) {
|
||||||
|
for (int cell = 0; cell < 24; cell++) {
|
||||||
|
srcAngles[digit][cell] = currentAngles[digit][cell];
|
||||||
|
dstAngles[digit][cell] = digitAngles[ clockDigits[digit] - '0' ][cell];
|
||||||
|
|
||||||
|
// Quick exception for 12h mode
|
||||||
|
if (digit == 0 && hourMode == 12 && clockDigits[0] == '0') {
|
||||||
|
dstAngles[digit][cell] = ZZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srcAngles[digit][cell].x > dstAngles[digit][cell].x) {
|
||||||
|
srcAngles[digit][cell].x -= 360.0f;
|
||||||
|
}
|
||||||
|
if (srcAngles[digit][cell].y > dstAngles[digit][cell].y) {
|
||||||
|
srcAngles[digit][cell].y -= 360.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the timer
|
||||||
|
handsMoveTimer = -GetFrameTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now let's animate all the hands if we need to
|
||||||
|
if (handsMoveTimer < handsMoveDuration) {
|
||||||
|
// Increase the timer but don't go above the maximum
|
||||||
|
handsMoveTimer = Clamp(handsMoveTimer + GetFrameTime(), 0, handsMoveDuration);
|
||||||
|
|
||||||
|
// Calculate the % completion of the animation
|
||||||
|
float t = handsMoveTimer / handsMoveDuration;
|
||||||
|
|
||||||
|
// A little cheeky smoothstep
|
||||||
|
t = t * t * (3.0f - 2.0f * t);
|
||||||
|
|
||||||
|
for (int digit = 0; digit < 6; digit++) {
|
||||||
|
for (int cell = 0; cell < 24; cell++) {
|
||||||
|
currentAngles[digit][cell].x = Lerp(srcAngles[digit][cell].x, dstAngles[digit][cell].x, t);
|
||||||
|
currentAngles[digit][cell].y = Lerp(srcAngles[digit][cell].y, dstAngles[digit][cell].y, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handsMoveTimer == handsMoveDuration) {
|
||||||
|
// The animation has now finished
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle input
|
||||||
|
|
||||||
|
// Toggle between 12 and 24 hour mode with space
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) {
|
||||||
|
hourMode = 36 - hourMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(bgColor);
|
||||||
|
|
||||||
|
DrawText(TextFormat("%d-h mode, space to change", hourMode), 10, 30, 20, RAYWHITE);
|
||||||
|
|
||||||
|
float xOffset = 4.0f;
|
||||||
|
|
||||||
|
for (int digit = 0; digit < 6; digit++) {
|
||||||
|
|
||||||
|
for (int row = 0; row < 6; row++) {
|
||||||
|
for (int col = 0; col < 4; col++) {
|
||||||
|
Vector2 centre = (Vector2){
|
||||||
|
xOffset + col*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f,
|
||||||
|
100 + row*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f
|
||||||
|
};
|
||||||
|
DrawRing(centre, clockFaceSize * 0.5f - 2.0f, clockFaceSize * 0.5f, 0, 360, 24, DARKGRAY);
|
||||||
|
|
||||||
|
// Big hand
|
||||||
|
DrawRectanglePro(
|
||||||
|
(Rectangle){centre.x, centre.y, clockFaceSize*.5f+4.0f, 4.0f},
|
||||||
|
(Vector2){ 2.0f, 2.0f },
|
||||||
|
currentAngles[digit][row*4+col].x,
|
||||||
|
handsColor
|
||||||
|
);
|
||||||
|
|
||||||
|
// Little hand
|
||||||
|
DrawRectanglePro(
|
||||||
|
(Rectangle){centre.x, centre.y, clockFaceSize*.5f+2.0f, 4.0f},
|
||||||
|
(Vector2){ 2.0f, 2.0f },
|
||||||
|
currentAngles[digit][row*4+col].y,
|
||||||
|
handsColor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xOffset += (clockFaceSize+clockFaceSpacing) * 4;
|
||||||
|
if (digit % 2 == 1) {
|
||||||
|
|
||||||
|
DrawRing((Vector2){xOffset + 4.0f, 160.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor);
|
||||||
|
DrawRing((Vector2){xOffset + 4.0f, 225.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor);
|
||||||
|
|
||||||
|
xOffset += sectionSpacing;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_clock_of_clocks.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
|
@ -15,8 +15,6 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: abs()
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Program main entry point
|
// Program main entry point
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
96
examples/shapes/shapes_dashed_line.c
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - dashed line
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||||
|
*
|
||||||
|
* Example contributed by Luís Almeida (@luis605)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Luís Almeida (@luis605)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - dashed line");
|
||||||
|
|
||||||
|
// Line Properties
|
||||||
|
Vector2 lineStartPosition = { 20.0f, 50.0f };
|
||||||
|
Vector2 lineEndPosition = { 780.0f, 400.0f };
|
||||||
|
float dashLength = 25.0f;
|
||||||
|
float blankLength = 15.0f;
|
||||||
|
|
||||||
|
// Color selection
|
||||||
|
Color lineColors[] = { RED, ORANGE, GOLD, GREEN, BLUE, VIOLET, PINK, BLACK };
|
||||||
|
int colorIndex = 0;
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
lineEndPosition = GetMousePosition(); // Line endpoint follows the mouse
|
||||||
|
|
||||||
|
// Change Dash Length (UP/DOWN arrows)
|
||||||
|
if (IsKeyDown(KEY_UP)) dashLength += 1.0f;
|
||||||
|
if (IsKeyDown(KEY_DOWN) && dashLength > 1.0f) dashLength -= 1.0f;
|
||||||
|
|
||||||
|
// Change Space Length (LEFT/RIGHT arrows)
|
||||||
|
if (IsKeyDown(KEY_RIGHT)) blankLength += 1.0f;
|
||||||
|
if (IsKeyDown(KEY_LEFT) && blankLength > 1.0f) blankLength -= 1.0f;
|
||||||
|
|
||||||
|
// Cycle through colors ('C' key)
|
||||||
|
if (IsKeyPressed(KEY_C)) colorIndex = (colorIndex + 1)%(sizeof(lineColors)/sizeof(Color));
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// Draw the dashed line with the current properties
|
||||||
|
DrawLineDashed(lineStartPosition, lineEndPosition, (int)dashLength, (int)blankLength, lineColors[colorIndex]);
|
||||||
|
|
||||||
|
// Draw UI and Instructions
|
||||||
|
DrawRectangle(5, 5, 265, 95, Fade(SKYBLUE, 0.5f));
|
||||||
|
DrawRectangleLines(5, 5, 265, 95, BLUE);
|
||||||
|
|
||||||
|
DrawText("CONTROLS:", 15, 15, 10, BLACK);
|
||||||
|
DrawText("UP/DOWN: Change Dash Length", 15, 35, 10, BLACK);
|
||||||
|
DrawText("LEFT/RIGHT: Change Space Length", 15, 55, 10, BLACK);
|
||||||
|
DrawText("C: Cycle Color", 15, 75, 10, BLACK);
|
||||||
|
|
||||||
|
DrawText(TextFormat("Dash: %.0f | Space: %.0f", dashLength, blankLength), 15, 115, 10, DARKGRAY);
|
||||||
|
|
||||||
|
DrawFPS(screenWidth - 80, 10);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_dashed_line.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -15,6 +15,8 @@
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS // Disable some Visual Studio warnings
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
#include <math.h> // Required for: cosf(), sinf()
|
#include <math.h> // Required for: cosf(), sinf()
|
||||||
|
|
@ -158,7 +160,7 @@ static void UpdateClock(Clock *clock)
|
||||||
clock->minute.value = timeinfo->tm_min;
|
clock->minute.value = timeinfo->tm_min;
|
||||||
clock->hour.value = timeinfo->tm_hour;
|
clock->hour.value = timeinfo->tm_hour;
|
||||||
|
|
||||||
clock->hour.angle = (timeinfo->tm_hour%12)*180.0/6.0f;
|
clock->hour.angle = (timeinfo->tm_hour%12)*180.0f/6.0f;
|
||||||
clock->hour.angle += (timeinfo->tm_min%60)*30/60.0f;
|
clock->hour.angle += (timeinfo->tm_min%60)*30/60.0f;
|
||||||
clock->hour.angle -= 90;
|
clock->hour.angle -= 90;
|
||||||
|
|
||||||
|
|
@ -175,8 +177,8 @@ static void UpdateClock(Clock *clock)
|
||||||
static void DrawClockAnalog(Clock clock, Vector2 position)
|
static void DrawClockAnalog(Clock clock, Vector2 position)
|
||||||
{
|
{
|
||||||
// Draw clock base
|
// Draw clock base
|
||||||
DrawCircleV(position, clock.second.length + 40, LIGHTGRAY);
|
DrawCircleV(position, clock.second.length + 40.0f, LIGHTGRAY);
|
||||||
DrawCircleV(position, 12, GRAY);
|
DrawCircleV(position, 12.0f, GRAY);
|
||||||
|
|
||||||
// Draw clock minutes/seconds lines
|
// Draw clock minutes/seconds lines
|
||||||
for (int i = 0; i < 60; i++)
|
for (int i = 0; i < 60; i++)
|
||||||
|
|
@ -192,15 +194,15 @@ static void DrawClockAnalog(Clock clock, Vector2 position)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw hand seconds
|
// Draw hand seconds
|
||||||
DrawRectanglePro((Rectangle){ position.x, position.y, clock.second.length, clock.second.thickness },
|
DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.second.length, (float)clock.second.thickness },
|
||||||
(Vector2){ 0.0f, clock.second.thickness/2.0f }, clock.second.angle, clock.second.color);
|
(Vector2){ 0.0f, clock.second.thickness/2.0f }, clock.second.angle, clock.second.color);
|
||||||
|
|
||||||
// Draw hand minutes
|
// Draw hand minutes
|
||||||
DrawRectanglePro((Rectangle){ position.x, position.y, clock.minute.length, clock.minute.thickness },
|
DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.minute.length, (float)clock.minute.thickness },
|
||||||
(Vector2){ 0.0f, clock.minute.thickness/2.0f }, clock.minute.angle, clock.minute.color);
|
(Vector2){ 0.0f, clock.minute.thickness/2.0f }, clock.minute.angle, clock.minute.color);
|
||||||
|
|
||||||
// Draw hand hours
|
// Draw hand hours
|
||||||
DrawRectanglePro((Rectangle){ position.x, position.y, clock.hour.length, clock.hour.thickness },
|
DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.hour.length, (float)clock.hour.thickness },
|
||||||
(Vector2){ 0.0f, clock.hour.thickness/2.0f }, clock.hour.angle, clock.hour.color);
|
(Vector2){ 0.0f, clock.hour.thickness/2.0f }, clock.hour.angle, clock.hour.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,14 +214,14 @@ static void DrawClockDigital(Clock clock, Vector2 position)
|
||||||
DrawDisplayValue((Vector2){ position.x, position.y }, clock.hour.value/10, RED, Fade(LIGHTGRAY, 0.3f));
|
DrawDisplayValue((Vector2){ position.x, position.y }, clock.hour.value/10, RED, Fade(LIGHTGRAY, 0.3f));
|
||||||
DrawDisplayValue((Vector2){ position.x + 120, position.y }, clock.hour.value%10, RED, Fade(LIGHTGRAY, 0.3f));
|
DrawDisplayValue((Vector2){ position.x + 120, position.y }, clock.hour.value%10, RED, Fade(LIGHTGRAY, 0.3f));
|
||||||
|
|
||||||
DrawCircle(position.x + 240, position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
|
DrawCircle((int)position.x + 240, (int)position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
|
||||||
DrawCircle(position.x + 240, position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
|
DrawCircle((int)position.x + 240, (int)position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
|
||||||
|
|
||||||
DrawDisplayValue((Vector2){ position.x + 260, position.y }, clock.minute.value/10, RED, Fade(LIGHTGRAY, 0.3f));
|
DrawDisplayValue((Vector2){ position.x + 260, position.y }, clock.minute.value/10, RED, Fade(LIGHTGRAY, 0.3f));
|
||||||
DrawDisplayValue((Vector2){ position.x + 380, position.y }, clock.minute.value%10, RED, Fade(LIGHTGRAY, 0.3f));
|
DrawDisplayValue((Vector2){ position.x + 380, position.y }, clock.minute.value%10, RED, Fade(LIGHTGRAY, 0.3f));
|
||||||
|
|
||||||
DrawCircle(position.x + 500, position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
|
DrawCircle((int)position.x + 500, (int)position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
|
||||||
DrawCircle(position.x + 500, position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
|
DrawCircle((int)position.x + 500, (int)position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
|
||||||
|
|
||||||
DrawDisplayValue((Vector2){ position.x + 520, position.y }, clock.second.value/10, RED, Fade(LIGHTGRAY, 0.3f));
|
DrawDisplayValue((Vector2){ position.x + 520, position.y }, clock.second.value/10, RED, Fade(LIGHTGRAY, 0.3f));
|
||||||
DrawDisplayValue((Vector2){ position.x + 640, position.y }, clock.second.value%10, RED, Fade(LIGHTGRAY, 0.3f));
|
DrawDisplayValue((Vector2){ position.x + 640, position.y }, clock.second.value%10, RED, Fade(LIGHTGRAY, 0.3f));
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
// Constant for Simulation
|
// Constant for Simulation
|
||||||
#define SIMULATION_STEPS 30
|
#define SIMULATION_STEPS 30
|
||||||
#define G 9.81
|
#define G 9.81f
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Declaration
|
// Module Functions Declaration
|
||||||
|
|
@ -43,9 +43,9 @@ int main(void)
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - double pendulum");
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - double pendulum");
|
||||||
|
|
||||||
// Simulation Paramters
|
// Simulation Paramters
|
||||||
float l1 = 15, m1 = 0.2, theta1 = DEG2RAD*170, w1 = 0;
|
float l1 = 15.0f, m1 = 0.2f, theta1 = DEG2RAD*170, w1 = 0;
|
||||||
float l2 = 15, m2 = 0.1, theta2 = DEG2RAD*0, w2 = 0;
|
float l2 = 15.0f, m2 = 0.1f, theta2 = DEG2RAD*0, w2 = 0;
|
||||||
float lengthScaler = 0.1;
|
float lengthScaler = 0.1f;
|
||||||
float totalM = m1 + m2;
|
float totalM = m1 + m2;
|
||||||
|
|
||||||
Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
|
Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
|
||||||
|
|
@ -57,8 +57,8 @@ int main(void)
|
||||||
float L2 = l2*lengthScaler;
|
float L2 = l2*lengthScaler;
|
||||||
|
|
||||||
// Draw parameters
|
// Draw parameters
|
||||||
int lineThick = 20, trailThick = 2;
|
float lineThick = 20, trailThick = 2;
|
||||||
float fateAlpha = 0.01;
|
float fateAlpha = 0.01f;
|
||||||
|
|
||||||
// Create framebuffer
|
// Create framebuffer
|
||||||
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
|
||||||
|
|
@ -129,15 +129,15 @@ int main(void)
|
||||||
ClearBackground(BLACK);
|
ClearBackground(BLACK);
|
||||||
|
|
||||||
// Draw trails texture
|
// Draw trails texture
|
||||||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
||||||
|
|
||||||
// Draw double pendulum
|
// Draw double pendulum
|
||||||
DrawRectanglePro((Rectangle){ screenWidth/2, screenHeight/2 - 100, 10*l1, lineThick },
|
DrawRectanglePro((Rectangle){ screenWidth/2.0f, screenHeight/2.0f - 100, 10*l1, lineThick },
|
||||||
(Vector2){0, lineThick*0.5}, 90 - RAD2DEG*theta1, RAYWHITE);
|
(Vector2){0, lineThick*0.5f}, 90 - RAD2DEG*theta1, RAYWHITE);
|
||||||
|
|
||||||
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
|
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
|
||||||
DrawRectanglePro((Rectangle){ screenWidth/2 + endpoint1.x, screenHeight/2 - 100 + endpoint1.y, 10*l2, lineThick },
|
DrawRectanglePro((Rectangle){ screenWidth/2.0f + endpoint1.x, screenHeight/2.0f - 100 + endpoint1.y, 10*l2, lineThick },
|
||||||
(Vector2){0, lineThick*0.5}, 90 - RAD2DEG*theta2, RAYWHITE);
|
(Vector2){0, lineThick*0.5f}, 90 - RAD2DEG*theta2, RAYWHITE);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -159,7 +159,7 @@ int main(void)
|
||||||
// Calculate pendulum end point
|
// Calculate pendulum end point
|
||||||
static Vector2 CalculatePendulumEndPoint(float l, float theta)
|
static Vector2 CalculatePendulumEndPoint(float l, float theta)
|
||||||
{
|
{
|
||||||
return (Vector2){ 10*l*sin(theta), 10*l*cos(theta) };
|
return (Vector2){ 10*l*sinf(theta), 10*l*cosf(theta) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate double pendulum end point
|
// Calculate double pendulum end point
|
||||||
|
|
|
||||||
92
examples/shapes/shapes_kaleidoscope.c
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - kaleidoscope
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Hugo ARNAL (@hugoarnal) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Hugo ARNAL (@hugoarnal)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - kaleidoscope");
|
||||||
|
|
||||||
|
int symmetry = 6;
|
||||||
|
float angle = 360.0f/(float)symmetry;
|
||||||
|
float thickness = 3.0f;
|
||||||
|
Vector2 prevMousePos = { 0 };
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
ClearBackground(BLACK);
|
||||||
|
|
||||||
|
Vector2 offset = { (float)screenWidth/2.0f, (float)screenHeight/2.0f };
|
||||||
|
Camera2D camera = { 0 };
|
||||||
|
camera.target = (Vector2){ 0 };
|
||||||
|
camera.offset = offset;
|
||||||
|
camera.rotation = 0.0f;
|
||||||
|
camera.zoom = 1.0f;
|
||||||
|
|
||||||
|
Vector2 scaleVector = { 1.0f, -1.0f };
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
Vector2 mousePos = GetMousePosition();
|
||||||
|
Vector2 lineStart = Vector2Subtract(mousePos, offset);
|
||||||
|
Vector2 lineEnd = Vector2Subtract(prevMousePos, offset);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
BeginMode2D(camera);
|
||||||
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) {
|
||||||
|
for (int i = 0; i < symmetry; i++) {
|
||||||
|
lineStart = Vector2Rotate(lineStart, angle*DEG2RAD);
|
||||||
|
lineEnd = Vector2Rotate(lineEnd, angle*DEG2RAD);
|
||||||
|
|
||||||
|
DrawLineEx(lineStart, lineEnd, thickness, WHITE);
|
||||||
|
|
||||||
|
Vector2 reflectLineStart = Vector2Multiply(lineStart, scaleVector);
|
||||||
|
Vector2 reflectLineEnd = Vector2Multiply(lineEnd, scaleVector);
|
||||||
|
|
||||||
|
DrawLineEx(reflectLineStart, reflectLineEnd, thickness, WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prevMousePos = mousePos;
|
||||||
|
EndMode2D();
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_kaleidoscope.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
146
examples/shapes/shapes_lines_drawing.c
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - lines drawing
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025-2025 Robin (@RobinsAviary)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - lines drawing");
|
||||||
|
|
||||||
|
// Hint text that shows before you click the screen
|
||||||
|
bool startText = true;
|
||||||
|
|
||||||
|
// The mouse's position on the previous frame
|
||||||
|
Vector2 mousePositionPrevious = GetMousePosition();
|
||||||
|
|
||||||
|
// The canvas to draw lines on
|
||||||
|
RenderTexture canvas = LoadRenderTexture(screenWidth, screenHeight);
|
||||||
|
|
||||||
|
// The background color of the canvas
|
||||||
|
const Color backgroundColor = RAYWHITE;
|
||||||
|
|
||||||
|
// The line's thickness
|
||||||
|
float lineThickness = 8.0f;
|
||||||
|
// The lines hue (in HSV, from 0-360)
|
||||||
|
float lineHue = 0.0f;
|
||||||
|
|
||||||
|
// Clear the canvas to the background color
|
||||||
|
BeginTextureMode(canvas);
|
||||||
|
ClearBackground(backgroundColor);
|
||||||
|
EndTextureMode();
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Disable the hint text once the user clicks
|
||||||
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && startText)
|
||||||
|
{
|
||||||
|
startText = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the canvas when the user middle-clicks
|
||||||
|
if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE))
|
||||||
|
{
|
||||||
|
BeginTextureMode(canvas);
|
||||||
|
ClearBackground(backgroundColor);
|
||||||
|
EndTextureMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store whether the left and right buttons are down
|
||||||
|
bool leftButtonDown = IsMouseButtonDown(MOUSE_BUTTON_LEFT);
|
||||||
|
bool rightButtonDown = IsMouseButtonDown(MOUSE_BUTTON_RIGHT);
|
||||||
|
|
||||||
|
if (leftButtonDown || rightButtonDown)
|
||||||
|
{
|
||||||
|
// The color for the line
|
||||||
|
Color drawColor;
|
||||||
|
|
||||||
|
if (leftButtonDown)
|
||||||
|
{
|
||||||
|
// Increase the hue value by the distance our cursor has moved since the last frame (divided by 3)
|
||||||
|
lineHue += Vector2Distance(mousePositionPrevious, GetMousePosition())/3.0f;
|
||||||
|
|
||||||
|
// While the hue is >=360, subtract it to bring it down into the range 0-360
|
||||||
|
// This is more visually accurate than resetting to zero
|
||||||
|
while (lineHue >= 360.0f)
|
||||||
|
{
|
||||||
|
lineHue -= 360.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the final color
|
||||||
|
drawColor = ColorFromHSV(lineHue, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
else if (rightButtonDown)
|
||||||
|
{
|
||||||
|
// Use the background color as an "eraser"
|
||||||
|
drawColor = backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the line onto the canvas
|
||||||
|
BeginTextureMode(canvas);
|
||||||
|
// Circles act as "caps", smoothing corners
|
||||||
|
DrawCircleV(mousePositionPrevious, lineThickness/2.0f, drawColor);
|
||||||
|
DrawCircleV(GetMousePosition(), lineThickness/2.0f, drawColor);
|
||||||
|
DrawLineEx(mousePositionPrevious, GetMousePosition(), lineThickness, drawColor);
|
||||||
|
EndTextureMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update line thickness based on mousewheel
|
||||||
|
lineThickness += GetMouseWheelMove();
|
||||||
|
lineThickness = Clamp(lineThickness, 1.0, 500.0f);
|
||||||
|
|
||||||
|
// Update mouse's previous position
|
||||||
|
mousePositionPrevious = GetMousePosition();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
// Draw the render texture to the screen, flipped vertically to make it appear top-side up
|
||||||
|
DrawTextureRec(canvas.texture, (Rectangle){ 0.0f, 0.0f, (float)canvas.texture.width,(float)-canvas.texture.height }, Vector2Zero(), WHITE);
|
||||||
|
|
||||||
|
// Draw the preview circle
|
||||||
|
if (!leftButtonDown) DrawCircleLinesV(GetMousePosition(), lineThickness/2.0f, (Color){ 127, 127, 127, 127 });
|
||||||
|
|
||||||
|
// Draw the hint text
|
||||||
|
if (startText) DrawText("try clicking and dragging!", 275, 215, 20, LIGHTGRAY);
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Unload the canvas render texture
|
||||||
|
UnloadRenderTexture(canvas);
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_lines_drawing.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
102
examples/shapes/shapes_math_angle_rotation.c
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - Math angle rotation lines
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Kris (@krispy-snacc) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h" // for DEG2RAD
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 720;
|
||||||
|
const int screenHeight = 400;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - angle rotation lines");
|
||||||
|
SetTargetFPS(60);
|
||||||
|
|
||||||
|
Vector2 center = { screenWidth / 2.0f, screenHeight / 2.0f };
|
||||||
|
const float lineLength = 150.0f;
|
||||||
|
|
||||||
|
// Predefined angles for fixed lines
|
||||||
|
int angles[] = { 0, 30, 60, 90 };
|
||||||
|
int numAngles = sizeof(angles)/sizeof(angles[0]);
|
||||||
|
|
||||||
|
float totalAngle = 0.0f; // Animated rotation angle
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose())
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
totalAngle += 1.0f; // degrees per frame
|
||||||
|
if (totalAngle >= 360.0f) totalAngle -= 360.0f;
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
|
||||||
|
DrawText("Fixed angles + rotating line", 10, 10, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
// Draw fixed-angle lines with colorful gradient
|
||||||
|
for (int i = 0; i < numAngles; i++)
|
||||||
|
{
|
||||||
|
float rad = angles[i] * DEG2RAD;
|
||||||
|
Vector2 end = { center.x + cosf(rad) * lineLength,
|
||||||
|
center.y + sinf(rad) * lineLength };
|
||||||
|
|
||||||
|
// Gradient color from green → cyan → blue → magenta
|
||||||
|
Color col;
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 0: col = GREEN; break;
|
||||||
|
case 1: col = ORANGE; break;
|
||||||
|
case 2: col = BLUE; break;
|
||||||
|
case 3: col = MAGENTA; break;
|
||||||
|
default: col = WHITE; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawLineEx(center, end, 5.0f, col);
|
||||||
|
|
||||||
|
// Draw angle label slightly offset along the line
|
||||||
|
Vector2 textPos = { center.x + cosf(rad) * (lineLength + 20),
|
||||||
|
center.y + sinf(rad) * (lineLength + 20) };
|
||||||
|
DrawText(TextFormat("%d°", angles[i]), (int)textPos.x, (int)textPos.y, 20, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw animated rotating line with changing color
|
||||||
|
float animRad = totalAngle * DEG2RAD;
|
||||||
|
Vector2 animEnd = { center.x + cosf(animRad) * lineLength,
|
||||||
|
center.y + sinf(animRad) * lineLength };
|
||||||
|
|
||||||
|
// Cycle through HSV colors for animated line
|
||||||
|
Color animCol = ColorFromHSV(fmodf(totalAngle, 360.0f), 0.8f, 0.9f);
|
||||||
|
DrawLineEx(center, animEnd, 5.0f, animCol);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow();
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_math_angle_rotation.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
176
examples/shapes/shapes_math_sine_cosine.c
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - math sine cosine
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by Jopestpe (@jopestpe)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025-2025 Jopestpe (@jopestpe)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "raygui.h" // Required for GUI controls
|
||||||
|
|
||||||
|
// Wave points for sine/cosine visualization
|
||||||
|
#define WAVE_POINTS 36
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math sine cosine");
|
||||||
|
|
||||||
|
Vector2 sinePoints[WAVE_POINTS];
|
||||||
|
Vector2 cosPoints[WAVE_POINTS];
|
||||||
|
Vector2 center = { (screenWidth/2.0f) - 30.f, screenHeight/2.0f };
|
||||||
|
Rectangle start = { 20.f, screenHeight - 120.f , 200.0f, 100.0f};
|
||||||
|
float radius = 130.0f;
|
||||||
|
float angle = 0.0f;
|
||||||
|
bool pause = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < WAVE_POINTS; i++)
|
||||||
|
{
|
||||||
|
float t = i/(float)(WAVE_POINTS - 1);
|
||||||
|
float currentAngle = t*360.0f*DEG2RAD;
|
||||||
|
sinePoints[i] = (Vector2){ start.x + t*start.width, start.y + start.height/2.0f - sinf(currentAngle)*(start.height/2.0f) };
|
||||||
|
cosPoints[i] = (Vector2){ start.x + t*start.width, start.y + start.height/2.0f - cosf(currentAngle)*(start.height/2.0f) };
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
float angleRad = angle*DEG2RAD;
|
||||||
|
float cosRad = cosf(angleRad);
|
||||||
|
float sinRad = sinf(angleRad);
|
||||||
|
|
||||||
|
Vector2 point = { center.x + cosRad*radius, center.y - sinRad*radius };
|
||||||
|
Vector2 limitMin = { center.x - radius, center.y - radius };
|
||||||
|
Vector2 limitMax = { center.x + radius, center.y + radius };
|
||||||
|
|
||||||
|
float complementary = 90.0f - angle;
|
||||||
|
float supplementary = 180.0f - angle;
|
||||||
|
float explementary = 360.0f - angle;
|
||||||
|
|
||||||
|
float tangent = Clamp(tanf(angleRad), -10.0f, 10.0f);
|
||||||
|
float cotangent = (fabsf(tangent) > 0.001f) ? Clamp(1.0f/tangent, -radius, radius) : 0.0f;
|
||||||
|
Vector2 tangentPoint = { center.x + radius, center.y - tangent*radius };
|
||||||
|
Vector2 cotangentPoint = { center.x + cotangent*radius, center.y - radius };
|
||||||
|
|
||||||
|
angle = Wrap(angle + (!pause ? 1.0f : 0.0f), 0.0f, 360.0f);
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// Cotangent (orange)
|
||||||
|
DrawLineEx((Vector2){ center.x , limitMin.y }, (Vector2){ cotangentPoint.x, limitMin.y }, 2.0f, ORANGE);
|
||||||
|
DrawLineDashed(center, cotangentPoint, 10.0f, 4.0f, ORANGE);
|
||||||
|
|
||||||
|
// Side background
|
||||||
|
DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
|
||||||
|
DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 });
|
||||||
|
|
||||||
|
// Base circle and axes
|
||||||
|
DrawCircleLinesV(center, radius, GRAY);
|
||||||
|
DrawLineEx((Vector2){ center.x, limitMin.y }, (Vector2){ center.x, limitMax.y }, 1.0f, GRAY);
|
||||||
|
DrawLineEx((Vector2){ limitMin.x, center.y }, (Vector2){ limitMax.x, center.y }, 1.f, GRAY);
|
||||||
|
|
||||||
|
// Wave graph axes
|
||||||
|
DrawLineEx((Vector2){ start.x , start.y }, (Vector2){ start.x , start.y + start.height }, 2.0f, GRAY);
|
||||||
|
DrawLineEx((Vector2){ start.x + start.width, start.y }, (Vector2){ start.x + start.width, start.y + start.height }, 2.0f, GRAY);
|
||||||
|
DrawLineEx((Vector2){ start.x, start.y + start.height/2 }, (Vector2){ start.x + start.width, start.y + start.height/2 }, 2.0f, GRAY);
|
||||||
|
|
||||||
|
// Wave graph axis labels
|
||||||
|
DrawText("1", start.x - 8, start.y, 6, GRAY);
|
||||||
|
DrawText("0", start.x - 8, start.y + start.height/2 - 6, 6, GRAY);
|
||||||
|
DrawText("-1", start.x - 12, start.y + start.height - 8, 6, GRAY);
|
||||||
|
DrawText("0", start.x - 2, start.y + start.height + 4, 6, GRAY);
|
||||||
|
DrawText("360", start.x + start.width - 8, start.y + start.height + 4, 6, GRAY);
|
||||||
|
|
||||||
|
// Sine (red - vertical)
|
||||||
|
DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ center.x, point.y }, 2.0f, RED);
|
||||||
|
DrawLineDashed((Vector2){ point.x, center.y }, (Vector2){ point.x, point.y }, 10.0f, 4.0f, RED);
|
||||||
|
DrawText(TextFormat("Sine %.2f", sinRad), 640, 190, 6, RED);
|
||||||
|
DrawCircleV((Vector2){ start.x + (angle/360.0f)*start.width, start.y + ((-sinRad + 1)*start.height/2.0f) }, 4.0f, RED);
|
||||||
|
DrawSplineLinear(sinePoints, WAVE_POINTS, 1.0f, RED);
|
||||||
|
|
||||||
|
// Cosine (blue - horizontal)
|
||||||
|
DrawLineEx((Vector2){ center.x, center.y }, (Vector2){ point.x, center.y }, 2.0f, BLUE);
|
||||||
|
DrawLineDashed((Vector2){ center.x , point.y }, (Vector2){ point.x, point.y }, 10.0f, 4.0f, BLUE);
|
||||||
|
DrawText(TextFormat("Cosine %.2f", cosRad), 640, 210, 6, BLUE);
|
||||||
|
DrawCircleV((Vector2){ start.x + (angle/360.0f)*start.width, start.y + ((-cosRad + 1)*start.height/2.0f) }, 4.0f, BLUE);
|
||||||
|
DrawSplineLinear(cosPoints, WAVE_POINTS, 1.0f, BLUE);
|
||||||
|
|
||||||
|
// Tangent (purple)
|
||||||
|
DrawLineEx((Vector2){ limitMax.x , center.y }, (Vector2){ limitMax.x, tangentPoint.y }, 2.0f, PURPLE);
|
||||||
|
DrawLineDashed(center, tangentPoint, 10.0f, 4.0f, PURPLE);
|
||||||
|
DrawText(TextFormat("Tangent %.2f", tangent), 640, 230, 6, PURPLE);
|
||||||
|
|
||||||
|
// Cotangent (orange)
|
||||||
|
DrawText(TextFormat("Cotangent %.2f", cotangent), 640, 250, 6, ORANGE);
|
||||||
|
|
||||||
|
// Complementary angle (beige)
|
||||||
|
DrawCircleSectorLines(center, radius*0.6f , -angle, -90.f , 36.0f, BEIGE);
|
||||||
|
DrawText(TextFormat("Complementary %0.f°",complementary), 640, 150, 6, BEIGE);
|
||||||
|
|
||||||
|
// Supplementary angle (darkblue)
|
||||||
|
DrawCircleSectorLines(center, radius*0.5f , -angle, -180.f , 36.0f, DARKBLUE);
|
||||||
|
DrawText(TextFormat("Supplementary %0.f°",supplementary), 640, 130, 6, DARKBLUE);
|
||||||
|
|
||||||
|
// Explementary angle (pink)
|
||||||
|
DrawCircleSectorLines(center, radius*0.4f , -angle, -360.f , 36.0f, PINK);
|
||||||
|
DrawText(TextFormat("Explementary %0.f°",explementary), 640, 170, 6, PINK);
|
||||||
|
|
||||||
|
// Current angle - arc (lime), radius (black), endpoint (black)
|
||||||
|
DrawCircleSectorLines(center, radius*0.7f , -angle, 0.f, 36.0f, LIME);
|
||||||
|
DrawLineEx((Vector2){ center.x , center.y }, point, 2.0f, BLACK);
|
||||||
|
DrawCircleV(point, 4.0f, BLACK);
|
||||||
|
|
||||||
|
// Draw GUI controls
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(GRAY));
|
||||||
|
GuiToggle((Rectangle){ 640, 70, 120, 20}, TextFormat("Pause"), &pause);
|
||||||
|
GuiSetStyle(LABEL, TEXT_COLOR_NORMAL, ColorToInt(LIME));
|
||||||
|
GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f°", angle), &angle, 0.0f, 360.f);
|
||||||
|
|
||||||
|
// Angle values panel
|
||||||
|
GuiGroupBox((Rectangle){ 620, 110, 140, 170}, "Angle Values");
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_math_sine_cosine.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
102
examples/shapes/shapes_mouse_trail.c
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - Draw a mouse trail (position history)
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★☆☆☆] 1/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Balamurugan R (@Bala050814]) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Balamurugan R (@Bala050814)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
// Define the maximum number of positions to store in the trail
|
||||||
|
#define MAX_TRAIL_LENGTH 30
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - mouse trail");
|
||||||
|
|
||||||
|
// Array to store the history of mouse positions (our fixed-size queue)
|
||||||
|
Vector2 trailPositions[MAX_TRAIL_LENGTH] = { 0 };
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
Vector2 mousePosition = GetMousePosition();
|
||||||
|
|
||||||
|
// Shift all existing positions backward by one slot in the array
|
||||||
|
// The last element (the oldest position) is dropped
|
||||||
|
for (int i = MAX_TRAIL_LENGTH - 1; i > 0; i--)
|
||||||
|
{
|
||||||
|
trailPositions[i] = trailPositions[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the new, current mouse position at the start of the array (Index 0)
|
||||||
|
trailPositions[0] = mousePosition;
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(BLACK);
|
||||||
|
|
||||||
|
// Draw the trail by looping through the history array
|
||||||
|
for (int i = 0; i < MAX_TRAIL_LENGTH; i++)
|
||||||
|
{
|
||||||
|
// Ensure we skip drawing if the array hasn't been fully filled on startup
|
||||||
|
if ((trailPositions[i].x != 0.0f) || (trailPositions[i].y != 0.0f))
|
||||||
|
{
|
||||||
|
// Calculate relative trail strength (ratio is near 1.0 for new, near 0.0 for old)
|
||||||
|
float ratio = (float)(MAX_TRAIL_LENGTH - i) / MAX_TRAIL_LENGTH;
|
||||||
|
|
||||||
|
// Fade effect: oldest positions are more transparent
|
||||||
|
// Fade (color, alpha) - alpha is 0.5 to 1.0 based on ratio
|
||||||
|
Color trailColor = Fade(SKYBLUE, ratio*0.5f + 0.5f);
|
||||||
|
|
||||||
|
// Size effect: oldest positions are smaller
|
||||||
|
float trailRadius = 15.0f*ratio;
|
||||||
|
|
||||||
|
DrawCircleV(trailPositions[i], trailRadius, trailColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a distinct white circle for the current mouse position (Index 0)
|
||||||
|
DrawCircleV(mousePosition, 15.0f, WHITE);
|
||||||
|
|
||||||
|
DrawText("Move the mouse to see the trail effect!", 10, screenHeight - 30, 20, LIGHTGRAY);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_mouse_trail.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
228
examples/shapes/shapes_pie_chart.c
Normal file
|
|
@ -0,0 +1,228 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - pie chart
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Gideon Serfontein (@GideonSerf) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Gideon Serfontein (@GideonSerf)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "raygui.h"
|
||||||
|
|
||||||
|
#define MAX_PIE_SLICES 10 // Max pie slices
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - pie chart");
|
||||||
|
|
||||||
|
int sliceCount = 7;
|
||||||
|
float donutInnerRadius = 25.0f;
|
||||||
|
float values[MAX_PIE_SLICES] = { 300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f }; // Initial slice values
|
||||||
|
char labels[MAX_PIE_SLICES][32] = { 0 };
|
||||||
|
bool editingLabel[MAX_PIE_SLICES] = { 0 };
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_PIE_SLICES; i++)
|
||||||
|
snprintf(labels[i], 32, "Slice %02i", i + 1);
|
||||||
|
|
||||||
|
bool showValues = true;
|
||||||
|
bool showPercentages = false;
|
||||||
|
bool showDonut = false;
|
||||||
|
int hoveredSlice = -1;
|
||||||
|
Rectangle scrollPanelBounds = {0};
|
||||||
|
Vector2 scrollContentOffset = {0};
|
||||||
|
Rectangle view = { 0 };
|
||||||
|
|
||||||
|
// UI layout parameters
|
||||||
|
const int panelWidth = 270;
|
||||||
|
const int panelMargin = 5;
|
||||||
|
|
||||||
|
// UI Panel top-left anchor
|
||||||
|
const Vector2 panelPos = {
|
||||||
|
(float)screenWidth - panelMargin - panelWidth,
|
||||||
|
(float)panelMargin
|
||||||
|
};
|
||||||
|
|
||||||
|
// UI Panel rectangle
|
||||||
|
const Rectangle panelRect = {
|
||||||
|
panelPos.x, panelPos.y,
|
||||||
|
(float)panelWidth,
|
||||||
|
(float)screenHeight - 2.0f*panelMargin
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pie chart geometry
|
||||||
|
const Rectangle canvas = { 0, 0, panelPos.x, (float)screenHeight };
|
||||||
|
const Vector2 center = { canvas.width/2.0f, canvas.height/2.0f};
|
||||||
|
const float radius = 205.0f;
|
||||||
|
|
||||||
|
// Total value for percentage calculations
|
||||||
|
float totalValue = 0.0f;
|
||||||
|
|
||||||
|
SetTargetFPS(60);
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose())
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Calculate total value for percentage calculations
|
||||||
|
totalValue = 0.0f;
|
||||||
|
for (int i = 0; i < sliceCount; i++) totalValue += values[i];
|
||||||
|
|
||||||
|
// Check for mouse hover over slices
|
||||||
|
hoveredSlice = -1; // Reset hovered slice
|
||||||
|
Vector2 mousePos = GetMousePosition();
|
||||||
|
if (CheckCollisionPointRec(mousePos, canvas)) // Only check if mouse is inside the canvas
|
||||||
|
{
|
||||||
|
float dx = mousePos.x - center.x;
|
||||||
|
float dy = mousePos.y - center.y;
|
||||||
|
float distance = sqrtf(dx*dx + dy*dy);
|
||||||
|
|
||||||
|
if (distance <= radius) // Inside the pie radius
|
||||||
|
{
|
||||||
|
float angle = atan2f(dy, dx)*RAD2DEG;
|
||||||
|
if (angle < 0) angle += 360;
|
||||||
|
|
||||||
|
float currentAngle = 0.0f;
|
||||||
|
for (int i = 0; i < sliceCount; i++)
|
||||||
|
{
|
||||||
|
float sweep = (totalValue > 0)? (values[i]/totalValue)*360.0f : 0.0f;
|
||||||
|
|
||||||
|
if ((angle >= currentAngle) && (angle < (currentAngle + sweep)))
|
||||||
|
{
|
||||||
|
hoveredSlice = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentAngle += sweep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// Draw the pie chart on the canvas
|
||||||
|
float startAngle = 0.0f;
|
||||||
|
for (int i = 0; i < sliceCount; i++)
|
||||||
|
{
|
||||||
|
float sweepAngle = (totalValue > 0)? (values[i]/totalValue)*360.0f : 0.0f;
|
||||||
|
float midAngle = startAngle + sweepAngle/2.0f; // Middle angle for label positioning
|
||||||
|
|
||||||
|
Color color = ColorFromHSV((float)i/sliceCount*360.0f, 0.75f, 0.9f);
|
||||||
|
float currentRadius = radius;
|
||||||
|
|
||||||
|
// Make the hovered slice pop out by adding 5 pixels to its radius
|
||||||
|
if (i == hoveredSlice) currentRadius += 20.0f;
|
||||||
|
|
||||||
|
// Draw the pie slice using raylib's DrawCircleSector function
|
||||||
|
DrawCircleSector(center, currentRadius, startAngle, startAngle + sweepAngle, 120, color);
|
||||||
|
|
||||||
|
// Draw the label for the current slice
|
||||||
|
if (values[i] > 0)
|
||||||
|
{
|
||||||
|
char labelText[64] = { 0 };
|
||||||
|
if (showValues && showPercentages) snprintf(labelText, 64, "%.1f (%.0f%%)", values[i], (values[i]/totalValue)*100.0f);
|
||||||
|
else if (showValues) snprintf(labelText, 64, "%.1f", values[i]);
|
||||||
|
else if (showPercentages) snprintf(labelText, 64, "%.0f%%", (values[i]/totalValue)*100.0f);
|
||||||
|
else labelText[0] = '\0';
|
||||||
|
|
||||||
|
Vector2 textSize = MeasureTextEx(GetFontDefault(), labelText, 20, 1);
|
||||||
|
float labelRadius = radius*0.7f;
|
||||||
|
Vector2 labelPos = { center.x + cosf(midAngle*DEG2RAD)*labelRadius - textSize.x/2.0f,
|
||||||
|
center.y + sinf(midAngle*DEG2RAD)*labelRadius - textSize.y/2.0f };
|
||||||
|
DrawText(labelText, (int)labelPos.x, (int)labelPos.y, 20, WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw inner circle to create donut effect
|
||||||
|
// TODO: This is a hacky solution, better use DrawRing()
|
||||||
|
if (showDonut) DrawCircle(center.x, center.y, donutInnerRadius, RAYWHITE);
|
||||||
|
|
||||||
|
startAngle += sweepAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UI control panel
|
||||||
|
DrawRectangleRec(panelRect, Fade(LIGHTGRAY, 0.5f));
|
||||||
|
DrawRectangleLinesEx(panelRect, 1.0f, GRAY);
|
||||||
|
|
||||||
|
GuiSpinner((Rectangle){ panelPos.x + 95, (float)panelPos.y + 12, 125, 25 }, "Slices ", &sliceCount, 1, MAX_PIE_SLICES, false);
|
||||||
|
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 40, 20, 20 }, "Show Values", &showValues);
|
||||||
|
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 70, 20, 20 }, "Show Percentages", &showPercentages);
|
||||||
|
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)panelPos.y + 12 + 100, 20, 20 }, "Make Donut", &showDonut);
|
||||||
|
|
||||||
|
if (showDonut) GuiDisable();
|
||||||
|
GuiSliderBar((Rectangle){ panelPos.x + 80, (float)panelPos.y + 12 + 130, panelRect.width - 100, 30 },
|
||||||
|
"Inner Radius", NULL, &donutInnerRadius, 5.0f, radius - 10.0f);
|
||||||
|
GuiEnable();
|
||||||
|
|
||||||
|
GuiLine((Rectangle){ panelPos.x + 10, (float)panelPos.y + 12 + 170, panelRect.width - 20, 1 }, NULL);
|
||||||
|
|
||||||
|
// Scrollable area for slice editors
|
||||||
|
scrollPanelBounds = (Rectangle){
|
||||||
|
panelPos.x + panelMargin,
|
||||||
|
(float)panelPos.y + 12 + 190,
|
||||||
|
panelRect.width - panelMargin*2,
|
||||||
|
panelRect.y + panelRect.height - panelPos.y + 12 + 190 - panelMargin
|
||||||
|
};
|
||||||
|
int contentHeight = sliceCount*35;
|
||||||
|
|
||||||
|
GuiScrollPanel(scrollPanelBounds, NULL,
|
||||||
|
(Rectangle){ 0, 0, panelRect.width - 25, (float)contentHeight },
|
||||||
|
&scrollContentOffset, &view);
|
||||||
|
|
||||||
|
const float contentX = view.x + scrollContentOffset.x; // Left of content
|
||||||
|
const float contentY = view.y + scrollContentOffset.y; // Top of content
|
||||||
|
|
||||||
|
BeginScissorMode((int)view.x, (int)view.y, (int)view.width, (int)view.height);
|
||||||
|
|
||||||
|
for (int i = 0; i < sliceCount; i++)
|
||||||
|
{
|
||||||
|
const int rowY = (int)(contentY + 5 + i*35);
|
||||||
|
|
||||||
|
// Color indicator
|
||||||
|
Color color = ColorFromHSV((float)i/sliceCount*360.0f, 0.75f, 0.9f);
|
||||||
|
DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
|
||||||
|
|
||||||
|
// Label textbox
|
||||||
|
if (GuiTextBox((Rectangle){ contentX + 45, (float)rowY, 75, 30 }, labels[i], 32, editingLabel[i])) editingLabel[i] = !editingLabel[i];
|
||||||
|
|
||||||
|
GuiSliderBar((Rectangle){ contentX + 130, (float)rowY, 110, 30 }, NULL, NULL, &values[i], 0.0f, 1000.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndScissorMode();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_pie_chart.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
132
examples/shapes/shapes_recursive_tree.c
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - recursive tree
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★★☆] 3/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||||
|
*
|
||||||
|
* Example contributed by Jopestpe (@jopestpe)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Jopestpe (@jopestpe)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define RAYGUI_IMPLEMENTATION
|
||||||
|
#include "raygui.h" // Required for GUI controls
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef struct {
|
||||||
|
Vector2 start;
|
||||||
|
Vector2 end;
|
||||||
|
float angle;
|
||||||
|
float length;
|
||||||
|
} Branch;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - recursive tree");
|
||||||
|
|
||||||
|
Vector2 start = { (screenWidth/2.0f) - 125.0f, (float)screenHeight };
|
||||||
|
float angle = 40.0f;
|
||||||
|
float thick = 1.0f;
|
||||||
|
float treeDepth = 10.0f;
|
||||||
|
float branchDecay = 0.66f;
|
||||||
|
float length = 120.0f;
|
||||||
|
bool bezier = false;
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
float theta = angle*DEG2RAD;
|
||||||
|
int maxBranches = (int)(powf(2, floorf(treeDepth)));
|
||||||
|
Branch branches[1030] = { 0 };
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
Vector2 initialEnd = { start.x + length*sinf(0.0f), start.y - length*cosf(0.0f) };
|
||||||
|
branches[count++] = (Branch){start, initialEnd, 0.0f, length};
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
Branch branch = branches[i];
|
||||||
|
if (branch.length < 2) continue;
|
||||||
|
|
||||||
|
float nextLength = branch.length*branchDecay;
|
||||||
|
|
||||||
|
if (count < maxBranches && nextLength >= 2)
|
||||||
|
{
|
||||||
|
Vector2 branchStart = branch.end;
|
||||||
|
|
||||||
|
float angle1 = branch.angle + theta;
|
||||||
|
Vector2 branchEnd1 = { branchStart.x + nextLength*sinf(angle1), branchStart.y - nextLength*cosf(angle1) };
|
||||||
|
branches[count++] = (Branch){branchStart, branchEnd1, angle1, nextLength};
|
||||||
|
|
||||||
|
float angle2 = branch.angle - theta;
|
||||||
|
Vector2 branchEnd2 = { branchStart.x + nextLength*sinf(angle2), branchStart.y - nextLength*cosf(angle2) };
|
||||||
|
branches[count++] = (Branch){branchStart, branchEnd2, angle2, nextLength};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
Branch branch = branches[i];
|
||||||
|
if (branch.length >= 2)
|
||||||
|
{
|
||||||
|
if (bezier) DrawLineBezier(branch.start, branch.end, thick, RED);
|
||||||
|
else DrawLineEx(branch.start, branch.end, thick, RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
|
||||||
|
DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 });
|
||||||
|
|
||||||
|
// Draw GUI controls
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f", angle), &angle, 0, 180);
|
||||||
|
GuiSliderBar((Rectangle){ 640, 70, 120, 20 }, "Length", TextFormat("%.0f", length), &length, 12.0f, 240.0f);
|
||||||
|
GuiSliderBar((Rectangle){ 640, 100, 120, 20}, "Decay", TextFormat("%.2f", branchDecay), &branchDecay, 0.1f, 0.78f);
|
||||||
|
GuiSliderBar((Rectangle){ 640, 130, 120, 20 }, "Depth", TextFormat("%.0f", treeDepth), &treeDepth, 1.0f, 10.f);
|
||||||
|
GuiSliderBar((Rectangle){ 640, 160, 120, 20}, "Thick", TextFormat("%.0f", thick), &thick, 1, 8);
|
||||||
|
GuiCheckBox((Rectangle){ 640, 190, 20, 20 }, "Bezier", &bezier);
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_recursive_tree.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
284
examples/shapes/shapes_simple_particles.c
Normal file
|
|
@ -0,0 +1,284 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [shapes] example - simple particles
|
||||||
|
*
|
||||||
|
* Example complexity rating: [★★☆☆] 2/4
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||||
|
*
|
||||||
|
* Example contributed by Jordi Santonja (@JordSant)
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 Jordi Santonja (@JordSant)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <stdlib.h> // Required for: calloc(), free()
|
||||||
|
#include <math.h> // Required for: cosf(), sinf()
|
||||||
|
|
||||||
|
#define MAX_PARTICLES 3000 // Max number of particles
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Types and Structures Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
typedef enum ParticleType {
|
||||||
|
WATER = 0,
|
||||||
|
SMOKE,
|
||||||
|
FIRE
|
||||||
|
} ParticleType;
|
||||||
|
|
||||||
|
static const char particleTypeNames[3][10] = { "WATER", "SMOKE", "FIRE" };
|
||||||
|
|
||||||
|
typedef struct Particle {
|
||||||
|
ParticleType type; // Particle type (WATER, SMOKE, FIRE)
|
||||||
|
Vector2 position; // Particle position on screen
|
||||||
|
Vector2 velocity; // Particle current speed and direction
|
||||||
|
float radius; // Particle radius
|
||||||
|
Color color; // Particle color
|
||||||
|
|
||||||
|
float lifeTime; // Particle life time
|
||||||
|
bool alive; // Particle alive: inside screen and life time
|
||||||
|
} Particle;
|
||||||
|
|
||||||
|
typedef struct CircularBuffer {
|
||||||
|
int head; // Index for the next write
|
||||||
|
int tail; // Index for the next read
|
||||||
|
Particle *buffer; // Particle buffer array
|
||||||
|
} CircularBuffer;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Declaration
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
static void EmitParticle(CircularBuffer *circularBuffer, Vector2 emitterPosition, ParticleType type);
|
||||||
|
static Particle *AddToCircularBuffer(CircularBuffer *circularBuffer);
|
||||||
|
static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight);
|
||||||
|
static void UpdateCircularBuffer(CircularBuffer *circularBuffer);
|
||||||
|
static void DrawParticles(CircularBuffer *circularBuffer);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - simple particles");
|
||||||
|
|
||||||
|
// Definition of particles
|
||||||
|
Particle *particles = (Particle*)RL_CALLOC(MAX_PARTICLES, sizeof(Particle)); // Particle array
|
||||||
|
CircularBuffer circularBuffer = { 0, 0, particles };
|
||||||
|
|
||||||
|
// Particle emitter parameters
|
||||||
|
int emissionRate = -2; // Negative: on average every -X frames. Positive: particles per frame
|
||||||
|
ParticleType currentType = WATER;
|
||||||
|
Vector2 emitterPosition = { screenWidth/2.0f, screenHeight/2.0f };
|
||||||
|
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Emit new particles: when emissionRate is 1, emit every frame
|
||||||
|
if (emissionRate < 0)
|
||||||
|
{
|
||||||
|
if (rand()%(-emissionRate) == 0) EmitParticle(&circularBuffer, emitterPosition, currentType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= emissionRate; ++i) EmitParticle(&circularBuffer, emitterPosition, currentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the parameters of each particle
|
||||||
|
UpdateParticles(&circularBuffer, screenWidth, screenHeight);
|
||||||
|
|
||||||
|
// Remove dead particles from the circular buffer
|
||||||
|
UpdateCircularBuffer(&circularBuffer);
|
||||||
|
|
||||||
|
// Change Particle Emission Rate (UP/DOWN arrows)
|
||||||
|
if (IsKeyPressed(KEY_UP)) emissionRate++;
|
||||||
|
if (IsKeyPressed(KEY_DOWN)) emissionRate--;
|
||||||
|
|
||||||
|
// Change Particle Type (LEFT/RIGHT arrows)
|
||||||
|
if (IsKeyPressed(KEY_RIGHT)) (currentType == FIRE)? (currentType = WATER) : currentType++;
|
||||||
|
if (IsKeyPressed(KEY_LEFT)) (currentType == WATER)? (currentType = FIRE) : currentType--;
|
||||||
|
|
||||||
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) emitterPosition = GetMousePosition();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
// Call the function with a loop to draw all particles
|
||||||
|
DrawParticles(&circularBuffer);
|
||||||
|
|
||||||
|
// Draw UI and Instructions
|
||||||
|
DrawRectangle(5, 5, 315, 75, Fade(SKYBLUE, 0.5f));
|
||||||
|
DrawRectangleLines(5, 5, 315, 75, BLUE);
|
||||||
|
|
||||||
|
DrawText("CONTROLS:", 15, 15, 10, BLACK);
|
||||||
|
DrawText("UP/DOWN: Change Particle Emission Rate", 15, 35, 10, BLACK);
|
||||||
|
DrawText("LEFT/RIGHT: Change Particle Type (Water, Smoke, Fire)", 15, 55, 10, BLACK);
|
||||||
|
|
||||||
|
if (emissionRate < 0) DrawText(TextFormat("Particles every %d frames | Type: %s", -emissionRate, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY);
|
||||||
|
else DrawText(TextFormat("%d Particles per frame | Type: %s", emissionRate + 1, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY);
|
||||||
|
|
||||||
|
DrawFPS(screenWidth - 80, 10);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
RL_FREE(particles); // Free particles array data
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
static void EmitParticle(CircularBuffer *circularBuffer, Vector2 emitterPosition, ParticleType type)
|
||||||
|
{
|
||||||
|
Particle *newParticle = AddToCircularBuffer(circularBuffer);
|
||||||
|
|
||||||
|
// If buffer is full, newParticle is NULL
|
||||||
|
if (newParticle != NULL)
|
||||||
|
{
|
||||||
|
// Fill particle properties
|
||||||
|
newParticle->position = emitterPosition;
|
||||||
|
newParticle->alive = true;
|
||||||
|
newParticle->lifeTime = 0.0f;
|
||||||
|
newParticle->type = type;
|
||||||
|
float speed = (float)(rand()%10)/5.0f;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case WATER:
|
||||||
|
{
|
||||||
|
newParticle->radius = 5.0f;
|
||||||
|
newParticle->color = BLUE;
|
||||||
|
} break;
|
||||||
|
case SMOKE:
|
||||||
|
{
|
||||||
|
newParticle->radius = 7.0f;
|
||||||
|
newParticle->color = GRAY;
|
||||||
|
} break;
|
||||||
|
case FIRE:
|
||||||
|
{
|
||||||
|
newParticle->radius = 10.0f;
|
||||||
|
newParticle->color = YELLOW;
|
||||||
|
speed /= 10.0f;
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float direction = (float)(rand()%360);
|
||||||
|
newParticle->velocity = (Vector2){ speed*cosf(direction*DEG2RAD), speed*sinf(direction*DEG2RAD) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Particle *AddToCircularBuffer(CircularBuffer *circularBuffer)
|
||||||
|
{
|
||||||
|
Particle *particle = NULL;
|
||||||
|
|
||||||
|
// Check if buffer full
|
||||||
|
if (((circularBuffer->head + 1)%MAX_PARTICLES) != circularBuffer->tail)
|
||||||
|
{
|
||||||
|
// Add new particle to the head position and advance head
|
||||||
|
particle = &circularBuffer->buffer[circularBuffer->head];
|
||||||
|
circularBuffer->head = (circularBuffer->head + 1)%MAX_PARTICLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return particle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight)
|
||||||
|
{
|
||||||
|
for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES)
|
||||||
|
{
|
||||||
|
// Update particle life and positions
|
||||||
|
circularBuffer->buffer[i].lifeTime += 1.0f/60.0f; // 60 FPS -> 1/60 seconds per frame
|
||||||
|
|
||||||
|
switch (circularBuffer->buffer[i].type)
|
||||||
|
{
|
||||||
|
case WATER:
|
||||||
|
{
|
||||||
|
circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x;
|
||||||
|
circularBuffer->buffer[i].velocity.y += 0.2f; // Gravity
|
||||||
|
circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
|
||||||
|
} break;
|
||||||
|
case SMOKE:
|
||||||
|
{
|
||||||
|
circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x;
|
||||||
|
circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards
|
||||||
|
circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
|
||||||
|
circularBuffer->buffer[i].radius += 0.5f; // Increment radius: smoke expands
|
||||||
|
circularBuffer->buffer[i].color.a -= 4; // Decrement alpha: smoke fades
|
||||||
|
|
||||||
|
// If alpha transparent, particle dies
|
||||||
|
if (circularBuffer->buffer[i].color.a < 4) circularBuffer->buffer[i].alive = false;
|
||||||
|
} break;
|
||||||
|
case FIRE:
|
||||||
|
{
|
||||||
|
// Add a little horizontal oscillation to fire particles
|
||||||
|
circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x + cosf(circularBuffer->buffer[i].lifeTime*215.0f);
|
||||||
|
circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards
|
||||||
|
circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
|
||||||
|
circularBuffer->buffer[i].radius -= 0.15f; // Decrement radius: fire shrinks
|
||||||
|
circularBuffer->buffer[i].color.g -= 3; // Decrement green: fire turns reddish starting from yellow
|
||||||
|
|
||||||
|
// If radius too small, particle dies
|
||||||
|
if (circularBuffer->buffer[i].radius <= 0.02f) circularBuffer->buffer[i].alive = false;
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable particle when out of screen
|
||||||
|
Vector2 center = circularBuffer->buffer[i].position;
|
||||||
|
float radius = circularBuffer->buffer[i].radius;
|
||||||
|
|
||||||
|
if ((center.x < -radius) || (center.x > (screenWidth + radius)) ||
|
||||||
|
(center.y < -radius) || (center.y > (screenHeight + radius)))
|
||||||
|
{
|
||||||
|
circularBuffer->buffer[i].alive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateCircularBuffer(CircularBuffer *circularBuffer)
|
||||||
|
{
|
||||||
|
// Update circular buffer: advance tail over dead particles
|
||||||
|
while ((circularBuffer->tail != circularBuffer->head) && !circularBuffer->buffer[circularBuffer->tail].alive)
|
||||||
|
{
|
||||||
|
circularBuffer->tail = (circularBuffer->tail + 1)%MAX_PARTICLES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawParticles(CircularBuffer *circularBuffer)
|
||||||
|
{
|
||||||
|
for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES)
|
||||||
|
{
|
||||||
|
if (circularBuffer->buffer[i].alive)
|
||||||
|
{
|
||||||
|
DrawCircleV(circularBuffer->buffer[i].position,
|
||||||
|
circularBuffer->buffer[i].radius,
|
||||||
|
circularBuffer->buffer[i].color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
examples/shapes/shapes_simple_particles.png
Normal file
|
After Width: | Height: | Size: 32 KiB |