Compare commits
187 Commits
596d3bcb7e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 101502103a | |||
| 20dd4641c8 | |||
| fc843dc557 | |||
| 9103f6e055 | |||
| ced84333a9 | |||
| 05f42aa119 | |||
| a1e84caa8c | |||
| ddb827fb6f | |||
| 0a4583ca54 | |||
| 6a701b2679 | |||
| aa2884bd78 | |||
| f27f2d097f | |||
| e4baf682ab | |||
| 8516750975 | |||
| 3212becc91 | |||
| b9446863d7 | |||
| 13f9112d8c | |||
| f16fb065ea | |||
| 66392fe0ae | |||
| 720dd22491 | |||
| ca578b8b08 | |||
| 4b760091da | |||
| 6d562e5e87 | |||
| 7553e9d586 | |||
| 80ad96acc2 | |||
| 7a5e8aa3a5 | |||
| 1c94e94873 | |||
| 33adda1983 | |||
| f031b2f4f4 | |||
| 1c7240a01d | |||
| cf0d6fc664 | |||
| 615fc36eeb | |||
| cbe31759ab | |||
| d74556d35c | |||
| 8d246fdaff | |||
| a0fd5ab1d9 | |||
| 9a337f3b3b | |||
| 5025009860 | |||
| 6f5cabf60c | |||
| c96669e123 | |||
| 9c04b1de82 | |||
| b465b4e2ea | |||
| 2853b28d6d | |||
| 8fa5f1fe2c | |||
| 6f7cd3a9ab | |||
| ae438e804e | |||
| 2a566544d4 | |||
| 71a35f661e | |||
| 2d8e346945 | |||
| f3f02b3e17 | |||
| dad93abcf8 | |||
| 5e8118daf2 | |||
| bc2057345b | |||
| f2a900a60d | |||
| 3adfde42f7 | |||
| 91ac3cc707 | |||
| 19a1683641 | |||
| be6007be93 | |||
| efeccfef61 | |||
| 366300aafe | |||
| 215ad78d5b | |||
| 8115b7e922 | |||
| fd8830948e | |||
| f9899a7182 | |||
| 561cc27403 | |||
| 983efae3e4 | |||
| 95c4efd7a3 | |||
| 68befcc64f | |||
| b1f8cde329 | |||
| 78a81bf407 | |||
| 944567651c | |||
| 1bbc8682f4 | |||
| ed5da45203 | |||
| d3addad9a7 | |||
| d13314fe1c | |||
| 3ba186f2c1 | |||
| 4d9df337a7 | |||
| 4724f7cf1b | |||
| a568506265 | |||
| 6a048b7afe | |||
| ebce9fa97a | |||
| 78661a4ee0 | |||
| 18e1ec504f | |||
| 9f567e6ee4 | |||
| e273aaea1e | |||
| 1ac1309b24 | |||
| c991f9e89f | |||
| 8f3cabcf76 | |||
| 2b051afb29 | |||
| 3d9129e3b4 | |||
| 80ed6eadb8 | |||
| a7ce14ee95 | |||
| 47a8b554bc | |||
| fc8049a039 | |||
| bd36610f91 | |||
| 7e3d6cbfa8 | |||
| 17dc2bb474 | |||
| aaa893f668 | |||
| e1b9857b14 | |||
| cf5e84c3c4 | |||
| f1719480e0 | |||
| 84737a9fc1 | |||
| 727a90c5d1 | |||
| 6c3ef8d9b4 | |||
| 97707d7a6b | |||
| 12cce1766f | |||
| dddc94dc7a | |||
| c22b1d84d5 | |||
| 6820ff61f1 | |||
| 4ad9e09bb2 | |||
| 90af210712 | |||
| 0747e9b5c1 | |||
| c6f4c8e3e0 | |||
| c0179288ba | |||
| 8161475c28 | |||
| 30cd36a8a9 | |||
| ba65bd7f99 | |||
| 67f24b3b41 | |||
| 29173a4978 | |||
| 49868b356f | |||
| 8fcd99c8dd | |||
| 646e814baf | |||
| 5aee9f9d50 | |||
| 282c4b0eab | |||
| 1f7f9ab22b | |||
| ee3d65cbc9 | |||
| 82ad486e6b | |||
| d26435703f | |||
| 0b9f463e64 | |||
| bd21d74914 | |||
| 4cef89cf04 | |||
| 63fb407dc5 | |||
| 80e164fa04 | |||
| e1d5adb326 | |||
| 43bd2b1e18 | |||
| 313659d37d | |||
| a6976b1930 | |||
| 39e39216f6 | |||
| 5fdf178969 | |||
| e3738c1b17 | |||
| d56371ce85 | |||
| 265fa7833c | |||
| f21c1cc6ae | |||
| ec828071ef | |||
| 33cee1146c | |||
| 8081d2bd07 | |||
| 2453977d59 | |||
| e2233acdb0 | |||
| 3f92c396a0 | |||
| d5e8ee77b1 | |||
| f51204821a | |||
| a24e65d8e1 | |||
| f75682f5c9 | |||
| 57e22d5fa0 | |||
| 1b6303b900 | |||
| 83a167ca3f | |||
| 48496e2307 | |||
| e6ef99275a | |||
| c7c6aaf156 | |||
| 06958c91d0 | |||
| 46ca641ec5 | |||
| f3393b8fd8 | |||
| 8455f9d088 | |||
| 95d58ed988 | |||
| 5da90172ac | |||
| 6f4f4cc508 | |||
| e062e3835e | |||
| dcc9e96148 | |||
| 6993bc7337 | |||
| a4a6812d68 | |||
| 9efe127f5d | |||
| 4caba49658 | |||
| 86e00bde65 | |||
| 95a8977e33 | |||
| f531ee2d8f | |||
| b18f547d8f | |||
| be9a24e68c | |||
| bbba3d0802 | |||
| cde917c63c | |||
| a590126351 | |||
| 063986fdae | |||
| a235cd6a18 | |||
| ab463ac89b | |||
| 9fe3f7ca14 | |||
| d26b17f320 | |||
| 6756e9d3d7 | |||
| 06589d3350 |
7
.github/workflows/update_examples.yml
vendored
@ -29,8 +29,9 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Build and run rexm tool (requires GNU Makefile)
|
||||
# "rexm update" validates and updates all required examples in raylib and even raylib.com repos,
|
||||
# note that it calls examples/Makefile.Web internally, so it requires [make] tool available
|
||||
# "rexm validate" validates examples collection, looking for inconsistencies, it does not rebuild examples
|
||||
# "rexm update" validates and updates all examples with inconsistencies, pushing fixes to raylib and raylib.com repos
|
||||
# note that rexm calls examples/Makefile.Web internally, so it requires [make] tool available
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install -y libopengl0 libglu1-mesa libx11-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libgl1-mesa-dev libglu1-mesa-dev
|
||||
cd "${{ github.workspace }}/src"
|
||||
@ -47,7 +48,7 @@ jobs:
|
||||
export REXM_EXAMPLES_COLLECTION_FILE_PATH="${{ github.workspace }}/examples/examples_list.txt"
|
||||
export REXM_EXAMPLES_VS2022_SLN_FILE="${{ github.workspace }}/projects/VS2022/raylib.sln"
|
||||
export EMSDK_PATH="${{ github.workspace }}/emsdk-cache/emsdk-main"
|
||||
./rexm update
|
||||
./rexm validate
|
||||
shell: bash
|
||||
|
||||
- name: Commit changes to raylib repo (DISABLED)
|
||||
|
||||
9
.gitignore
vendored
@ -58,14 +58,23 @@ packages/
|
||||
*.h.pch
|
||||
./*.obj
|
||||
|
||||
# Ignore SDL libs for testing
|
||||
src/external/SDL2
|
||||
src/external/SDL3
|
||||
|
||||
# Emscripten
|
||||
emsdk
|
||||
|
||||
# Ignore wasm data in examples/
|
||||
examples/**/*
|
||||
!examples/**/*.*
|
||||
!examples/**/*/
|
||||
examples/**/*.exe
|
||||
examples/**/*.wasm
|
||||
examples/**/*.data
|
||||
examples/**/*.js
|
||||
examples/**/*.html
|
||||
examples/**/logs/*
|
||||
|
||||
# Ignore files build by xcode
|
||||
*.mode*v*
|
||||
|
||||
@ -29,6 +29,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
|
||||
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib |
|
||||
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
|
||||
| [raylib-elle](https://github.com/acquitelol/elle/blob/rewrite/std/raylib.le) | **5.5** | [Elle](https://github.com/acquitelol/elle) | GPL-3.0 |
|
||||
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |
|
||||
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
|
||||
| [raylib.f](https://github.com/cthulhuology/raylib.f) | **5.5** | [Forth](https://forth.com) | Zlib |
|
||||
@ -75,6 +76,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
||||
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib |
|
||||
| [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib |
|
||||
| [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** |
|
||||
| [ringraylib5](https://github.com/ring-lang/ring/tree/master/extensions/ringraylib5) | **5.0** | [Ring](https://ring-lang.github.io/) | **???** |
|
||||
| [racket-raylib](https://github.com/eutro/racket-raylib) | **5.5** | [Racket](https://racket-lang.org) | MIT/Apache-2.0 |
|
||||
| [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT |
|
||||
| [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT |
|
||||
|
||||
@ -565,7 +565,7 @@ Detailed changes:
|
||||
[rtext] ADDED: SetTextLineSpacing() to define line breaks text drawing spacing by @raysan5
|
||||
[rtext] RENAMED: LoadFont*() parameter names for consistency and coherence by @raysan5
|
||||
[rtext] REVIEWED: GetCodepointCount(), ignore unused return value of GetCodepointNext by @ashn-dot-dev
|
||||
[rtext] REVIEWED: TextFormat() warn user if buffer overflow occured (#3399) by @Murlocohol
|
||||
[rtext] REVIEWED: TextFormat() warn user if buffer overflow occurred (#3399) by @Murlocohol
|
||||
[rtext] REVIEWED: TextFormat(), added "..." for truncation (#3366) by @raysan5
|
||||
[rtext] REVIEWED: GetGlyphIndex() (#3000) by @raysan5
|
||||
[rtext] REVIEWED: GetCodepointNext() to return default value by @chocolate42
|
||||
|
||||
@ -6,7 +6,7 @@ if(EMSCRIPTEN)
|
||||
# When configuring web builds with "emcmake cmake -B build -S .", set PLATFORM to Web by default
|
||||
SET(PLATFORM Web CACHE STRING "Platform to build for.")
|
||||
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;RGFW" "Platform to build for.")
|
||||
|
||||
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?")
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@ while (!WindowShouldClose())
|
||||
|
||||
}
|
||||
|
||||
// Always use accumulators as `x++` instead of `++x`
|
||||
for (int i = 0; i < NUM_VALUES; i++) printf("%i", i);
|
||||
|
||||
// Be careful with the switch formatting!
|
||||
|
||||
18
SECURITY.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Most considerations of errors and defects can be handled using the project Issues and/or Discussions.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 6.0.x | :white_check_mark: |
|
||||
| < 5.5 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Discovered vulnerability can be directly reported using the project Issues and/or Discussions.
|
||||
|
||||
_TODO: Tell them where to go, how often they can expect to get an update on a
|
||||
reported vulnerability, what to expect if the vulnerability is accepted or
|
||||
declined, etc._
|
||||
16
build.zig
@ -106,9 +106,9 @@ const config_h_flags = outer: {
|
||||
if (std.mem.startsWith(u8, line, "//")) continue;
|
||||
if (std.mem.startsWith(u8, line, "#if")) continue;
|
||||
|
||||
var flag = std.mem.trimLeft(u8, line, " \t"); // Trim whitespace
|
||||
var flag = std.mem.trimStart(u8, line, " \t"); // Trim whitespace
|
||||
flag = flag["#define ".len - 1 ..]; // Remove #define
|
||||
flag = std.mem.trimLeft(u8, flag, " \t"); // Trim whitespace
|
||||
flag = std.mem.trimStart(u8, flag, " \t"); // Trim whitespace
|
||||
flag = flag[0 .. std.mem.indexOf(u8, flag, " ") orelse continue]; // Flag is only one word, so capture till space
|
||||
flag = "-D" ++ flag; // Prepend with -D
|
||||
|
||||
@ -155,9 +155,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
);
|
||||
}
|
||||
|
||||
// Sets a flag indiciating the use of a custom `config.h`
|
||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
||||
if (options.config.len > 0) {
|
||||
// Sets a flag indicating the use of a custom `config.h`
|
||||
try raylib_flags_arr.append(b.allocator, "-DEXTERNAL_CONFIG_FLAGS");
|
||||
// Splits a space-separated list of config flags into multiple flags
|
||||
//
|
||||
// Note: This means certain flags like `-x c++` won't be processed properly.
|
||||
@ -187,13 +187,13 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
try raylib_flags_arr.append(b.allocator, flag);
|
||||
}
|
||||
} else {
|
||||
// Set default config if no custome config got set
|
||||
// Set default config if no custom config got set
|
||||
try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
|
||||
}
|
||||
|
||||
// No GLFW required on PLATFORM_DRM
|
||||
if (options.platform != .drm) {
|
||||
raylib.addIncludePath(b.path("src/external/glfw/include"));
|
||||
raylib.root_module.addIncludePath(b.path("src/external/glfw/include"));
|
||||
}
|
||||
|
||||
var c_source_files: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 2);
|
||||
@ -224,7 +224,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), "");
|
||||
}
|
||||
|
||||
raylib.addIncludePath(b.path("src/platforms"));
|
||||
raylib.root_module.addIncludePath(b.path("src/platforms"));
|
||||
switch (target.result.os.tag) {
|
||||
.windows => {
|
||||
switch (options.platform) {
|
||||
@ -438,7 +438,7 @@ pub const Options = struct {
|
||||
|
||||
pub fn getOptions(b: *std.Build) Options {
|
||||
return .{
|
||||
.platform = b.option(PlatformBackend, "platform", "Choose the platform backedn for desktop target") orelse defaults.platform,
|
||||
.platform = b.option(PlatformBackend, "platform", "Choose the platform backend for desktop target") orelse defaults.platform,
|
||||
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
|
||||
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
|
||||
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
|
||||
|
||||
@ -141,6 +141,8 @@ elseif ("${PLATFORM}" MATCHES "SDL")
|
||||
add_compile_definitions(USING_SDL2_PACKAGE)
|
||||
endif()
|
||||
endif()
|
||||
elseif ("${PLATFORM}" MATCHES "RGFW")
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_RGFW")
|
||||
endif ()
|
||||
|
||||
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||
|
||||
@ -231,7 +231,7 @@ endif
|
||||
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
|
||||
# -Wno-unused-value ignore unused return values of some functions (i.e. fread())
|
||||
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
|
||||
CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result
|
||||
CFLAGS = -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wno-unused-result
|
||||
|
||||
ifeq ($(BUILD_MODE),DEBUG)
|
||||
CFLAGS += -g -D_DEBUG
|
||||
@ -531,7 +531,7 @@ CORE = \
|
||||
core/core_delta_time \
|
||||
core/core_directory_files \
|
||||
core/core_drop_files \
|
||||
core/core_high_dpi \
|
||||
core/core_highdpi_demo \
|
||||
core/core_highdpi_testbed \
|
||||
core/core_input_actions \
|
||||
core/core_input_gamepad \
|
||||
@ -560,6 +560,7 @@ CORE = \
|
||||
core/core_world_screen
|
||||
|
||||
SHAPES = \
|
||||
shapes/shapes_ball_physics \
|
||||
shapes/shapes_basic_shapes \
|
||||
shapes/shapes_bouncing_ball \
|
||||
shapes/shapes_bullet_hell \
|
||||
@ -582,11 +583,14 @@ SHAPES = \
|
||||
shapes/shapes_math_angle_rotation \
|
||||
shapes/shapes_math_sine_cosine \
|
||||
shapes/shapes_mouse_trail \
|
||||
shapes/shapes_penrose_tile \
|
||||
shapes/shapes_pie_chart \
|
||||
shapes/shapes_rectangle_advanced \
|
||||
shapes/shapes_rectangle_scaling \
|
||||
shapes/shapes_recursive_tree \
|
||||
shapes/shapes_ring_drawing \
|
||||
shapes/shapes_rlgl_color_wheel \
|
||||
shapes/shapes_rlgl_triangle \
|
||||
shapes/shapes_rounded_rectangle_drawing \
|
||||
shapes/shapes_simple_particles \
|
||||
shapes/shapes_splines_drawing \
|
||||
@ -599,6 +603,7 @@ TEXTURES = \
|
||||
textures/textures_background_scrolling \
|
||||
textures/textures_blend_modes \
|
||||
textures/textures_bunnymark \
|
||||
textures/textures_cellular_automata \
|
||||
textures/textures_fog_of_war \
|
||||
textures/textures_gif_player \
|
||||
textures/textures_image_channel \
|
||||
@ -615,11 +620,12 @@ TEXTURES = \
|
||||
textures/textures_particles_blending \
|
||||
textures/textures_polygon_drawing \
|
||||
textures/textures_raw_data \
|
||||
textures/textures_screen_buffer \
|
||||
textures/textures_sprite_animation \
|
||||
textures/textures_sprite_button \
|
||||
textures/textures_sprite_explosion \
|
||||
textures/textures_sprite_stacking \
|
||||
textures/textures_srcrec_dstrec \
|
||||
textures/textures_screen_buffer \
|
||||
textures/textures_textured_curve \
|
||||
textures/textures_tiled_drawing \
|
||||
textures/textures_to_image
|
||||
@ -636,6 +642,7 @@ TEXT = \
|
||||
text/text_input_box \
|
||||
text/text_rectangle_bounds \
|
||||
text/text_sprite_fonts \
|
||||
text/text_strings_management \
|
||||
text/text_unicode_emojis \
|
||||
text/text_unicode_ranges \
|
||||
text/text_words_alignment \
|
||||
@ -650,6 +657,7 @@ MODELS = \
|
||||
models/models_box_collisions \
|
||||
models/models_cubicmap_rendering \
|
||||
models/models_decals \
|
||||
models/models_directional_billboard \
|
||||
models/models_first_person_maze \
|
||||
models/models_geometric_shapes \
|
||||
models/models_heightmap_rendering \
|
||||
@ -680,6 +688,7 @@ SHADERS = \
|
||||
shaders/shaders_depth_writing \
|
||||
shaders/shaders_eratosthenes_sieve \
|
||||
shaders/shaders_fog_rendering \
|
||||
shaders/shaders_game_of_life \
|
||||
shaders/shaders_hot_reloading \
|
||||
shaders/shaders_hybrid_rendering \
|
||||
shaders/shaders_julia_set \
|
||||
@ -704,7 +713,6 @@ SHADERS = \
|
||||
shaders/shaders_vertex_displacement
|
||||
|
||||
AUDIO = \
|
||||
audio/audio_fft_spectrum_visualizer \
|
||||
audio/audio_mixed_processor \
|
||||
audio/audio_module_playing \
|
||||
audio/audio_music_stream \
|
||||
@ -712,6 +720,7 @@ AUDIO = \
|
||||
audio/audio_sound_loading \
|
||||
audio/audio_sound_multi \
|
||||
audio/audio_sound_positioning \
|
||||
audio/audio_spectrum_visualizer \
|
||||
audio/audio_stream_effects
|
||||
|
||||
OTHERS = \
|
||||
|
||||
@ -130,7 +130,7 @@ ifeq ($(ANDROID_ARCH),ARM)
|
||||
CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
|
||||
endif
|
||||
ifeq ($(ANDROID_ARCH),ARM64)
|
||||
CFLAGS = -std=c99 -target aarch64 -mfix-cortex-a53-835769
|
||||
CFLAGS = -std=c99 -mfix-cortex-a53-835769
|
||||
endif
|
||||
# Compilation functions attributes options
|
||||
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC
|
||||
|
||||
@ -519,7 +519,7 @@ CORE = \
|
||||
core/core_delta_time \
|
||||
core/core_directory_files \
|
||||
core/core_drop_files \
|
||||
core/core_high_dpi \
|
||||
core/core_highdpi_demo \
|
||||
core/core_highdpi_testbed \
|
||||
core/core_input_actions \
|
||||
core/core_input_gamepad \
|
||||
@ -548,6 +548,7 @@ CORE = \
|
||||
core/core_world_screen
|
||||
|
||||
SHAPES = \
|
||||
shapes/shapes_ball_physics \
|
||||
shapes/shapes_basic_shapes \
|
||||
shapes/shapes_bouncing_ball \
|
||||
shapes/shapes_bullet_hell \
|
||||
@ -570,11 +571,14 @@ SHAPES = \
|
||||
shapes/shapes_math_angle_rotation \
|
||||
shapes/shapes_math_sine_cosine \
|
||||
shapes/shapes_mouse_trail \
|
||||
shapes/shapes_penrose_tile \
|
||||
shapes/shapes_pie_chart \
|
||||
shapes/shapes_rectangle_advanced \
|
||||
shapes/shapes_rectangle_scaling \
|
||||
shapes/shapes_recursive_tree \
|
||||
shapes/shapes_ring_drawing \
|
||||
shapes/shapes_rlgl_color_wheel \
|
||||
shapes/shapes_rlgl_triangle \
|
||||
shapes/shapes_rounded_rectangle_drawing \
|
||||
shapes/shapes_simple_particles \
|
||||
shapes/shapes_splines_drawing \
|
||||
@ -587,6 +591,7 @@ TEXTURES = \
|
||||
textures/textures_background_scrolling \
|
||||
textures/textures_blend_modes \
|
||||
textures/textures_bunnymark \
|
||||
textures/textures_cellular_automata \
|
||||
textures/textures_fog_of_war \
|
||||
textures/textures_gif_player \
|
||||
textures/textures_image_channel \
|
||||
@ -603,11 +608,12 @@ TEXTURES = \
|
||||
textures/textures_particles_blending \
|
||||
textures/textures_polygon_drawing \
|
||||
textures/textures_raw_data \
|
||||
textures/textures_screen_buffer \
|
||||
textures/textures_sprite_animation \
|
||||
textures/textures_sprite_button \
|
||||
textures/textures_sprite_explosion \
|
||||
textures/textures_sprite_stacking \
|
||||
textures/textures_srcrec_dstrec \
|
||||
textures/textures_screen_buffer \
|
||||
textures/textures_textured_curve \
|
||||
textures/textures_tiled_drawing \
|
||||
textures/textures_to_image
|
||||
@ -624,6 +630,7 @@ TEXT = \
|
||||
text/text_input_box \
|
||||
text/text_rectangle_bounds \
|
||||
text/text_sprite_fonts \
|
||||
text/text_strings_management \
|
||||
text/text_unicode_emojis \
|
||||
text/text_unicode_ranges \
|
||||
text/text_words_alignment \
|
||||
@ -638,6 +645,7 @@ MODELS = \
|
||||
models/models_box_collisions \
|
||||
models/models_cubicmap_rendering \
|
||||
models/models_decals \
|
||||
models/models_directional_billboard \
|
||||
models/models_first_person_maze \
|
||||
models/models_geometric_shapes \
|
||||
models/models_heightmap_rendering \
|
||||
@ -668,6 +676,7 @@ SHADERS = \
|
||||
shaders/shaders_depth_writing \
|
||||
shaders/shaders_eratosthenes_sieve \
|
||||
shaders/shaders_fog_rendering \
|
||||
shaders/shaders_game_of_life \
|
||||
shaders/shaders_hot_reloading \
|
||||
shaders/shaders_hybrid_rendering \
|
||||
shaders/shaders_julia_set \
|
||||
@ -699,6 +708,7 @@ AUDIO = \
|
||||
audio/audio_sound_loading \
|
||||
audio/audio_sound_multi \
|
||||
audio/audio_sound_positioning \
|
||||
audio/audio_spectrum_visualizer \
|
||||
audio/audio_stream_effects
|
||||
|
||||
# Default target entry
|
||||
@ -773,7 +783,7 @@ core/core_directory_files: core/core_directory_files.c
|
||||
core/core_drop_files: core/core_drop_files.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_high_dpi: core/core_high_dpi.c
|
||||
core/core_highdpi_demo: core/core_highdpi_demo.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_highdpi_testbed: core/core_highdpi_testbed.c
|
||||
@ -859,6 +869,9 @@ core/core_world_screen: core/core_world_screen.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
# Compile SHAPES examples
|
||||
shapes/shapes_ball_physics: shapes/shapes_ball_physics.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_basic_shapes: shapes/shapes_basic_shapes.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
@ -925,6 +938,9 @@ shapes/shapes_math_sine_cosine: shapes/shapes_math_sine_cosine.c
|
||||
shapes/shapes_mouse_trail: shapes/shapes_mouse_trail.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_penrose_tile: shapes/shapes_penrose_tile.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)
|
||||
|
||||
@ -940,6 +956,12 @@ shapes/shapes_recursive_tree: shapes/shapes_recursive_tree.c
|
||||
shapes/shapes_ring_drawing: shapes/shapes_ring_drawing.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_rlgl_color_wheel: shapes/shapes_rlgl_color_wheel.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_rlgl_triangle: shapes/shapes_rlgl_triangle.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
shapes/shapes_rounded_rectangle_drawing: shapes/shapes_rounded_rectangle_drawing.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
@ -975,7 +997,10 @@ textures/textures_blend_modes: textures/textures_blend_modes.c
|
||||
|
||||
textures/textures_bunnymark: textures/textures_bunnymark.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/wabbit_alpha.png@resources/wabbit_alpha.png
|
||||
--preload-file textures/resources/raybunny.png@resources/raybunny.png
|
||||
|
||||
textures/textures_cellular_automata: textures/textures_cellular_automata.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
textures/textures_fog_of_war: textures/textures_fog_of_war.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
@ -1041,6 +1066,9 @@ textures/textures_raw_data: textures/textures_raw_data.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/fudesumi.raw@resources/fudesumi.raw
|
||||
|
||||
textures/textures_screen_buffer: textures/textures_screen_buffer.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
textures/textures_sprite_animation: textures/textures_sprite_animation.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/scarfy.png@resources/scarfy.png
|
||||
@ -1055,13 +1083,14 @@ textures/textures_sprite_explosion: textures/textures_sprite_explosion.c
|
||||
--preload-file textures/resources/boom.wav@resources/boom.wav \
|
||||
--preload-file textures/resources/explosion.png@resources/explosion.png
|
||||
|
||||
textures/textures_sprite_stacking: textures/textures_sprite_stacking.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/booth.png@resources/booth.png
|
||||
|
||||
textures/textures_srcrec_dstrec: textures/textures_srcrec_dstrec.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/scarfy.png@resources/scarfy.png
|
||||
|
||||
textures/textures_screen_buffer: textures/textures_screen_buffer.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
textures/textures_textured_curve: textures/textures_textured_curve.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/road.png@resources/road.png
|
||||
@ -1124,6 +1153,9 @@ text/text_sprite_fonts: text/text_sprite_fonts.c
|
||||
--preload-file text/resources/sprite_fonts/alpha_beta.png@resources/sprite_fonts/alpha_beta.png \
|
||||
--preload-file text/resources/sprite_fonts/jupiter_crash.png@resources/sprite_fonts/jupiter_crash.png
|
||||
|
||||
text/text_strings_management: text/text_strings_management.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
text/text_unicode_emojis: text/text_unicode_emojis.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file text/resources/dejavu.fnt@resources/dejavu.fnt \
|
||||
@ -1184,6 +1216,10 @@ models/models_decals: models/models_decals.c
|
||||
--preload-file models/resources/models/obj/character_diffuse.png@resources/models/obj/character_diffuse.png \
|
||||
--preload-file models/resources/raylib_logo.png@resources/raylib_logo.png
|
||||
|
||||
models/models_directional_billboard: models/models_directional_billboard.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file models/resources/skillbot.png@resources/skillbot.png
|
||||
|
||||
models/models_first_person_maze: models/models_first_person_maze.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file models/resources/cubicmap.png@resources/cubicmap.png \
|
||||
@ -1328,6 +1364,19 @@ shaders/shaders_fog_rendering: shaders/shaders_fog_rendering.c
|
||||
--preload-file shaders/resources/shaders/glsl100/lighting.vs@resources/shaders/glsl100/lighting.vs \
|
||||
--preload-file shaders/resources/shaders/glsl100/fog.fs@resources/shaders/glsl100/fog.fs
|
||||
|
||||
shaders/shaders_game_of_life: shaders/shaders_game_of_life.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file shaders/resources/shaders/glsl100/game_of_life.fs@resources/shaders/glsl100/game_of_life.fs \
|
||||
--preload-file shaders/resources/game_of_life/acorn.png@resources/game_of_life/acorn.png \
|
||||
--preload-file shaders/resources/game_of_life/breeder.png@resources/game_of_life/breeder.png \
|
||||
--preload-file shaders/resources/game_of_life/glider.png@resources/game_of_life/glider.png \
|
||||
--preload-file shaders/resources/game_of_life/glider_gun.png@resources/game_of_life/glider_gun.png \
|
||||
--preload-file shaders/resources/game_of_life/oscillators.png@resources/game_of_life/oscillators.png \
|
||||
--preload-file shaders/resources/game_of_life/puffer_train.png@resources/game_of_life/puffer_train.png \
|
||||
--preload-file shaders/resources/game_of_life/r_pentomino.png@resources/game_of_life/r_pentomino.png \
|
||||
--preload-file shaders/resources/game_of_life/spaceships.png@resources/game_of_life/spaceships.png \
|
||||
--preload-file shaders/resources/game_of_life/still_lifes.png@resources/game_of_life/still_lifes.png
|
||||
|
||||
shaders/shaders_hot_reloading: shaders/shaders_hot_reloading.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file shaders/resources/shaders/glsl100/reload.fs@resources/shaders/glsl100/reload.fs
|
||||
@ -1480,6 +1529,11 @@ audio/audio_sound_positioning: audio/audio_sound_positioning.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file audio/resources/coin.wav@resources/coin.wav
|
||||
|
||||
audio/audio_spectrum_visualizer: audio/audio_spectrum_visualizer.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file audio/resources/shaders/glsl100/fft.fs@resources/shaders/glsl100/fft.fs \
|
||||
--preload-file audio/resources/country.mp3@resources/country.mp3
|
||||
|
||||
audio/audio_stream_effects: audio/audio_stream_effects.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file audio/resources/country.mp3@resources/country.mp3
|
||||
|
||||
@ -17,7 +17,7 @@ You may find it easier to use than other toolchains, especially when it comes to
|
||||
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
|
||||
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
|
||||
|
||||
## EXAMPLES COLLECTION [TOTAL: 195]
|
||||
## EXAMPLES COLLECTION [TOTAL: 205]
|
||||
|
||||
### category: core [47]
|
||||
|
||||
@ -43,7 +43,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
||||
| [core_3d_camera_free](core/core_3d_camera_free.c) | <img src="core/core_3d_camera_free.png" alt="core_3d_camera_free" width="80"> | ⭐☆☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | <img src="core/core_3d_camera_first_person.png" alt="core_3d_camera_first_person" width="80"> | ⭐⭐☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_3d_camera_split_screen](core/core_3d_camera_split_screen.c) | <img src="core/core_3d_camera_split_screen.png" alt="core_3d_camera_split_screen" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
| [core_3d_camera_fps](core/core_3d_camera_fps.c) | <img src="core/core_3d_camera_fps.png" alt="core_3d_camera_fps" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) |
|
||||
| [core_3d_camera_fps](core/core_3d_camera_fps.c) | <img src="core/core_3d_camera_fps.png" alt="core_3d_camera_fps" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
||||
| [core_3d_picking](core/core_3d_picking.c) | <img src="core/core_3d_picking.png" alt="core_3d_picking" width="80"> | ⭐⭐☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_world_screen](core/core_world_screen.c) | <img src="core/core_world_screen.png" alt="core_world_screen" width="80"> | ⭐⭐☆☆ | 1.3 | 1.4 | [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) |
|
||||
@ -61,10 +61,10 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
||||
| [core_smooth_pixelperfect](core/core_smooth_pixelperfect.c) | <img src="core/core_smooth_pixelperfect.png" alt="core_smooth_pixelperfect" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Giancamillo Alessandroni](https://github.com/NotManyIdeasDev) |
|
||||
| [core_random_sequence](core/core_random_sequence.c) | <img src="core/core_random_sequence.png" alt="core_random_sequence" width="80"> | ⭐☆☆☆ | 5.0 | 5.0 | [Dalton Overmyer](https://github.com/REDl3east) |
|
||||
| [core_automation_events](core/core_automation_events.c) | <img src="core/core_automation_events.png" alt="core_automation_events" width="80"> | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [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_highdpi_demo](core/core_highdpi_demo.c) | <img src="core/core_highdpi_demo.png" alt="core_highdpi_demo" 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_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_viewport_scaling](core/core_viewport_scaling.c) | <img src="core/core_viewport_scaling.png" alt="core_viewport_scaling" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) |
|
||||
| [core_viewport_scaling](core/core_viewport_scaling.c) | <img src="core/core_viewport_scaling.png" alt="core_viewport_scaling" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
||||
| [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) |
|
||||
@ -73,7 +73,7 @@ Examples using raylib [core](../src/rcore.c) module platform functionality: wind
|
||||
| [core_text_file_loading](core/core_text_file_loading.c) | <img src="core/core_text_file_loading.png" alt="core_text_file_loading" width="80"> | ⭐☆☆☆ | 5.5 | 5.6 | [Aanjishnu Bhattacharyya](https://github.com/NimComPoo-04) |
|
||||
| [core_compute_hash](core/core_compute_hash.c) | <img src="core/core_compute_hash.png" alt="core_compute_hash" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
|
||||
### category: shapes [34]
|
||||
### category: shapes [38]
|
||||
|
||||
Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module.
|
||||
|
||||
@ -113,8 +113,12 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes](
|
||||
| [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) |
|
||||
| [shapes_lines_drawing](shapes/shapes_lines_drawing.c) | <img src="shapes/shapes_lines_drawing.png" alt="shapes_lines_drawing" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_math_angle_rotation](shapes/shapes_math_angle_rotation.c) | <img src="shapes/shapes_math_angle_rotation.png" alt="shapes_math_angle_rotation" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6 | [Kris](https://github.com/krispy-snacc) |
|
||||
| [shapes_rlgl_color_wheel](shapes/shapes_rlgl_color_wheel.c) | <img src="shapes/shapes_rlgl_color_wheel.png" alt="shapes_rlgl_color_wheel" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_rlgl_triangle](shapes/shapes_rlgl_triangle.c) | <img src="shapes/shapes_rlgl_triangle.png" alt="shapes_rlgl_triangle" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [Robin](https://github.com/RobinsAviary) |
|
||||
| [shapes_ball_physics](shapes/shapes_ball_physics.c) | <img src="shapes/shapes_ball_physics.png" alt="shapes_ball_physics" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
| [shapes_penrose_tile](shapes/shapes_penrose_tile.c) | <img src="shapes/shapes_penrose_tile.png" alt="shapes_penrose_tile" width="80"> | ⭐⭐⭐⭐️ | 5.5 | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
|
||||
### category: textures [27]
|
||||
### category: textures [29]
|
||||
|
||||
Examples using raylib textures functionality, including image/textures loading/generation and drawing, provided by raylib [textures](../src/rtextures.c) module.
|
||||
|
||||
@ -145,10 +149,12 @@ Examples using raylib textures functionality, including image/textures loading/g
|
||||
| [textures_image_kernel](textures/textures_image_kernel.c) | <img src="textures/textures_image_kernel.png" alt="textures_image_kernel" width="80"> | ⭐⭐⭐⭐️ | 1.3 | 1.3 | [Karim Salem](https://github.com/kimo-s) |
|
||||
| [textures_image_channel](textures/textures_image_channel.c) | <img src="textures/textures_image_channel.png" alt="textures_image_channel" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Bruno Cabral](https://github.com/brccabral) |
|
||||
| [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_screen_buffer](textures/textures_screen_buffer.c) | <img src="textures/textures_screen_buffer.png" alt="textures_screen_buffer" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) |
|
||||
| [textures_screen_buffer](textures/textures_screen_buffer.c) | <img src="textures/textures_screen_buffer.png" alt="textures_screen_buffer" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Agnis Aldiņš](https://github.com/nezvers) |
|
||||
| [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_sprite_stacking](textures/textures_sprite_stacking.c) | <img src="textures/textures_sprite_stacking.png" alt="textures_sprite_stacking" width="80"> | ⭐⭐☆☆ | 5.6-dev | 6.0 | [Robin](https://github.com/RobinsAviary) |
|
||||
| [textures_cellular_automata](textures/textures_cellular_automata.c) | <img src="textures/textures_cellular_automata.png" alt="textures_cellular_automata" width="80"> | ⭐⭐☆☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
|
||||
### category: text [15]
|
||||
### category: text [16]
|
||||
|
||||
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
|
||||
|
||||
@ -169,8 +175,9 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
||||
| [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_words_alignment](text/text_words_alignment.c) | <img src="text/text_words_alignment.png" alt="text_words_alignment" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [text_strings_management](text/text_strings_management.c) | <img src="text/text_strings_management.png" alt="text_strings_management" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [David Buzatto](https://github.com/davidbuzatto) |
|
||||
|
||||
### category: models [26]
|
||||
### category: models [27]
|
||||
|
||||
Examples using raylib models functionality, including models loading/generation and drawing, provided by raylib [models](../src/rmodels.c) module.
|
||||
|
||||
@ -202,8 +209,9 @@ Examples using raylib models functionality, including models loading/generation
|
||||
| [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) |
|
||||
| [models_decals](models/models_decals.c) | <img src="models/models_decals.png" alt="models_decals" width="80"> | ⭐⭐⭐⭐️ | 5.6-dev | 5.6-dev | [JP Mortiboys](https://github.com/themushroompirates) |
|
||||
| [models_directional_billboard](models/models_directional_billboard.c) | <img src="models/models_directional_billboard.png" alt="models_directional_billboard" width="80"> | ⭐⭐☆☆ | 5.6-dev | 5.6 | [Robin](https://github.com/RobinsAviary) |
|
||||
|
||||
### category: shaders [32]
|
||||
### category: shaders [33]
|
||||
|
||||
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.
|
||||
|
||||
@ -241,8 +249,9 @@ 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_rounded_rectangle](shaders/shaders_rounded_rectangle.c) | <img src="shaders/shaders_rounded_rectangle.png" alt="shaders_rounded_rectangle" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Anstro Pleuton](https://github.com/anstropleuton) |
|
||||
| [shaders_depth_rendering](shaders/shaders_depth_rendering.c) | <img src="shaders/shaders_depth_rendering.png" alt="shaders_depth_rendering" width="80"> | ⭐⭐⭐☆ | 5.6-dev | 5.6-dev | [Luís Almeida](https://github.com/luis605) |
|
||||
| [shaders_game_of_life](shaders/shaders_game_of_life.c) | <img src="shaders/shaders_game_of_life.png" alt="shaders_game_of_life" width="80"> | ⭐⭐⭐☆ | 5.6 | 5.6 | [Jordi Santonja](https://github.com/JordSant) |
|
||||
|
||||
### category: audio [8]
|
||||
### category: audio [9]
|
||||
|
||||
Examples using raylib audio functionality, including sound/music loading and playing. This functionality is provided by raylib [raudio](../src/raudio.c) module. Note this module can be used standalone independently of raylib.
|
||||
|
||||
@ -256,6 +265,7 @@ Examples using raylib audio functionality, including sound/music loading and pla
|
||||
| [audio_stream_effects](audio/audio_stream_effects.c) | <img src="audio/audio_stream_effects.png" alt="audio_stream_effects" width="80"> | ⭐⭐⭐⭐️ | 4.2 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [audio_sound_multi](audio/audio_sound_multi.c) | <img src="audio/audio_sound_multi.png" alt="audio_sound_multi" width="80"> | ⭐⭐☆☆ | 5.0 | 5.0 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
| [audio_sound_positioning](audio/audio_sound_positioning.c) | <img src="audio/audio_sound_positioning.png" alt="audio_sound_positioning" width="80"> | ⭐⭐☆☆ | 5.5 | 5.5 | [Le Juez Victor](https://github.com/Bigfoot71) |
|
||||
| [audio_spectrum_visualizer](audio/audio_spectrum_visualizer.c) | <img src="audio/audio_spectrum_visualizer.png" alt="audio_spectrum_visualizer" width="80"> | ⭐⭐⭐☆ | 6.0 | 5.6-dev | [IANN](https://github.com/meisei4) |
|
||||
|
||||
### category: others [6]
|
||||
|
||||
@ -271,4 +281,4 @@ Examples showing raylib misc functionality that does not fit in other categories
|
||||
| [web_basic_window](others/web_basic_window.c) | <img src="others/web_basic_window.png" alt="web_basic_window" width="80"> | ⭐☆☆☆ | 5.6-dev | 5.6-dev | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
|
||||
Some example missing? As always, contributions are welcome, feel free to send new examples!
|
||||
Here is an[examples template](examples_template.c) with instructions to start with!
|
||||
Here is an [examples template](examples_template.c) with instructions to start with!
|
||||
|
||||
@ -36,6 +36,12 @@ int main(void)
|
||||
float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f]
|
||||
bool pause = false; // Music playing paused
|
||||
|
||||
float pan = 0.0f; // Default audio pan center [-1.0f..1.0f]
|
||||
SetMusicPan(music, pan);
|
||||
|
||||
float volume = 0.8f; // Default audio volume [0.0f..1.0f]
|
||||
SetMusicVolume(music, volume);
|
||||
|
||||
SetTargetFPS(30); // Set our game to run at 30 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -62,6 +68,34 @@ int main(void)
|
||||
else ResumeMusicStream(music);
|
||||
}
|
||||
|
||||
// Set audio pan
|
||||
if (IsKeyDown(KEY_LEFT))
|
||||
{
|
||||
pan -= 0.05f;
|
||||
if (pan < -1.0f) pan = -1.0f;
|
||||
SetMusicPan(music, pan);
|
||||
}
|
||||
else if (IsKeyDown(KEY_RIGHT))
|
||||
{
|
||||
pan += 0.05f;
|
||||
if (pan > 1.0f) pan = 1.0f;
|
||||
SetMusicPan(music, pan);
|
||||
}
|
||||
|
||||
// Set audio volume
|
||||
if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
volume -= 0.05f;
|
||||
if (volume < 0.0f) volume = 0.0f;
|
||||
SetMusicVolume(music, volume);
|
||||
}
|
||||
else if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
volume += 0.05f;
|
||||
if (volume > 1.0f) volume = 1.0f;
|
||||
SetMusicVolume(music, volume);
|
||||
}
|
||||
|
||||
// Get normalized time played for current music stream
|
||||
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music);
|
||||
|
||||
@ -76,6 +110,11 @@ int main(void)
|
||||
|
||||
DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
|
||||
|
||||
DrawText("LEFT-RIGHT for PAN CONTROL", 320, 74, 10, DARKBLUE);
|
||||
DrawRectangle(300, 100, 200, 12, LIGHTGRAY);
|
||||
DrawRectangleLines(300, 100, 200, 12, GRAY);
|
||||
DrawRectangle(300 + (pan + 1.0)/2.0f*200 - 5, 92, 10, 28, DARKGRAY);
|
||||
|
||||
DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
|
||||
DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON);
|
||||
DrawRectangleLines(200, 200, 400, 12, GRAY);
|
||||
@ -83,6 +122,11 @@ int main(void)
|
||||
DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY);
|
||||
DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY);
|
||||
|
||||
DrawText("UP-DOWN for VOLUME CONTROL", 320, 334, 10, DARKGREEN);
|
||||
DrawRectangle(300, 360, 200, 12, LIGHTGRAY);
|
||||
DrawRectangleLines(300, 360, 200, 12, GRAY);
|
||||
DrawRectangle(300 + volume*200 - 5, 352, 10, 28, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ int main(void)
|
||||
memcpy(writeBuf + writeCursor, data + readCursor, writeLength*sizeof(short));
|
||||
|
||||
// Update cursors and loop audio
|
||||
readCursor = (readCursor + writeLength) % waveLength;
|
||||
readCursor = (readCursor + writeLength)%waveLength;
|
||||
|
||||
writeCursor += writeLength;
|
||||
}
|
||||
|
||||
@ -69,6 +69,7 @@ int main(void)
|
||||
};
|
||||
|
||||
SetSoundPosition(camera, sound, spherePos, 20.0f);
|
||||
|
||||
if (!IsSoundPlaying(sound)) PlaySound(sound);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -94,6 +95,8 @@ int main(void)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - fft spectrum visualizer
|
||||
* raylib [audio] example - spectrum visualizer
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 6.0
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 5.6-dev
|
||||
*
|
||||
* Inspired by Inigo Quilez's https://www.shadertoy.com/
|
||||
* Resources/specification: https://gist.github.com/soulthreads/2efe50da4be1fb5f7ab60ff14ca434b8
|
||||
@ -19,11 +19,19 @@
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
#define MONO 1
|
||||
#define SAMPLE_RATE 44100
|
||||
#define SAMPLE_RATE_F 44100.0f
|
||||
@ -70,14 +78,15 @@ int main(void)
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - fft spectrum visualizer");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - spectrum visualizer");
|
||||
|
||||
Image fftImage = GenImageColor(BUFFER_SIZE, TEXTURE_HEIGHT, WHITE);
|
||||
Texture2D fftTexture = LoadTextureFromImage(fftImage);
|
||||
RenderTexture2D bufferA = LoadRenderTexture(screenWidth, screenHeight);
|
||||
Vector2 iResolution = { (float)screenWidth, (float)screenHeight };
|
||||
|
||||
Shader shader = LoadShader(NULL, "resources/fft.glsl");
|
||||
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/fft.fs", GLSL_VERSION));
|
||||
|
||||
int iResolutionLocation = GetShaderLocation(shader, "iResolution");
|
||||
int iChannel0Location = GetShaderLocation(shader, "iChannel0");
|
||||
SetShaderValue(shader, iResolutionLocation, &iResolution, SHADER_UNIFORM_VEC2);
|
||||
@ -86,6 +95,7 @@ int main(void)
|
||||
InitAudioDevice();
|
||||
SetAudioStreamBufferSizeDefault(AUDIO_STREAM_RING_BUFFER_SIZE);
|
||||
|
||||
// WARNING: Memory out-of-bounds on PLATFORM_WEB
|
||||
Wave wav = LoadWave("resources/country.mp3");
|
||||
WaveFormat(&wav, SAMPLE_RATE, PER_SAMPLE_BIT_DEPTH, MONO);
|
||||
|
||||
@ -95,10 +105,10 @@ int main(void)
|
||||
int fftHistoryLen = (int)ceilf(FFT_HISTORICAL_SMOOTHING_DUR/WINDOW_TIME) + 1;
|
||||
|
||||
FFTData fft = {
|
||||
.spectrum = malloc(sizeof(FFTComplex)*FFT_WINDOW_SIZE),
|
||||
.workBuffer = malloc(sizeof(FFTComplex)*FFT_WINDOW_SIZE),
|
||||
.prevMagnitudes = calloc(BUFFER_SIZE, sizeof(float)),
|
||||
.fftHistory = calloc(fftHistoryLen, sizeof(float[BUFFER_SIZE])),
|
||||
.spectrum = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE),
|
||||
.workBuffer = RL_CALLOC(sizeof(FFTComplex), FFT_WINDOW_SIZE),
|
||||
.prevMagnitudes = RL_CALLOC(BUFFER_SIZE, sizeof(float)),
|
||||
.fftHistory = RL_CALLOC(fftHistoryLen, sizeof(float[BUFFER_SIZE])),
|
||||
.fftHistoryLen = fftHistoryLen,
|
||||
.historyPos = 0,
|
||||
.lastFftTime = 0.0,
|
||||
@ -127,33 +137,32 @@ int main(void)
|
||||
int right = (wav.channels == 2)? wavPCM16[wavCursor*2 + 1] : left;
|
||||
chunkSamples[i] = (short)((left + right)/2);
|
||||
|
||||
if (++wavCursor >= wav.frameCount)
|
||||
wavCursor = 0;
|
||||
|
||||
if (++wavCursor >= wav.frameCount) wavCursor = 0;
|
||||
}
|
||||
|
||||
UpdateAudioStream(audioStream, chunkSamples, AUDIO_STREAM_RING_BUFFER_SIZE);
|
||||
|
||||
for (int i = 0; i < FFT_WINDOW_SIZE; i++)
|
||||
audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f;
|
||||
for (int i = 0; i < FFT_WINDOW_SIZE; i++) audioSamples[i] = (chunkSamples[i*2] + chunkSamples[i*2 + 1])*0.5f/32767.0f;
|
||||
}
|
||||
|
||||
CaptureFrame(&fft, audioSamples);
|
||||
RenderFrame(&fft, &fftImage);
|
||||
UpdateTexture(fftTexture, fftImage.data);
|
||||
//------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginShaderMode(shader);
|
||||
SetShaderValueTexture(shader, iChannel0Location, fftTexture);
|
||||
DrawTextureRec(bufferA.texture,
|
||||
(Rectangle){ 0, 0, (float)screenWidth, (float)-screenHeight },
|
||||
(Vector2){ 0, 0 },
|
||||
WHITE);
|
||||
(Vector2){ 0, 0 }, WHITE);
|
||||
EndShaderMode();
|
||||
|
||||
EndDrawing();
|
||||
//------------------------------------------------------------------------------
|
||||
}
|
||||
@ -168,10 +177,10 @@ int main(void)
|
||||
UnloadWave(wav);
|
||||
CloseAudioDevice();
|
||||
|
||||
free(fft.spectrum);
|
||||
free(fft.workBuffer);
|
||||
free(fft.prevMagnitudes);
|
||||
free(fft.fftHistory);
|
||||
RL_FREE(fft.spectrum);
|
||||
RL_FREE(fft.workBuffer);
|
||||
RL_FREE(fft.prevMagnitudes);
|
||||
RL_FREE(fft.fftHistory);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -260,7 +269,7 @@ static void CaptureFrame(FFTData *fftData, const float *audioSamples)
|
||||
|
||||
fftData->lastFftTime = GetTime();
|
||||
memcpy(fftData->fftHistory[fftData->historyPos], smoothedSpectrum, sizeof(smoothedSpectrum));
|
||||
fftData->historyPos = (fftData->historyPos + 1) % fftData->fftHistoryLen;
|
||||
fftData->historyPos = (fftData->historyPos + 1)%fftData->fftHistoryLen;
|
||||
}
|
||||
|
||||
static void RenderFrame(const FFTData *fftData, Image *fftImage)
|
||||
@ -268,12 +277,9 @@ static void RenderFrame(const FFTData *fftData, Image *fftImage)
|
||||
double framesSinceTapback = floor(fftData->tapbackPos/WINDOW_TIME);
|
||||
framesSinceTapback = Clamp(framesSinceTapback, 0.0, fftData->fftHistoryLen - 1);
|
||||
|
||||
int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback) % fftData->fftHistoryLen;
|
||||
if (historyPosition < 0)
|
||||
historyPosition += fftData->fftHistoryLen;
|
||||
int historyPosition = (fftData->historyPos - 1 - (int)framesSinceTapback)%fftData->fftHistoryLen;
|
||||
if (historyPosition < 0) historyPosition += fftData->fftHistoryLen;
|
||||
|
||||
const float *amplitude = fftData->fftHistory[historyPosition];
|
||||
for (int bin = 0; bin < BUFFER_SIZE; bin++) {
|
||||
ImageDrawPixel(fftImage, bin, FFT_ROW, ColorFromNormalized((Vector4){ amplitude[bin], UNUSED_CHANNEL, UNUSED_CHANNEL, UNUSED_CHANNEL }));
|
||||
}
|
||||
for (int bin = 0; bin < BUFFER_SIZE; bin++) ImageDrawPixel(fftImage, bin, FFT_ROW, ColorFromNormalized((Vector4){ amplitude[bin], UNUSED_CHANNEL, UNUSED_CHANNEL, UNUSED_CHANNEL }));
|
||||
}
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@ -1,32 +0,0 @@
|
||||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
uniform vec2 iResolution;
|
||||
uniform sampler2D iChannel0;
|
||||
|
||||
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
const float FFT_ROW = 0.0;
|
||||
const float NUM_OF_BINS = 512.0;
|
||||
|
||||
void main() {
|
||||
vec2 fragCoord = fragTexCoord*iResolution;
|
||||
float cell_width = iResolution.x/NUM_OF_BINS;
|
||||
float bin_index = floor(fragCoord.x/cell_width);
|
||||
float local_x = mod(fragCoord.x, cell_width);
|
||||
float bar_width = cell_width - 1.0;
|
||||
vec4 color = BLACK;
|
||||
if (local_x <= bar_width) {
|
||||
float sample_x = (bin_index + 0.5)/NUM_OF_BINS;
|
||||
vec2 sample_coord = vec2(sample_x, FFT_ROW);
|
||||
float amplitude = texture(iChannel0, sample_coord).r; // only filled the red channel, all channels left open for alternative use
|
||||
if (fragTexCoord.y < amplitude) {
|
||||
color = WHITE;
|
||||
}
|
||||
}
|
||||
finalColor = color;
|
||||
}
|
||||
37
examples/audio/resources/shaders/glsl100/fft.fs
Normal file
@ -0,0 +1,37 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform vec2 iResolution;
|
||||
uniform sampler2D iChannel0;
|
||||
|
||||
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
const float FFT_ROW = 0.0;
|
||||
const float NUM_OF_BINS = 512.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 fragCoord = fragTexCoord*iResolution;
|
||||
float cellWidth = iResolution.x/NUM_OF_BINS;
|
||||
float binIndex = floor(fragCoord.x/cellWidth);
|
||||
float localX = mod(fragCoord.x, cellWidth);
|
||||
float barWidth = cellWidth - 1.0;
|
||||
vec4 color = WHITE;
|
||||
|
||||
if (localX <= barWidth)
|
||||
{
|
||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||
|
||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||
}
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
35
examples/audio/resources/shaders/glsl120/fft.fs
Normal file
@ -0,0 +1,35 @@
|
||||
#version 120
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform vec2 iResolution;
|
||||
uniform sampler2D iChannel0;
|
||||
|
||||
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
const float FFT_ROW = 0.0;
|
||||
const float NUM_OF_BINS = 512.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 fragCoord = fragTexCoord*iResolution;
|
||||
float cellWidth = iResolution.x/NUM_OF_BINS;
|
||||
float binIndex = floor(fragCoord.x/cellWidth);
|
||||
float localX = mod(fragCoord.x, cellWidth);
|
||||
float barWidth = cellWidth - 1.0;
|
||||
vec4 color = WHITE;
|
||||
|
||||
if (localX <= barWidth)
|
||||
{
|
||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||
float amplitude = texture2D(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||
|
||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||
}
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
35
examples/audio/resources/shaders/glsl330/fft.fs
Normal file
@ -0,0 +1,35 @@
|
||||
#version 330
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 finalColor;
|
||||
|
||||
uniform vec2 iResolution;
|
||||
uniform sampler2D iChannel0;
|
||||
|
||||
const vec4 BLACK = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
const vec4 WHITE = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
const float FFT_ROW = 0.0;
|
||||
const float NUM_OF_BINS = 512.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 fragCoord = fragTexCoord*iResolution;
|
||||
float cellWidth = iResolution.x/NUM_OF_BINS;
|
||||
float binIndex = floor(fragCoord.x/cellWidth);
|
||||
float localX = mod(fragCoord.x, cellWidth);
|
||||
float barWidth = cellWidth - 1.0;
|
||||
vec4 color = WHITE;
|
||||
|
||||
if (localX <= barWidth)
|
||||
{
|
||||
float sampleX = (binIndex + 0.5)/NUM_OF_BINS;
|
||||
vec2 sampleCoord = vec2(sampleX, FFT_ROW);
|
||||
float amplitude = texture(iChannel0, sampleCoord).r; // Only filled the red channel, all channels left open for alternative use
|
||||
|
||||
if (fragTexCoord.y < amplitude) color = BLACK;
|
||||
}
|
||||
|
||||
finalColor = color;
|
||||
}
|
||||
@ -125,8 +125,8 @@ int main(void)
|
||||
DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines( 10, 10, 250, 113, BLUE);
|
||||
|
||||
DrawText("Free 2d camera controls:", 20, 20, 10, BLACK);
|
||||
DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY);
|
||||
DrawText("Free 2D camera controls:", 20, 20, 10, BLACK);
|
||||
DrawText("- Right/Left to move player", 40, 40, 10, DARKGRAY);
|
||||
DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY);
|
||||
DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY);
|
||||
DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY);
|
||||
|
||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 8.3 KiB |
@ -23,7 +23,7 @@
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main ()
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
@ -35,9 +35,9 @@ int main ()
|
||||
Camera2D camera = { 0 };
|
||||
camera.zoom = 1.0f;
|
||||
|
||||
int zoomMode = 0; // 0-Mouse Wheel, 1-Mouse Move
|
||||
int zoomMode = 0; // 0-Mouse Wheel, 1-Mouse Move
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
@ -93,6 +93,7 @@ int main ()
|
||||
// under the cursor to the screen space point under the cursor at any zoom
|
||||
camera.target = mouseWorldPos;
|
||||
}
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
|
||||
{
|
||||
// Zoom increment
|
||||
@ -110,7 +111,6 @@ int main ()
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode2D(camera);
|
||||
|
||||
// Draw the 3d grid, rotated 90 degrees and centered around 0,0
|
||||
// just so we have something in the XY plane
|
||||
rlPushMatrix();
|
||||
@ -121,7 +121,6 @@ int main ()
|
||||
|
||||
// Draw a reference circle
|
||||
DrawCircle(GetScreenWidth()/2, GetScreenHeight()/2, 50, MAROON);
|
||||
|
||||
EndMode2D();
|
||||
|
||||
// Draw mouse reference
|
||||
@ -142,5 +141,6 @@ int main ()
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -6,12 +6,12 @@
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
|
||||
* Example contributed by Agnis Aldiņš (@nezvers) 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 Agnis Aldins (@nezvers)
|
||||
* Copyright (c) 2025 Agnis Aldiņš (@nezvers)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
*
|
||||
* raylib [core] example - clipboard text
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
*
|
||||
* Example contributed by Ananth S (@Ananth1839) and reviewed by Ramon Santamaria (@raysan5)
|
||||
@ -41,7 +43,7 @@ int main(void)
|
||||
"Copy and paste me!"
|
||||
};
|
||||
|
||||
char *clipboardText = NULL;
|
||||
const char *clipboardText = NULL;
|
||||
char inputBuffer[256] = "Hello from raylib!"; // Random initial string
|
||||
|
||||
// UI required variables
|
||||
@ -144,7 +146,7 @@ int main(void)
|
||||
GuiSetState(STATE_DISABLED);
|
||||
GuiLabel((Rectangle){ 50, 260, 700, 40 }, "Clipboard current text data:");
|
||||
GuiSetStyle(TEXTBOX, TEXT_READONLY, 1);
|
||||
GuiTextBox((Rectangle){ 50, 300, 700, 40 }, clipboardText, 256, false);
|
||||
GuiTextBox((Rectangle){ 50, 300, 700, 40 }, (char *)clipboardText, 256, false);
|
||||
GuiSetStyle(TEXTBOX, TEXT_READONLY, 0);
|
||||
GuiLabel((Rectangle){ 50, 360, 700, 40 }, "Try copying text from other applications and pasting here!");
|
||||
GuiSetState(STATE_NORMAL);
|
||||
|
||||
@ -64,7 +64,7 @@ int main(void)
|
||||
|
||||
// Encode data to Base64 string (includes NULL terminator), memory must be MemFree()
|
||||
base64Text = EncodeDataBase64((unsigned char *)textInput, textInputLen, &base64TextSize);
|
||||
|
||||
|
||||
hashCRC32 = ComputeCRC32((unsigned char *)textInput, textInputLen); // Compute CRC32 hash code (4 bytes)
|
||||
hashMD5 = ComputeMD5((unsigned char *)textInput, textInputLen); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||
hashSHA1 = ComputeSHA1((unsigned char *)textInput, textInputLen); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||
|
||||
@ -17,11 +17,11 @@
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdio.h> // Required for: fopen(), fclose(), fputc(), fwrite(), printf(), fprintf(), funopen()
|
||||
#include <time.h> // Required for: time_t, tm, time(), localtime(), strftime()
|
||||
#include <stdio.h> // Required for: printf(), vprintf(), fprintf()
|
||||
#include <time.h> // Required for: time_t, tm, time(), localtime(), strftime()
|
||||
|
||||
// Custom logging function
|
||||
void CustomLog(int msgType, const char *text, va_list args)
|
||||
void CustomTraceLog(int msgType, const char *text, va_list args)
|
||||
{
|
||||
char timeStr[64] = { 0 };
|
||||
time_t now = time(NULL);
|
||||
@ -54,7 +54,7 @@ int main(void)
|
||||
const int screenHeight = 450;
|
||||
|
||||
// Set custom logger
|
||||
SetTraceLogCallback(CustomLog);
|
||||
SetTraceLogCallback(CustomTraceLog);
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging");
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ int main(void)
|
||||
// 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
|
||||
// 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
|
||||
@ -68,7 +68,7 @@ int main(void)
|
||||
// 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))
|
||||
{
|
||||
|
||||
@ -20,9 +20,7 @@
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h" // Required for GUI controls
|
||||
|
||||
#include <string.h> // Required for: strcpy()
|
||||
|
||||
#define MAX_FILEPATH_SIZE 2048
|
||||
#define MAX_FILEPATH_SIZE 1024
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
@ -53,12 +51,10 @@ int main(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
if (btnBackPressed)
|
||||
{
|
||||
strcpy(directory, GetPrevDirectoryPath(directory));
|
||||
TextCopy(directory, GetPrevDirectoryPath(directory));
|
||||
UnloadDirectoryFiles(files);
|
||||
files = LoadDirectoryFiles(directory);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -68,7 +64,7 @@ int main(void)
|
||||
|
||||
DrawText(directory, 100, 40, 20, DARKGRAY);
|
||||
|
||||
btnBackPressed = GuiButton((Rectangle){ 40.0f, 40.0f, 20, 20 }, "<");
|
||||
btnBackPressed = GuiButton((Rectangle){ 40.0f, 38.0f, 48, 24 }, "<");
|
||||
|
||||
for (int i = 0; i < (int)files.count; i++)
|
||||
{
|
||||
@ -78,7 +74,7 @@ int main(void)
|
||||
{
|
||||
if (GuiButton((Rectangle){0.0f, 85.0f + 40.0f*(float)i, screenWidth, 40}, ""))
|
||||
{
|
||||
strcpy(directory, files.paths[i]);
|
||||
TextCopy(directory, files.paths[i]);
|
||||
UnloadDirectoryFiles(files);
|
||||
files = LoadDirectoryFiles(directory);
|
||||
continue;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - high dpi
|
||||
* raylib [core] example - highdpi demo
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
@ -33,7 +33,7 @@ int main(void)
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - high dpi");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi demo");
|
||||
SetWindowMinSize(450, 450);
|
||||
|
||||
int logicalGridDescY = 120;
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@ -27,9 +27,14 @@ int main(void)
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
|
||||
|
||||
// TODO: Load resources / Initialize variables at this point
|
||||
Vector2 scaleDpi = GetWindowScaleDPI();
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
int currentMonitor = GetCurrentMonitor();
|
||||
|
||||
int gridSpacing = 40; // Grid spacing in pixels
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
@ -39,7 +44,11 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update variables / Implement example logic at this point
|
||||
mousePos = GetMousePosition();
|
||||
currentMonitor = GetCurrentMonitor();
|
||||
scaleDpi = GetWindowScaleDPI();
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE)) ToggleBorderlessWindowed();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -48,11 +57,31 @@ int main(void)
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// TODO: Draw everything that requires to be drawn at this point
|
||||
// Draw grid
|
||||
for (int h = 0; h < 20; h++)
|
||||
{
|
||||
DrawText(TextFormat("%02i", h*gridSpacing), 4, h*gridSpacing - 4, 10, GRAY);
|
||||
DrawLine(24, h*gridSpacing, GetScreenWidth(), h*gridSpacing, LIGHTGRAY);
|
||||
}
|
||||
for (int v = 0; v < 40; v++)
|
||||
{
|
||||
DrawText(TextFormat("%02i", v*gridSpacing), v*gridSpacing - 10, 4, 10, GRAY);
|
||||
DrawLine(v*gridSpacing, 20, v*gridSpacing, GetScreenHeight(), LIGHTGRAY);
|
||||
}
|
||||
|
||||
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);
|
||||
// Draw UI info
|
||||
DrawText(TextFormat("CURRENT MONITOR: %i/%i (%ix%i)", currentMonitor + 1, GetMonitorCount(),
|
||||
GetMonitorWidth(currentMonitor), GetMonitorHeight(currentMonitor)), 50, 50, 20, DARKGRAY);
|
||||
DrawText(TextFormat("SCREEN SIZE: %ix%i", GetScreenWidth(), GetScreenHeight()), 50, 90, 20, DARKGRAY);
|
||||
DrawText(TextFormat("RENDER SIZE: %ix%i", GetRenderWidth(), GetRenderHeight()), 50, 130, 20, DARKGRAY);
|
||||
DrawText(TextFormat("SCALE FACTOR: %.1fx%.1f", scaleDpi.x, scaleDpi.y), 50, 170, 20, GRAY);
|
||||
|
||||
// Draw mouse position
|
||||
DrawCircleV(GetMousePosition(), 20, MAROON);
|
||||
DrawRectangle(mousePos.x - 25, mousePos.y, 50, 2, BLACK);
|
||||
DrawRectangle(mousePos.x, mousePos.y - 25, 2, 50, BLACK);
|
||||
DrawText(TextFormat("[%i,%i]", GetMouseX(), GetMouseY()), mousePos.x - 44,
|
||||
(mousePos.y > GetScreenHeight() - 60)? mousePos.y - 46 : mousePos.y + 30, 20, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
// 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
|
||||
// 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"
|
||||
|
||||
@ -44,7 +44,7 @@ typedef struct ActionInput {
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static int gamepadIndex = 0; // Gamepad default index
|
||||
static ActionInput actionInputs[MAX_ACTION] = { 0 };
|
||||
static ActionInput actionInputs[MAX_ACTION] = { 0 };
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
@ -67,14 +67,15 @@ int main(void)
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input actions");
|
||||
|
||||
// Set default actions
|
||||
|
||||
// Set default actions
|
||||
char actionSet = 0;
|
||||
SetActionsDefault();
|
||||
bool releaseAction = false;
|
||||
|
||||
Vector2 position = (Vector2){ 400.0f, 200.0f };
|
||||
Vector2 size = (Vector2){ 40.0f, 40.0f };
|
||||
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -83,7 +84,8 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
gamepadIndex = 0; // set this to gamepad being checked
|
||||
gamepadIndex = 0; // Set gamepad being checked
|
||||
|
||||
if (IsActionDown(ACTION_UP)) position.y -= 2;
|
||||
if (IsActionDown(ACTION_DOWN)) position.y += 2;
|
||||
if (IsActionDown(ACTION_LEFT)) position.x -= 2;
|
||||
@ -94,7 +96,11 @@ int main(void)
|
||||
position.y = (screenHeight-size.y)/2;
|
||||
}
|
||||
|
||||
// Switch control scheme by pressing TAB
|
||||
// Register release action for one frame
|
||||
releaseAction = false;
|
||||
if (IsActionReleased(ACTION_FIRE)) releaseAction = true;
|
||||
|
||||
// Switch control scheme by pressing TAB
|
||||
if (IsKeyPressed(KEY_TAB))
|
||||
{
|
||||
actionSet = !actionSet;
|
||||
@ -109,8 +115,8 @@ int main(void)
|
||||
|
||||
ClearBackground(GRAY);
|
||||
|
||||
DrawRectangleV(position, size, RED);
|
||||
|
||||
DrawRectangleV(position, size, releaseAction? BLUE : 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);
|
||||
|
||||
@ -134,9 +140,9 @@ int main(void)
|
||||
static bool IsActionPressed(int action)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
|
||||
if (action < MAX_ACTION) result = (IsKeyPressed(actionInputs[action].key) || IsGamepadButtonPressed(gamepadIndex, actionInputs[action].button));
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -145,20 +151,20 @@ static bool IsActionPressed(int 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)
|
||||
static bool IsActionDown(int action)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
|
||||
if (action < MAX_ACTION) result = (IsKeyDown(actionInputs[action].key) || IsGamepadButtonDown(gamepadIndex, actionInputs[action].button));
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -51,6 +51,8 @@ int main(void)
|
||||
const float leftTriggerDeadzone = -0.9f;
|
||||
const float rightTriggerDeadzone = -0.9f;
|
||||
|
||||
Rectangle vibrateButton = { 0 };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -61,7 +63,12 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// ...
|
||||
if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--;
|
||||
if (IsKeyPressed(KEY_RIGHT)) gamepad++;
|
||||
Vector2 mousePosition = GetMousePosition();
|
||||
|
||||
vibrateButton = (Rectangle){ 10, 70 + 20*GetGamepadAxisCount(gamepad) + 20, 75, 24 };
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && CheckCollisionPointRec(mousePosition, vibrateButton)) SetGamepadVibration(gamepad, 1.0, 1.0, 1.0);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -70,9 +77,6 @@ int main(void)
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (IsKeyPressed(KEY_LEFT) && gamepad > 0) gamepad--;
|
||||
if (IsKeyPressed(KEY_RIGHT)) gamepad++;
|
||||
|
||||
if (IsGamepadAvailable(gamepad))
|
||||
{
|
||||
DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK);
|
||||
@ -93,7 +97,8 @@ int main(void)
|
||||
if (leftTrigger < leftTriggerDeadzone) leftTrigger = -1.0f;
|
||||
if (rightTrigger < rightTriggerDeadzone) rightTrigger = -1.0f;
|
||||
|
||||
if (TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1 || TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1)
|
||||
if ((TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_1) > -1) ||
|
||||
(TextFindIndex(TextToLower(GetGamepadName(gamepad)), XBOX_ALIAS_2) > -1))
|
||||
{
|
||||
DrawTexture(texXboxPad, 0, 0, DARKGRAY);
|
||||
|
||||
@ -125,16 +130,14 @@ int main(void)
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||
DrawCircle(259, 152, 39, BLACK);
|
||||
DrawCircle(259, 152, 34, LIGHTGRAY);
|
||||
DrawCircle(259 + (int)(leftStickX*20),
|
||||
152 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
DrawCircle(259 + (int)(leftStickX*20), 152 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
|
||||
// Draw axis: right joystick
|
||||
Color rightGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||
DrawCircle(461, 237, 38, BLACK);
|
||||
DrawCircle(461, 237, 33, LIGHTGRAY);
|
||||
DrawCircle(461 + (int)(rightStickX*20),
|
||||
237 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
DrawCircle(461 + (int)(rightStickX*20), 237 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
DrawRectangle(170, 30, 15, 70, GRAY);
|
||||
@ -177,16 +180,14 @@ int main(void)
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||
DrawCircle(319, 255, 35, BLACK);
|
||||
DrawCircle(319, 255, 31, LIGHTGRAY);
|
||||
DrawCircle(319 + (int)(leftStickX*20),
|
||||
255 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
DrawCircle(319 + (int)(leftStickX*20), 255 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
|
||||
// Draw axis: right joystick
|
||||
Color rightGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||
DrawCircle(475, 255, 35, BLACK);
|
||||
DrawCircle(475, 255, 31, LIGHTGRAY);
|
||||
DrawCircle(475 + (int)(rightStickX*20),
|
||||
255 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
DrawCircle(475 + (int)(rightStickX*20), 255 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
DrawRectangle(169, 48, 15, 70, GRAY);
|
||||
@ -236,23 +237,20 @@ int main(void)
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_LEFT_THUMB)) leftGamepadColor = RED;
|
||||
DrawCircle(345, 260, 40, BLACK);
|
||||
DrawCircle(345, 260, 35, LIGHTGRAY);
|
||||
DrawCircle(345 + (int)(leftStickX*20),
|
||||
260 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
DrawCircle(345 + (int)(leftStickX*20), 260 + (int)(leftStickY*20), 25, leftGamepadColor);
|
||||
|
||||
// Draw axis: right joystick
|
||||
Color rightGamepadColor = BLACK;
|
||||
if (IsGamepadButtonDown(gamepad, GAMEPAD_BUTTON_RIGHT_THUMB)) rightGamepadColor = RED;
|
||||
DrawCircle(465, 260, 40, BLACK);
|
||||
DrawCircle(465, 260, 35, LIGHTGRAY);
|
||||
DrawCircle(465 + (int)(rightStickX*20),
|
||||
260 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
DrawCircle(465 + (int)(rightStickX*20), 260 + (int)(rightStickY*20), 25, rightGamepadColor);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
DrawRectangle(151, 110, 15, 70, GRAY);
|
||||
DrawRectangle(644, 110, 15, 70, GRAY);
|
||||
DrawRectangle(151, 110, 15, (int)(((1 + leftTrigger)/2)*70), RED);
|
||||
DrawRectangle(644, 110, 15, (int)(((1 + rightTrigger)/2)*70), RED);
|
||||
|
||||
}
|
||||
|
||||
DrawText(TextFormat("DETECTED AXIS [%i]:", GetGamepadAxisCount(gamepad)), 10, 50, 10, MAROON);
|
||||
@ -262,6 +260,10 @@ int main(void)
|
||||
DrawText(TextFormat("AXIS %i: %.02f", i, GetGamepadAxisMovement(gamepad, i)), 20, 70 + 20*i, 10, DARKGRAY);
|
||||
}
|
||||
|
||||
// Draw vibrate button
|
||||
DrawRectangleRec(vibrateButton, SKYBLUE);
|
||||
DrawText("VIBRATE", vibrateButton.x + 14, vibrateButton.y + 1, 10, DARKGRAY);
|
||||
|
||||
if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED);
|
||||
else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY);
|
||||
}
|
||||
|
||||
@ -118,4 +118,6 @@ int main(void)
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -22,9 +22,9 @@
|
||||
#define GESTURE_LOG_SIZE 20
|
||||
#define MAX_TOUCH_COUNT 32
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------------
|
||||
static char const *GetGestureName(int gesture); // Get text string for gesture value
|
||||
static Color GetGestureColor(int gesture); // Get color for gesture value
|
||||
|
||||
@ -69,7 +69,6 @@ int main(void)
|
||||
float angleLength = 90.0f;
|
||||
float currentAngleDegrees = 0.0f;
|
||||
Vector2 finalVector = { 0.0f, 0.0f };
|
||||
char currentAngleStr[7] = "";
|
||||
Vector2 protractorPosition = { 266.0f, 315.0f };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
@ -203,7 +202,7 @@ int main(void)
|
||||
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)
|
||||
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));
|
||||
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;
|
||||
switch (logMode)
|
||||
{
|
||||
|
||||
@ -40,14 +40,8 @@ int main(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_H))
|
||||
{
|
||||
if (IsCursorHidden())
|
||||
{
|
||||
ShowCursor();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideCursor();
|
||||
}
|
||||
if (IsCursorHidden()) ShowCursor();
|
||||
else HideCursor();
|
||||
}
|
||||
|
||||
ballPosition = GetMousePosition();
|
||||
|
||||
@ -46,7 +46,7 @@ int main(void)
|
||||
// Clamp touch points available ( set the maximum touch points allowed )
|
||||
if (tCount > MAX_TOUCH_POINTS) tCount = MAX_TOUCH_POINTS;
|
||||
// Get touch points positions
|
||||
for (int i = 0; i < tCount; ++i) touchPositions[i] = GetTouchPosition(i);
|
||||
for (int i = 0; i < tCount; i++) touchPositions[i] = GetTouchPosition(i);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -55,7 +55,7 @@ int main(void)
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
for (int i = 0; i < tCount; ++i)
|
||||
for (int i = 0; i < tCount; i++)
|
||||
{
|
||||
// Make sure point is not (0, 0) as this means there is no touch for it
|
||||
if ((touchPositions[i].x > 0) && (touchPositions[i].y > 0))
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||
*
|
||||
* Example contributed by GreenSnakeLinux (@GreenSnakeLinux),
|
||||
* Example contributed by GreenSnakeLinux (@GreenSnakeLinux),
|
||||
* reviewed by Ramon Santamaria (@raysan5), oblerion (@oblerion) and danilwhale (@danilwhale)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
@ -86,7 +86,7 @@ int main(void)
|
||||
pressedButton = BUTTON_NONE;
|
||||
|
||||
// Make sure user is pressing left mouse button if they're from desktop
|
||||
if ((GetTouchPointCount() > 0) ||
|
||||
if ((GetTouchPointCount() > 0) ||
|
||||
((GetTouchPointCount() == 0) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)))
|
||||
{
|
||||
// Find nearest D-Pad button to the input position
|
||||
@ -113,7 +113,7 @@ int main(void)
|
||||
default: break;
|
||||
};
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Draw
|
||||
//--------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
@ -40,10 +40,9 @@ int main(void)
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
MonitorInfo monitors[MAX_MONITORS] = { 0 };
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - monitor detector");
|
||||
|
||||
MonitorInfo monitors[MAX_MONITORS] = { 0 };
|
||||
int currentMonitorIndex = GetCurrentMonitor();
|
||||
int monitorCount = 0;
|
||||
|
||||
@ -55,7 +54,6 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Variables to find the max x and Y to calculate the scale
|
||||
int maxWidth = 1;
|
||||
int maxHeight = 1;
|
||||
@ -68,42 +66,40 @@ int main(void)
|
||||
for (int i = 0; i < monitorCount; i++)
|
||||
{
|
||||
monitors[i] = (MonitorInfo){
|
||||
GetMonitorPosition(i),
|
||||
GetMonitorName(i),
|
||||
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;
|
||||
|
||||
if (monitors[i].position.x < monitorOffsetX) monitorOffsetX = -(int)monitors[i].position.x;
|
||||
|
||||
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)
|
||||
if (IsKeyPressed(KEY_ENTER) && (monitorCount > 1))
|
||||
{
|
||||
currentMonitorIndex += 1;
|
||||
|
||||
// Set index to 0 if the last one
|
||||
if(currentMonitorIndex == monitorCount) currentMonitorIndex = 0;
|
||||
if (currentMonitorIndex == monitorCount) currentMonitorIndex = 0;
|
||||
|
||||
SetWindowMonitor(currentMonitorIndex); // Move window to currentMonitorIndex
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get currentMonitorIndex if manually moved
|
||||
currentMonitorIndex = GetCurrentMonitor();
|
||||
}
|
||||
else currentMonitorIndex = GetCurrentMonitor(); // Get currentMonitorIndex if manually moved
|
||||
|
||||
float monitorScale = 0.6f;
|
||||
float monitorScale = 0.6f;
|
||||
|
||||
if(maxHeight > maxWidth + monitorOffsetX) monitorScale *= ((float)screenHeight/(float)maxHeight);
|
||||
if (maxHeight > (maxWidth + monitorOffsetX)) monitorScale *= ((float)screenHeight/(float)maxHeight);
|
||||
else monitorScale *= ((float)screenWidth/(float)(maxWidth + monitorOffsetX));
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -120,18 +116,18 @@ int main(void)
|
||||
{
|
||||
// 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
|
||||
(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,
|
||||
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,
|
||||
@ -146,16 +142,11 @@ int main(void)
|
||||
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));
|
||||
DrawRectangleV(windowPosition, (Vector2){screenWidth*monitorScale, screenHeight*monitorScale}, Fade(GREEN, 0.5));
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectangleLinesEx(rec, 5, GRAY);
|
||||
}
|
||||
|
||||
else DrawRectangleLinesEx(rec, 5, GRAY);
|
||||
}
|
||||
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
#define MAX_UNDO_STATES 26 // Maximum undo states supported for the ring buffer
|
||||
|
||||
#define GRID_CELL_SIZE 24
|
||||
#define GRID_CELL_SIZE 24
|
||||
#define MAX_GRID_CELLS_X 30
|
||||
#define MAX_GRID_CELLS_Y 13
|
||||
|
||||
@ -57,7 +57,7 @@ int main(void)
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
|
||||
// We have multiple options to implement an Undo/Redo system
|
||||
// Probably the most professional one is using the Command pattern to
|
||||
// define Actions and store those actions into an array as the events happen,
|
||||
@ -187,7 +187,7 @@ int main(void)
|
||||
if (lastUndoIndex > firstUndoIndex)
|
||||
{
|
||||
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
||||
DrawRectangleRec((Rectangle){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);
|
||||
}
|
||||
else if (firstUndoIndex > lastUndoIndex)
|
||||
@ -195,7 +195,7 @@ int main(void)
|
||||
if ((currentUndoIndex < MAX_UNDO_STATES) && (currentUndoIndex > lastUndoIndex))
|
||||
{
|
||||
for (int i = firstUndoIndex; i < currentUndoIndex; i++)
|
||||
DrawRectangleRec((Rectangle) { 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);
|
||||
}
|
||||
else
|
||||
|
||||
@ -6,22 +6,20 @@
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
|
||||
* Example contributed by Agnis Aldiņš (@nezvers) 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 Agnis Aldins (@nezvers)
|
||||
* Copyright (c) 2025 Agnis Aldiņš (@nezvers)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
// For itteration purposes and teaching example
|
||||
#define RESOLUTION_COUNT 4
|
||||
#define RESOLUTION_COUNT 4 // For iteration purposes and teaching example
|
||||
|
||||
enum ViewportType
|
||||
{
|
||||
typedef enum {
|
||||
// Only upscale, useful for pixel art
|
||||
KEEP_ASPECT_INTEGER,
|
||||
KEEP_HEIGHT_INTEGER,
|
||||
@ -32,24 +30,28 @@ enum ViewportType
|
||||
KEEP_WIDTH,
|
||||
// For itteration purposes and as a teaching example
|
||||
VIEWPORT_TYPE_COUNT,
|
||||
} ViewportType;
|
||||
|
||||
// For displaying on GUI
|
||||
const char *ViewportTypeNames[VIEWPORT_TYPE_COUNT] = {
|
||||
"KEEP_ASPECT_INTEGER",
|
||||
"KEEP_HEIGHT_INTEGER",
|
||||
"KEEP_WIDTH_INTEGER",
|
||||
"KEEP_ASPECT",
|
||||
"KEEP_HEIGHT",
|
||||
"KEEP_WIDTH",
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//--------------------------------------------------------------------------------------
|
||||
static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||
|
||||
static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||
|
||||
static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||
|
||||
static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||
|
||||
static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||
|
||||
static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect);
|
||||
|
||||
static void ResizeRenderSize(enum ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target);
|
||||
static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target);
|
||||
|
||||
// Example how to calculate position on RenderTexture
|
||||
static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect);
|
||||
@ -61,91 +63,89 @@ int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//---------------------------------------------------------
|
||||
// Preset resolutions that could be created by subdividing screen resolution
|
||||
Vector2 resolutionList[RESOLUTION_COUNT] = {
|
||||
(Vector2){64, 64},
|
||||
(Vector2){256, 240},
|
||||
(Vector2){320, 180},
|
||||
// 4K doesn't work with integer scaling but included for example purposes with non-integer scaling
|
||||
(Vector2){3840, 2160},
|
||||
};
|
||||
int resolutionIndex = 0;
|
||||
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
int gameWidth = 64;
|
||||
int gameHeight = 64;
|
||||
|
||||
RenderTexture2D target = (RenderTexture2D){0};
|
||||
Rectangle sourceRect = (Rectangle){0};
|
||||
Rectangle destRect = (Rectangle){0};
|
||||
|
||||
// For displaying on GUI
|
||||
const char *ViewportTypeNames[VIEWPORT_TYPE_COUNT] = {
|
||||
"KEEP_ASPECT_INTEGER",
|
||||
"KEEP_HEIGHT_INTEGER",
|
||||
"KEEP_WIDTH_INTEGER",
|
||||
"KEEP_ASPECT",
|
||||
"KEEP_HEIGHT",
|
||||
"KEEP_WIDTH",
|
||||
};
|
||||
enum ViewportType viewportType = KEEP_ASPECT_INTEGER;
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - viewport scaling");
|
||||
|
||||
// Preset resolutions that could be created by subdividing screen resolution
|
||||
Vector2 resolutionList[RESOLUTION_COUNT] = {
|
||||
(Vector2){ 64, 64 },
|
||||
(Vector2){ 256, 240 },
|
||||
(Vector2){ 320, 180 },
|
||||
// 4K doesn't work with integer scaling but included for example purposes with non-integer scaling
|
||||
(Vector2){ 3840, 2160 },
|
||||
};
|
||||
|
||||
int resolutionIndex = 0;
|
||||
int gameWidth = 64;
|
||||
int gameHeight = 64;
|
||||
|
||||
RenderTexture2D target = (RenderTexture2D){ 0 };
|
||||
Rectangle sourceRect = (Rectangle){ 0 };
|
||||
Rectangle destRect = (Rectangle){ 0 };
|
||||
|
||||
ViewportType viewportType = KEEP_ASPECT_INTEGER;
|
||||
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||
|
||||
// Button rectangles
|
||||
Rectangle decreaseResolutionButton = (Rectangle){ 200, 30, 10, 10 };
|
||||
Rectangle increaseResolutionButton = (Rectangle){ 215, 30, 10, 10 };
|
||||
Rectangle decreaseTypeButton = (Rectangle){ 200, 45, 10, 10 };
|
||||
Rectangle increaseTypeButton = (Rectangle){ 215, 45, 10, 10 };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//----------------------------------------------------------
|
||||
|
||||
// Button rectangles
|
||||
Rectangle decreaseResolutionButton = (Rectangle){200, 30, 10, 10};
|
||||
Rectangle increaseResolutionButton = (Rectangle){215, 30, 10, 10};
|
||||
Rectangle decreaseTypeButton = (Rectangle){200, 45, 10, 10};
|
||||
Rectangle increaseTypeButton = (Rectangle){215, 45, 10, 10};
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//-----------------------------------------------------
|
||||
if (IsWindowResized()){
|
||||
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsWindowResized()) ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||
|
||||
Vector2 mousePosition = GetMousePosition();
|
||||
bool mousePressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
|
||||
|
||||
|
||||
// Check buttons and rescale
|
||||
if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed){
|
||||
resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1) % RESOLUTION_COUNT;
|
||||
if (CheckCollisionPointRec(mousePosition, decreaseResolutionButton) && mousePressed)
|
||||
{
|
||||
resolutionIndex = (resolutionIndex + RESOLUTION_COUNT - 1)%RESOLUTION_COUNT;
|
||||
gameWidth = resolutionList[resolutionIndex].x;
|
||||
gameHeight = resolutionList[resolutionIndex].y;
|
||||
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||
}
|
||||
if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed){
|
||||
resolutionIndex = (resolutionIndex + 1) % RESOLUTION_COUNT;
|
||||
|
||||
if (CheckCollisionPointRec(mousePosition, increaseResolutionButton) && mousePressed)
|
||||
{
|
||||
resolutionIndex = (resolutionIndex + 1)%RESOLUTION_COUNT;
|
||||
gameWidth = resolutionList[resolutionIndex].x;
|
||||
gameHeight = resolutionList[resolutionIndex].y;
|
||||
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||
}
|
||||
if (CheckCollisionPointRec(mousePosition, decreaseTypeButton) && mousePressed){
|
||||
viewportType = (viewportType + VIEWPORT_TYPE_COUNT - 1) % VIEWPORT_TYPE_COUNT;
|
||||
|
||||
if (CheckCollisionPointRec(mousePosition, decreaseTypeButton) && mousePressed)
|
||||
{
|
||||
viewportType = (viewportType + VIEWPORT_TYPE_COUNT - 1)%VIEWPORT_TYPE_COUNT;
|
||||
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||
}
|
||||
if (CheckCollisionPointRec(mousePosition, increaseTypeButton) && mousePressed){
|
||||
viewportType = (viewportType + 1) % VIEWPORT_TYPE_COUNT;
|
||||
|
||||
if (CheckCollisionPointRec(mousePosition, increaseTypeButton) && mousePressed)
|
||||
{
|
||||
viewportType = (viewportType + 1)%VIEWPORT_TYPE_COUNT;
|
||||
ResizeRenderSize(viewportType, &screenWidth, &screenHeight, gameWidth, gameHeight, &sourceRect, &destRect, &target);
|
||||
}
|
||||
|
||||
Vector2 textureMousePosition = Screen2RenderTexturePosition(mousePosition, &sourceRect, &destRect);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//-----------------------------------------------------
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw our scene to the render texture
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(WHITE);
|
||||
DrawCircle(textureMousePosition.x, textureMousePosition.y, 20.f, LIME);
|
||||
|
||||
|
||||
DrawCircle(textureMousePosition.x, textureMousePosition.y, 20.0f, LIME);
|
||||
EndTextureMode();
|
||||
|
||||
// Draw render texture to main framebuffer
|
||||
@ -153,9 +153,7 @@ int main(void)
|
||||
ClearBackground(BLACK);
|
||||
|
||||
// Draw our render texture with rotation applied
|
||||
const Vector2 ORIGIN_POSITION = (Vector2){ 0.0f, 0.0f };
|
||||
const float ROTATION = 0.f;
|
||||
DrawTexturePro(target.texture, sourceRect, destRect, ORIGIN_POSITION, ROTATION, WHITE);
|
||||
DrawTexturePro(target.texture, sourceRect, destRect, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
|
||||
|
||||
// Draw Native resolution (GUI or anything)
|
||||
// Draw info box
|
||||
@ -167,15 +165,10 @@ int main(void)
|
||||
DrawText(TextFormat("Game Resolution: %d x %d", gameWidth, gameHeight), 15, 30, 10, BLACK);
|
||||
|
||||
DrawText(TextFormat("Type: %s", ViewportTypeNames[viewportType]), 15, 45, 10, BLACK);
|
||||
Vector2 scaleRatio = (Vector2){destRect.width / sourceRect.width, destRect.height / -sourceRect.height};
|
||||
if (scaleRatio.x < 0.001f || scaleRatio.y < 0.001f)
|
||||
{
|
||||
DrawText(TextFormat("Scale ratio: INVALID"), 15, 60, 10, BLACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText(TextFormat("Scale ratio: %.2f x %.2f", scaleRatio.x, scaleRatio.y), 15, 60, 10, BLACK);
|
||||
}
|
||||
Vector2 scaleRatio = (Vector2){destRect.width/sourceRect.width, -destRect.height/sourceRect.height};
|
||||
if (scaleRatio.x < 0.001f || scaleRatio.y < 0.001f) DrawText(TextFormat("Scale ratio: INVALID"), 15, 60, 10, BLACK);
|
||||
else DrawText(TextFormat("Scale ratio: %.2f x %.2f", scaleRatio.x, scaleRatio.y), 15, 60, 10, BLACK);
|
||||
|
||||
DrawText(TextFormat("Source size: %.2f x %.2f", sourceRect.width, -sourceRect.height), 15, 75, 10, BLACK);
|
||||
DrawText(TextFormat("Destination size: %.2f x %.2f", destRect.width, destRect.height), 15, 90, 10, BLACK);
|
||||
|
||||
@ -190,13 +183,13 @@ int main(void)
|
||||
DrawText(">", increaseResolutionButton.x + 3, increaseResolutionButton.y + 1, 10, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//---------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//----------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -206,54 +199,54 @@ int main(void)
|
||||
//--------------------------------------------------------------------------------------
|
||||
static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||
{
|
||||
sourceRect->x = 0.f;
|
||||
sourceRect->x = 0.0f;
|
||||
sourceRect->y = (float)gameHeight;
|
||||
sourceRect->width = (float)gameWidth;
|
||||
sourceRect->height = (float)-gameHeight;
|
||||
|
||||
const int ratio_x = (screenWidth/gameWidth);
|
||||
const int ratio_y = (screenHeight/gameHeight);
|
||||
const float resizeRatio = (float)(ratio_x < ratio_y ? ratio_x : ratio_y);
|
||||
const float resizeRatio = (float)((ratio_x < ratio_y)? ratio_x : ratio_y);
|
||||
|
||||
destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5);
|
||||
destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5);
|
||||
destRect->width = (float)(int)(gameWidth * resizeRatio);
|
||||
destRect->height = (float)(int)(gameHeight * resizeRatio);
|
||||
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
|
||||
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
|
||||
destRect->width = (float)(int)(gameWidth*resizeRatio);
|
||||
destRect->height = (float)(int)(gameHeight*resizeRatio);
|
||||
}
|
||||
|
||||
static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||
{
|
||||
const float resizeRatio = (float)(screenHeight/gameHeight);
|
||||
sourceRect->x = 0.f;
|
||||
sourceRect->y = 0.f;
|
||||
sourceRect->width = (float)(int)(screenWidth / resizeRatio);
|
||||
sourceRect->x = 0.0f;
|
||||
sourceRect->y = 0.0f;
|
||||
sourceRect->width = (float)(int)(screenWidth/resizeRatio);
|
||||
sourceRect->height = (float)-gameHeight;
|
||||
|
||||
destRect->x = (float)(int)((screenWidth - (sourceRect->width * resizeRatio)) * 0.5);
|
||||
destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5);
|
||||
destRect->width = (float)(int)(sourceRect->width * resizeRatio);
|
||||
destRect->height = (float)(int)(gameHeight * resizeRatio);
|
||||
destRect->x = (float)(int)((screenWidth - (sourceRect->width*resizeRatio))*0.5f);
|
||||
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
|
||||
destRect->width = (float)(int)(sourceRect->width*resizeRatio);
|
||||
destRect->height = (float)(int)(gameHeight*resizeRatio);
|
||||
}
|
||||
|
||||
static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||
{
|
||||
const float resizeRatio = (float)(screenWidth/gameWidth);
|
||||
sourceRect->x = 0.f;
|
||||
sourceRect->y = 0.f;
|
||||
sourceRect->x = 0.0f;
|
||||
sourceRect->y = 0.0f;
|
||||
sourceRect->width = (float)gameWidth;
|
||||
sourceRect->height = (float)(int)(screenHeight / resizeRatio);
|
||||
sourceRect->height = (float)(int)(screenHeight/resizeRatio);
|
||||
|
||||
destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5);
|
||||
destRect->y = (float)(int)((screenHeight - (sourceRect->height * resizeRatio)) * 0.5);
|
||||
destRect->width = (float)(int)(gameWidth * resizeRatio);
|
||||
destRect->height = (float)(int)(sourceRect->height * resizeRatio);
|
||||
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
|
||||
destRect->y = (float)(int)((screenHeight - (sourceRect->height*resizeRatio))*0.5f);
|
||||
destRect->width = (float)(int)(gameWidth*resizeRatio);
|
||||
destRect->height = (float)(int)(sourceRect->height*resizeRatio);
|
||||
|
||||
sourceRect->height *= -1.f;
|
||||
sourceRect->height *= -1.0f;
|
||||
}
|
||||
|
||||
static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||
{
|
||||
sourceRect->x = 0.f;
|
||||
sourceRect->x = 0.0f;
|
||||
sourceRect->y = (float)gameHeight;
|
||||
sourceRect->width = (float)gameWidth;
|
||||
sourceRect->height = (float)-gameHeight;
|
||||
@ -262,81 +255,58 @@ static void KeepAspectCentered(int screenWidth, int screenHeight, int gameWidth,
|
||||
const float ratio_y = ((float)screenHeight/(float)gameHeight);
|
||||
const float resizeRatio = (ratio_x < ratio_y ? ratio_x : ratio_y);
|
||||
|
||||
destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5);
|
||||
destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5);
|
||||
destRect->width = (float)(int)(gameWidth * resizeRatio);
|
||||
destRect->height = (float)(int)(gameHeight * resizeRatio);
|
||||
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
|
||||
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
|
||||
destRect->width = (float)(int)(gameWidth*resizeRatio);
|
||||
destRect->height = (float)(int)(gameHeight*resizeRatio);
|
||||
}
|
||||
|
||||
static void KeepHeightCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||
{
|
||||
const float resizeRatio = ((float)screenHeight/(float)gameHeight);
|
||||
sourceRect->x = 0.f;
|
||||
sourceRect->y = 0.f;
|
||||
sourceRect->width = (float)(int)((float)screenWidth / resizeRatio);
|
||||
sourceRect->x = 0.0f;
|
||||
sourceRect->y = 0.0f;
|
||||
sourceRect->width = (float)(int)((float)screenWidth/resizeRatio);
|
||||
sourceRect->height = (float)-gameHeight;
|
||||
|
||||
destRect->x = (float)(int)((screenWidth - (sourceRect->width * resizeRatio)) * 0.5);
|
||||
destRect->y = (float)(int)((screenHeight - (gameHeight * resizeRatio)) * 0.5);
|
||||
destRect->width = (float)(int)(sourceRect->width * resizeRatio);
|
||||
destRect->height = (float)(int)(gameHeight * resizeRatio);
|
||||
destRect->x = (float)(int)((screenWidth - (sourceRect->width*resizeRatio))*0.5f);
|
||||
destRect->y = (float)(int)((screenHeight - (gameHeight*resizeRatio))*0.5f);
|
||||
destRect->width = (float)(int)(sourceRect->width*resizeRatio);
|
||||
destRect->height = (float)(int)(gameHeight*resizeRatio);
|
||||
}
|
||||
|
||||
static void KeepWidthCentered(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect)
|
||||
{
|
||||
const float resizeRatio = ((float)screenWidth/(float)gameWidth);
|
||||
sourceRect->x = 0.f;
|
||||
sourceRect->y = 0.f;
|
||||
sourceRect->x = 0.0f;
|
||||
sourceRect->y = 0.0f;
|
||||
sourceRect->width = (float)gameWidth;
|
||||
sourceRect->height = (float)(int)((float)screenHeight / resizeRatio);
|
||||
sourceRect->height = (float)(int)((float)screenHeight/resizeRatio);
|
||||
|
||||
destRect->x = (float)(int)((screenWidth - (gameWidth * resizeRatio)) * 0.5);
|
||||
destRect->y = (float)(int)((screenHeight - (sourceRect->height * resizeRatio)) * 0.5);
|
||||
destRect->width = (float)(int)(gameWidth * resizeRatio);
|
||||
destRect->height = (float)(int)(sourceRect->height * resizeRatio);
|
||||
destRect->x = (float)(int)((screenWidth - (gameWidth*resizeRatio))*0.5f);
|
||||
destRect->y = (float)(int)((screenHeight - (sourceRect->height*resizeRatio))*0.5f);
|
||||
destRect->width = (float)(int)(gameWidth*resizeRatio);
|
||||
destRect->height = (float)(int)(sourceRect->height*resizeRatio);
|
||||
|
||||
sourceRect->height *= -1.f;
|
||||
}
|
||||
|
||||
static void ResizeRenderSize(enum ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target)
|
||||
static void ResizeRenderSize(ViewportType viewportType, int *screenWidth, int *screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect, RenderTexture2D *target)
|
||||
{
|
||||
*screenWidth = GetScreenWidth();
|
||||
*screenHeight = GetScreenHeight();
|
||||
|
||||
switch(viewportType)
|
||||
{
|
||||
case KEEP_ASPECT_INTEGER:
|
||||
{
|
||||
KeepAspectCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect);
|
||||
break;
|
||||
}
|
||||
case KEEP_HEIGHT_INTEGER:
|
||||
{
|
||||
KeepHeightCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect);
|
||||
break;
|
||||
}
|
||||
case KEEP_WIDTH_INTEGER:
|
||||
{
|
||||
KeepWidthCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect);
|
||||
break;
|
||||
}
|
||||
case KEEP_ASPECT:
|
||||
{
|
||||
KeepAspectCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect);
|
||||
break;
|
||||
}
|
||||
case KEEP_HEIGHT:
|
||||
{
|
||||
KeepHeightCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect);
|
||||
break;
|
||||
}
|
||||
case KEEP_WIDTH:
|
||||
{
|
||||
KeepWidthCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect);
|
||||
break;
|
||||
}
|
||||
default: {}
|
||||
case KEEP_ASPECT_INTEGER: KeepAspectCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||
case KEEP_HEIGHT_INTEGER: KeepHeightCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||
case KEEP_WIDTH_INTEGER: KeepWidthCenteredInteger(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||
case KEEP_ASPECT: KeepAspectCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||
case KEEP_HEIGHT: KeepHeightCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||
case KEEP_WIDTH: KeepWidthCentered(*screenWidth, *screenHeight, gameWidth, gameHeight, sourceRect, destRect); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
UnloadRenderTexture(*target);
|
||||
*target = LoadRenderTexture(sourceRect->width, -sourceRect->height);
|
||||
}
|
||||
@ -345,7 +315,7 @@ static void ResizeRenderSize(enum ViewportType viewportType, int *screenWidth, i
|
||||
static Vector2 Screen2RenderTexturePosition(Vector2 point, Rectangle *textureRect, Rectangle *scaledRect)
|
||||
{
|
||||
Vector2 relativePosition = {point.x - scaledRect->x, point.y - scaledRect->y};
|
||||
Vector2 ratio = {textureRect->width / scaledRect->width, -textureRect->height / scaledRect->height};
|
||||
Vector2 ratio = {textureRect->width/scaledRect->width, -textureRect->height/scaledRect->height};
|
||||
|
||||
return (Vector2){relativePosition.x * ratio.x, relativePosition.y * ratio.x};
|
||||
return (Vector2){relativePosition.x*ratio.x, relativePosition.y*ratio.x};
|
||||
}
|
||||
@ -43,7 +43,7 @@ int main(void)
|
||||
*/
|
||||
|
||||
// Set configuration flags for window creation
|
||||
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
|
||||
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);// | FLAG_WINDOW_TRANSPARENT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - window flags");
|
||||
|
||||
Vector2 ballPosition = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||
@ -97,7 +97,8 @@ int main(void)
|
||||
if (IsWindowState(FLAG_WINDOW_MINIMIZED))
|
||||
{
|
||||
framesCounter++;
|
||||
if (framesCounter >= 240) {
|
||||
if (framesCounter >= 240)
|
||||
{
|
||||
RestoreWindow(); // Restore window after 3 seconds
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
*
|
||||
* static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)];
|
||||
*
|
||||
* guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
|
||||
* guiStyle size is by default: 16*(16 + 8) = 384 int = 384*4 bytes = 1536 bytes = 1.5 KB
|
||||
*
|
||||
* Note that the first set of BASE properties (by default guiStyle[0..15]) belong to the generic style
|
||||
* used for all controls, when any of those base values is set, it is automatically populated to all
|
||||
@ -141,7 +141,7 @@
|
||||
* Draw text bounds rectangles for debug
|
||||
*
|
||||
* VERSIONS HISTORY:
|
||||
* 5.0-dev (2025) Current dev version...
|
||||
* 5.0 (xx-Nov-2025) ADDED: Support up to 32 controls (v500)
|
||||
* ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes
|
||||
* ADDED: GuiValueBoxFloat()
|
||||
* ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP
|
||||
@ -271,7 +271,7 @@
|
||||
* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria
|
||||
*
|
||||
* DEPENDENCIES:
|
||||
* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
|
||||
* raylib 5.6-dev - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
|
||||
*
|
||||
* STANDALONE MODE:
|
||||
* By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled
|
||||
@ -1010,28 +1010,28 @@ typedef enum {
|
||||
ICON_SLICING = 231,
|
||||
ICON_MANUAL_CONTROL = 232,
|
||||
ICON_COLLISION = 233,
|
||||
ICON_234 = 234,
|
||||
ICON_235 = 235,
|
||||
ICON_236 = 236,
|
||||
ICON_237 = 237,
|
||||
ICON_238 = 238,
|
||||
ICON_239 = 239,
|
||||
ICON_240 = 240,
|
||||
ICON_241 = 241,
|
||||
ICON_242 = 242,
|
||||
ICON_243 = 243,
|
||||
ICON_244 = 244,
|
||||
ICON_245 = 245,
|
||||
ICON_246 = 246,
|
||||
ICON_247 = 247,
|
||||
ICON_248 = 248,
|
||||
ICON_249 = 249,
|
||||
ICON_CIRCLE_ADD = 234,
|
||||
ICON_CIRCLE_ADD_FILL = 235,
|
||||
ICON_CIRCLE_WARNING = 236,
|
||||
ICON_CIRCLE_WARNING_FILL = 237,
|
||||
ICON_BOX_MORE = 238,
|
||||
ICON_BOX_MORE_FILL = 239,
|
||||
ICON_BOX_MINUS = 240,
|
||||
ICON_BOX_MINUS_FILL = 241,
|
||||
ICON_UNION = 242,
|
||||
ICON_INTERSECTION = 243,
|
||||
ICON_DIFFERENCE = 244,
|
||||
ICON_SPHERE = 245,
|
||||
ICON_CYLINDER = 246,
|
||||
ICON_CONE = 247,
|
||||
ICON_ELLIPSOID = 248,
|
||||
ICON_CAPSULE = 249,
|
||||
ICON_250 = 250,
|
||||
ICON_251 = 251,
|
||||
ICON_252 = 252,
|
||||
ICON_253 = 253,
|
||||
ICON_254 = 254,
|
||||
ICON_255 = 255,
|
||||
ICON_255 = 255
|
||||
} GuiIconName;
|
||||
#endif
|
||||
|
||||
@ -1078,7 +1078,7 @@ typedef enum {
|
||||
|
||||
// Check if two rectangles are equal, used to validate a slider bounds as an id
|
||||
#ifndef CHECK_BOUNDS_ID
|
||||
#define CHECK_BOUNDS_ID(src, dst) ((src.x == dst.x) && (src.y == dst.y) && (src.width == dst.width) && (src.height == dst.height))
|
||||
#define CHECK_BOUNDS_ID(src, dst) (((int)src.x == (int)dst.x) && ((int)src.y == (int)dst.y) && ((int)src.width == (int)dst.width) && ((int)src.height == (int)dst.height))
|
||||
#endif
|
||||
|
||||
#if !defined(RAYGUI_NO_ICONS) && !defined(RAYGUI_CUSTOM_ICONS)
|
||||
@ -1341,22 +1341,22 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] =
|
||||
0x7fe00000, 0x402e4020, 0x43ce5e0a, 0x40504078, 0x438e4078, 0x402e5e0a, 0x7fe04020, 0x00000000, // ICON_SLICING
|
||||
0x00000000, 0x40027ffe, 0x47c24002, 0x55425d42, 0x55725542, 0x50125552, 0x10105016, 0x00001ff0, // ICON_MANUAL_CONTROL
|
||||
0x7ffe0000, 0x43c24002, 0x48124422, 0x500a500a, 0x500a500a, 0x44224812, 0x400243c2, 0x00007ffe, // ICON_COLLISION
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_237
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_238
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_239
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_240
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_241
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_242
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_243
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_244
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_245
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_246
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_247
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_248
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_249
|
||||
0x03c00000, 0x10080c30, 0x21842184, 0x4ff24182, 0x41824ff2, 0x21842184, 0x0c301008, 0x000003c0, // ICON_CIRCLE_ADD
|
||||
0x03c00000, 0x1ff80ff0, 0x3e7c3e7c, 0x700e7e7e, 0x7e7e700e, 0x3e7c3e7c, 0x0ff01ff8, 0x000003c0, // ICON_CIRCLE_ADD_FILL
|
||||
0x03c00000, 0x10080c30, 0x21842184, 0x41824182, 0x40024182, 0x21842184, 0x0c301008, 0x000003c0, // ICON_CIRCLE_WARNING
|
||||
0x03c00000, 0x1ff80ff0, 0x3e7c3e7c, 0x7e7e7e7e, 0x7ffe7e7e, 0x3e7c3e7c, 0x0ff01ff8, 0x000003c0, // ICON_CIRCLE_WARNING_FILL
|
||||
0x00000000, 0x10041ffc, 0x10841004, 0x13e41084, 0x10841084, 0x10041004, 0x00001ffc, 0x00000000, // ICON_BOX_MORE
|
||||
0x00000000, 0x1ffc1ffc, 0x1f7c1ffc, 0x1c1c1f7c, 0x1f7c1f7c, 0x1ffc1ffc, 0x00001ffc, 0x00000000, // ICON_BOX_MORE_FILL
|
||||
0x00000000, 0x1ffc1ffc, 0x1ffc1ffc, 0x1c1c1ffc, 0x1ffc1ffc, 0x1ffc1ffc, 0x00001ffc, 0x00000000, // ICON_BOX_MINUS
|
||||
0x00000000, 0x10041ffc, 0x10041004, 0x13e41004, 0x10041004, 0x10041004, 0x00001ffc, 0x00000000, // ICON_BOX_MINUS_FILL
|
||||
0x07fe0000, 0x055606aa, 0x7ff606aa, 0x55766eba, 0x55766eaa, 0x55606ffe, 0x55606aa0, 0x00007fe0, // ICON_UNION
|
||||
0x07fe0000, 0x04020402, 0x7fe20402, 0x456246a2, 0x456246a2, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_INTERSECTION
|
||||
0x07fe0000, 0x055606aa, 0x7ff606aa, 0x4436442a, 0x4436442a, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_DIFFERENCE
|
||||
0x03c00000, 0x10080c30, 0x20042004, 0x60064002, 0x47e2581a, 0x20042004, 0x0c301008, 0x000003c0, // ICON_SPHERE
|
||||
0x03e00000, 0x08080410, 0x0c180808, 0x08080be8, 0x08080808, 0x08080808, 0x04100808, 0x000003e0, // ICON_CYLINDER
|
||||
0x00800000, 0x01400140, 0x02200220, 0x04100410, 0x08080808, 0x1c1c13e4, 0x08081004, 0x000007f0, // ICON_CONE
|
||||
0x00000000, 0x07e00000, 0x20841918, 0x40824082, 0x40824082, 0x19182084, 0x000007e0, 0x00000000, // ICON_ELLIPSOID
|
||||
0x00000000, 0x00000000, 0x20041ff8, 0x40024002, 0x40024002, 0x1ff82004, 0x00000000, 0x00000000, // ICON_CAPSULE
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_250
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_251
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_252
|
||||
@ -1743,7 +1743,7 @@ int GuiPanel(Rectangle bounds, const char *text)
|
||||
// NOTE: Using GuiToggle() for the TABS
|
||||
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
|
||||
{
|
||||
#define RAYGUI_TABBAR_ITEM_WIDTH 160
|
||||
#define RAYGUI_TABBAR_ITEM_WIDTH 148
|
||||
|
||||
int result = -1;
|
||||
//GuiState state = guiState;
|
||||
@ -1776,12 +1776,12 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
|
||||
if (i == (*active))
|
||||
{
|
||||
toggle = true;
|
||||
GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle);
|
||||
GuiToggle(tabBounds, text[i], &toggle);
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = false;
|
||||
GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle);
|
||||
GuiToggle(tabBounds, text[i], &toggle);
|
||||
if (toggle) *active = i;
|
||||
}
|
||||
|
||||
@ -2590,7 +2590,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
int pasteLength = 0;
|
||||
int pasteCodepoint;
|
||||
int pasteCodepointSize;
|
||||
|
||||
|
||||
// Count how many codepoints to copy, stopping at the first unwanted control character
|
||||
while (true)
|
||||
{
|
||||
@ -2599,7 +2599,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
if (!(multiline && (pasteCodepoint == (int)'\n')) && !(pasteCodepoint >= 32)) break;
|
||||
pasteLength += pasteCodepointSize;
|
||||
}
|
||||
|
||||
|
||||
if (pasteLength > 0)
|
||||
{
|
||||
// Move forward data from cursor position
|
||||
@ -2662,7 +2662,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
while (offset < textLength)
|
||||
{
|
||||
if (!isspace(nextCodepoint & 0xff)) break;
|
||||
|
||||
|
||||
offset += nextCodepointSize;
|
||||
accCodepointSize += nextCodepointSize;
|
||||
nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize);
|
||||
@ -2673,11 +2673,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
|
||||
textLength -= accCodepointSize;
|
||||
}
|
||||
|
||||
|
||||
else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && autoCursorShouldTrigger)))
|
||||
{
|
||||
// Delete single codepoint from text, after current cursor position
|
||||
|
||||
|
||||
int nextCodepointSize = 0;
|
||||
GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize);
|
||||
|
||||
@ -2704,7 +2704,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
offset -= prevCodepointSize;
|
||||
accCodepointSize += prevCodepointSize;
|
||||
}
|
||||
|
||||
|
||||
// Check characters of the same type to delete (either ASCII punctuation or anything non-whitespace)
|
||||
// Not using isalnum() since it only works on ASCII characters
|
||||
bool puctuation = ispunct(prevCodepoint & 0xff);
|
||||
@ -2723,11 +2723,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
textLength -= accCodepointSize;
|
||||
textBoxCursorIndex -= accCodepointSize;
|
||||
}
|
||||
|
||||
|
||||
else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger)))
|
||||
{
|
||||
// Delete single codepoint from text, before current cursor position
|
||||
|
||||
|
||||
int prevCodepointSize = 0;
|
||||
|
||||
GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize);
|
||||
@ -3033,7 +3033,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
|
||||
int result = 0;
|
||||
GuiState state = guiState;
|
||||
|
||||
char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0";
|
||||
char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = { 0 };
|
||||
snprintf(textValue, RAYGUI_VALUEBOX_MAX_CHARS + 1, "%i", *value);
|
||||
|
||||
Rectangle textBounds = { 0 };
|
||||
@ -3051,7 +3051,6 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
|
||||
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
|
||||
{
|
||||
Vector2 mousePoint = GetMousePosition();
|
||||
|
||||
bool valueHasChanged = false;
|
||||
|
||||
if (editMode)
|
||||
@ -3070,7 +3069,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
|
||||
keyCount--;
|
||||
valueHasChanged = true;
|
||||
}
|
||||
else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS -1)
|
||||
else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS)
|
||||
{
|
||||
if (keyCount == 0)
|
||||
{
|
||||
@ -3087,30 +3086,26 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
|
||||
}
|
||||
}
|
||||
|
||||
// Only allow keys in range [48..57]
|
||||
if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS)
|
||||
// Add new digit to text value
|
||||
if ((keyCount >= 0) && (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width))
|
||||
{
|
||||
if (GuiGetTextWidth(textValue) < bounds.width)
|
||||
int key = GetCharPressed();
|
||||
|
||||
// Only allow keys in range [48..57]
|
||||
if ((key >= 48) && (key <= 57))
|
||||
{
|
||||
int key = GetCharPressed();
|
||||
if ((key >= 48) && (key <= 57))
|
||||
{
|
||||
textValue[keyCount] = (char)key;
|
||||
keyCount++;
|
||||
valueHasChanged = true;
|
||||
}
|
||||
textValue[keyCount] = (char)key;
|
||||
keyCount++;
|
||||
valueHasChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete text
|
||||
if (keyCount > 0)
|
||||
if ((keyCount > 0) && IsKeyPressed(KEY_BACKSPACE))
|
||||
{
|
||||
if (IsKeyPressed(KEY_BACKSPACE))
|
||||
{
|
||||
keyCount--;
|
||||
textValue[keyCount] = '\0';
|
||||
valueHasChanged = true;
|
||||
}
|
||||
keyCount--;
|
||||
textValue[keyCount] = '\0';
|
||||
valueHasChanged = true;
|
||||
}
|
||||
|
||||
if (valueHasChanged) *value = TextToInteger(textValue);
|
||||
@ -3224,9 +3219,9 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float
|
||||
textValue[1] = '\0';
|
||||
keyCount++;
|
||||
}
|
||||
|
||||
|
||||
for (int i = keyCount; i > -1; i--) textValue[i + 1] = textValue[i];
|
||||
|
||||
|
||||
textValue[0] = '-';
|
||||
keyCount++;
|
||||
valueHasChanged = true;
|
||||
@ -5084,25 +5079,18 @@ static const char **GetTextLines(const char *text, int *count)
|
||||
int textSize = (int)strlen(text);
|
||||
|
||||
lines[0] = text;
|
||||
int len = 0;
|
||||
*count = 1;
|
||||
//int lineSize = 0; // Stores current line size, not returned
|
||||
|
||||
for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
{
|
||||
if (text[i] == '\n')
|
||||
{
|
||||
//lineSize = len;
|
||||
k++;
|
||||
lines[k] = &text[i + 1]; // WARNING: next value is valid?
|
||||
len = 0;
|
||||
lines[k] = &text[i + 1]; // WARNING: next value is valid?
|
||||
*count += 1;
|
||||
}
|
||||
else len++;
|
||||
}
|
||||
|
||||
//lines[*count - 1].size = len;
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ core;core_3d_camera_mode;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@rays
|
||||
core;core_3d_camera_free;★☆☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_3d_camera_first_person;★★☆☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_3d_camera_split_screen;★★★☆;3.7;4.0;2021;2025;"Jeffery Myers";@JeffM2501
|
||||
core;core_3d_camera_fps;★★★☆;5.5;5.5;2025;2025;"Agnis Aldins";@nezvers
|
||||
core;core_3d_camera_fps;★★★☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||
core;core_3d_picking;★★☆☆;1.3;4.0;2015;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_world_screen;★★☆☆;1.3;1.4;2015;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_window_flags;★★★☆;3.5;3.5;2020;2025;"Ramon Santamaria";@raysan5
|
||||
@ -43,15 +43,15 @@ core;core_custom_frame_control;★★★★;4.0;4.0;2021;2025;"Ramon Santamaria"
|
||||
core;core_smooth_pixelperfect;★★★☆;3.7;4.0;2021;2025;"Giancamillo Alessandroni";@NotManyIdeasDev
|
||||
core;core_random_sequence;★☆☆☆;5.0;5.0;2023;2025;"Dalton Overmyer";@REDl3east
|
||||
core;core_automation_events;★★★☆;5.0;5.0;2023;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_high_dpi;★★☆☆;5.0;5.5;2025;2025;"Jonathan Marler";@marler8997
|
||||
core;core_highdpi_demo;★★☆☆;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_undo_redo;★★★☆;5.5;5.6;2025;2025;"Ramon Santamaria";@raysan5
|
||||
core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldins";@nezvers
|
||||
core;core_viewport_scaling;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||
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;"Ananth S";@Ananth1839
|
||||
core;core_clipboard_text;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ananth S";@Ananth1839
|
||||
core;core_text_file_loading;★☆☆☆;5.5;5.6;0;0;"Aanjishnu Bhattacharyya";@NimComPoo-04
|
||||
core;core_compute_hash;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Ramon Santamaria";@raysan5
|
||||
shapes;shapes_basic_shapes;★☆☆☆;1.0;4.2;2014;2025;"Ramon Santamaria";@raysan5
|
||||
@ -88,6 +88,10 @@ shapes;shapes_simple_particles;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@
|
||||
shapes;shapes_starfield_effect;★★☆☆;5.5;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
shapes;shapes_lines_drawing;★☆☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_math_angle_rotation;★☆☆☆;5.6-dev;5.6;2025;2025;"Kris";@krispy-snacc
|
||||
shapes;shapes_rlgl_color_wheel;★★★☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_rlgl_triangle;★★☆☆;5.6-dev;5.6-dev;2025;2025;"Robin";@RobinsAviary
|
||||
shapes;shapes_ball_physics;★★☆☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||
shapes;shapes_penrose_tile;★★★★;5.5;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||
textures;textures_logo_raylib;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_srcrec_dstrec;★★★☆;1.3;1.3;2015;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_image_drawing;★★☆☆;1.4;1.4;2016;2025;"Ramon Santamaria";@raysan5
|
||||
@ -113,8 +117,10 @@ textures;textures_gif_player;★★★☆;4.2;4.2;2021;2025;"Ramon Santamaria";@
|
||||
textures;textures_image_kernel;★★★★;1.3;1.3;2015;2025;"Karim Salem";@kimo-s
|
||||
textures;textures_image_channel;★★☆☆;5.5;5.5;2024;2025;"Bruno Cabral";@brccabral
|
||||
textures;textures_image_rotate;★★☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
textures;textures_screen_buffer;★★☆☆;5.5;5.5;2014;2025;"Agnis Aldins";@nezvers
|
||||
textures;textures_screen_buffer;★★☆☆;5.5;5.5;2025;2025;"Agnis Aldiņš";@nezvers
|
||||
textures;textures_textured_curve;★★★☆;4.5;4.5;2022;2025;"Jeffery Myers";@JeffM2501
|
||||
textures;textures_sprite_stacking;★★☆☆;5.6-dev;6.0;2025;2025;"Robin";@RobinsAviary
|
||||
textures;textures_cellular_automata;★★☆☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
text;text_sprite_fonts;★☆☆☆;1.7;3.7;2017;2025;"Ramon Santamaria";@raysan5
|
||||
text;text_font_spritefont;★☆☆☆;1.0;1.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
text;text_font_filters;★★☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
@ -130,6 +136,7 @@ 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_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
|
||||
text;text_strings_management;★★★☆;5.6-dev;5.6-dev;2025;2025;"David Buzatto";@davidbuzatto
|
||||
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_box_collisions;★☆☆☆;1.3;3.5;2015;2025;"Ramon Santamaria";@raysan5
|
||||
@ -156,6 +163,7 @@ models;models_tesseract_view;★★☆☆;5.6-dev;5.6-dev;2024;2025;"Timothy van
|
||||
models;models_basic_voxel;★★☆☆;5.5;5.5;2025;2025;"Tim Little";@timlittle
|
||||
models;models_rotating_cube;★☆☆☆;5.6-dev;5.6-dev;2025;2025;"Jopestpe";@jopestpe
|
||||
models;models_decals;★★★★;5.6-dev;5.6-dev;2025;2025;"JP Mortiboys";@themushroompirates
|
||||
models;models_directional_billboard;★★☆☆;5.6-dev;5.6;2025;2025;"Robin";@RobinsAviary
|
||||
shaders;shaders_ascii_rendering;★★☆☆;5.5;5.6;2025;2025;"Maicon Santana";@maiconpintoabreu
|
||||
shaders;shaders_basic_lighting;★★★★;3.0;4.2;2019;2025;"Chris Camacho";@chriscamacho
|
||||
shaders;shaders_model_shader;★★☆☆;1.3;3.7;2014;2025;"Ramon Santamaria";@raysan5
|
||||
@ -188,6 +196,7 @@ shaders;shaders_basic_pbr;★★★★;5.0;5.5;2023;2025;"Afan OLOVCIC";@_DevDad
|
||||
shaders;shaders_lightmap_rendering;★★★☆;4.5;4.5;2019;2025;"Jussi Viitala";@nullstare
|
||||
shaders;shaders_rounded_rectangle;★★★☆;5.5;5.5;2025;2025;"Anstro Pleuton";@anstropleuton
|
||||
shaders;shaders_depth_rendering;★★★☆;5.6-dev;5.6-dev;2025;2025;"Luís Almeida";@luis605
|
||||
shaders;shaders_game_of_life;★★★☆;5.6;5.6;2025;2025;"Jordi Santonja";@JordSant
|
||||
audio;audio_module_playing;★☆☆☆;1.5;3.5;2016;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_music_stream;★☆☆☆;1.3;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_raw_stream;★★★☆;1.6;4.2;2015;2025;"Ramon Santamaria";@raysan5
|
||||
@ -196,6 +205,7 @@ audio;audio_mixed_processor;★★★★;4.2;4.2;2023;2025;"hkc";@hatkidchan
|
||||
audio;audio_stream_effects;★★★★;4.2;5.0;2022;2025;"Ramon Santamaria";@raysan5
|
||||
audio;audio_sound_multi;★★☆☆;5.0;5.0;2023;2025;"Jeffery Myers";@JeffM2501
|
||||
audio;audio_sound_positioning;★★☆☆;5.5;5.5;2025;2025;"Le Juez Victor";@Bigfoot71
|
||||
audio;audio_spectrum_visualizer;★★★☆;6.0;5.6-dev;2025;2025;"IANN";@meisei4
|
||||
others;rlgl_standalone;★★★★;1.6;4.0;2014;2025;"Ramon Santamaria";@raysan5
|
||||
others;rlgl_compute_shader;★★★★;4.0;4.0;2021;2025;"Teddy Astie";@tsnake41
|
||||
others;easings_testbed;★★★☆;2.5;3.0;2019;2025;"Juan Miguel López";@flashback-fx
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
* 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)
|
||||
* Copyright (c) 2025 Robin (@RobinsAviary)
|
||||
* Killbot art by patvanmackelberg https://opengameart.org/content/killbot-8-directional under CC0
|
||||
*
|
||||
********************************************************************************************/
|
||||
@ -62,7 +62,7 @@ int main(void)
|
||||
anim_timer += GetFrameTime();
|
||||
|
||||
// Update frame index after a certain amount of time (half a second)
|
||||
if (anim_timer > 0.5f)
|
||||
if (anim_timer > 0.5f)
|
||||
{
|
||||
anim_timer = 0.0f;
|
||||
anim += 1;
|
||||
|
||||
@ -35,171 +35,157 @@
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
const char *voxFileNames[] = {
|
||||
"resources/models/vox/chr_knight.vox",
|
||||
"resources/models/vox/chr_sword.vox",
|
||||
"resources/models/vox/monu9.vox",
|
||||
"resources/models/vox/fez.vox"
|
||||
};
|
||||
const char *voxFileNames[] = {
|
||||
"resources/models/vox/chr_knight.vox",
|
||||
"resources/models/vox/chr_sword.vox",
|
||||
"resources/models/vox/monu9.vox",
|
||||
"resources/models/vox/fez.vox"
|
||||
};
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - loading vox");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - loading vox");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
|
||||
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 (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
|
||||
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 (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
// Load MagicaVoxel files
|
||||
Model models[MAX_VOX_FILES] = { 0 };
|
||||
// Load MagicaVoxel files
|
||||
Model models[MAX_VOX_FILES] = { 0 };
|
||||
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++)
|
||||
{
|
||||
// Load VOX file and measure time
|
||||
double t0 = GetTime()*1000.0;
|
||||
models[i] = LoadModel(voxFileNames[i]);
|
||||
double t1 = GetTime()*1000.0;
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++)
|
||||
{
|
||||
// Load VOX file and measure time
|
||||
double t0 = GetTime()*1000.0;
|
||||
models[i] = LoadModel(voxFileNames[i]);
|
||||
double t1 = GetTime()*1000.0;
|
||||
|
||||
TraceLog(LOG_WARNING, TextFormat("[%s] File loaded in %.3f ms", voxFileNames[i], t1 - t0));
|
||||
TraceLog(LOG_INFO, TextFormat("[%s] Model file loaded in %.3f ms", voxFileNames[i], t1 - t0));
|
||||
|
||||
// Compute model translation matrix to center model on draw position (0, 0 , 0)
|
||||
BoundingBox bb = GetModelBoundingBox(models[i]);
|
||||
Vector3 center = { 0 };
|
||||
center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));
|
||||
center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));
|
||||
// Compute model translation matrix to center model on draw position (0, 0 , 0)
|
||||
BoundingBox bb = GetModelBoundingBox(models[i]);
|
||||
Vector3 center = { 0 };
|
||||
center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));
|
||||
center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));
|
||||
|
||||
Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
|
||||
models[i].transform = matTranslate;
|
||||
}
|
||||
Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
|
||||
models[i].transform = matTranslate;
|
||||
}
|
||||
|
||||
int currentModel = 0;
|
||||
int currentModel = 0;
|
||||
Vector3 modelpos = { 0 };
|
||||
Vector3 camerarot = { 0 };
|
||||
|
||||
// Load voxel shader
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION));
|
||||
// Load voxel shader
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION));
|
||||
|
||||
// Get some required shader locations
|
||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||
// NOTE: "matModel" location name is automatically assigned on shader loading,
|
||||
// no need to get the location again if using that uniform name
|
||||
//shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
|
||||
// Get some required shader locations
|
||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||
// NOTE: "matModel" location name is automatically assigned on shader loading,
|
||||
// no need to get the location again if using that uniform name
|
||||
//shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
|
||||
|
||||
// Ambient light level (some basic lighting)
|
||||
int ambientLoc = GetShaderLocation(shader, "ambient");
|
||||
SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4);
|
||||
// Ambient light level (some basic lighting)
|
||||
int ambientLoc = GetShaderLocation(shader, "ambient");
|
||||
SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4);
|
||||
|
||||
// Assign out lighting shader to model
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++)
|
||||
{
|
||||
Model m = models[i];
|
||||
for (int j = 0; j < m.materialCount; j++)
|
||||
{
|
||||
m.materials[j].shader = shader;
|
||||
}
|
||||
}
|
||||
// Assign out lighting shader to model
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++)
|
||||
{
|
||||
for (int j = 0; j < models[i].materialCount; j++) models[i].materials[j].shader = shader;
|
||||
}
|
||||
|
||||
// Create lights
|
||||
Light lights[MAX_LIGHTS] = { 0 };
|
||||
lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader);
|
||||
// Create lights
|
||||
Light lights[MAX_LIGHTS] = { 0 };
|
||||
lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader);
|
||||
lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader);
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
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_MIDDLE))
|
||||
{
|
||||
const Vector2 mouseDelta = GetMouseDelta();
|
||||
camerarot.x = mouseDelta.x*0.05f;
|
||||
camerarot.y = mouseDelta.y*0.05f;
|
||||
}
|
||||
else
|
||||
{
|
||||
camerarot.x = 0;
|
||||
camerarot.y = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
Vector3 modelpos = { 0 };
|
||||
Vector3 camerarot = { 0 };
|
||||
UpdateCameraPro(&camera,
|
||||
(Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward
|
||||
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left
|
||||
0.0f }, // Move up-down
|
||||
camerarot, // Camera rotation
|
||||
GetMouseWheelMove()*-2.0f); // Move to target (zoom)
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))
|
||||
{
|
||||
const Vector2 mouseDelta = GetMouseDelta();
|
||||
camerarot.x = mouseDelta.x*0.05f;
|
||||
camerarot.y = mouseDelta.y*0.05f;
|
||||
}
|
||||
else
|
||||
{
|
||||
camerarot.x = 0;
|
||||
camerarot.y = 0;
|
||||
}
|
||||
// Cycle between models on mouse click
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1)%MAX_VOX_FILES;
|
||||
|
||||
UpdateCameraPro(&camera,
|
||||
(Vector3) {
|
||||
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
|
||||
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
|
||||
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
|
||||
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
|
||||
0.0f // Move up-down
|
||||
},
|
||||
camerarot,
|
||||
GetMouseWheelMove()*-2.0f); // Move to target (zoom)
|
||||
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
|
||||
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
|
||||
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
|
||||
|
||||
// Cycle between models on mouse click
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES;
|
||||
// Update light values (actually, only enable/disable them)
|
||||
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
|
||||
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
|
||||
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
// Update light values (actually, only enable/disable them)
|
||||
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]);
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
// Draw 3D model
|
||||
BeginMode3D(camera);
|
||||
DrawModel(models[currentModel], modelpos, 1.0f, WHITE);
|
||||
DrawGrid(10, 1.0);
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
// Draw spheres to show where the lights are
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color);
|
||||
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f));
|
||||
}
|
||||
EndMode3D();
|
||||
|
||||
// Draw 3D model
|
||||
BeginMode3D(camera);
|
||||
// Display info
|
||||
DrawRectangle(10, 40, 340, 70, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines(10, 40, 340, 70, Fade(DARKBLUE, 0.5f));
|
||||
DrawText("- MOUSE LEFT BUTTON: CYCLE VOX MODELS", 20, 50, 10, BLUE);
|
||||
DrawText("- MOUSE MIDDLE BUTTON: ZOOM OR ROTATE CAMERA", 20, 70, 10, BLUE);
|
||||
DrawText("- UP-DOWN-LEFT-RIGHT KEYS: MOVE CAMERA", 20, 90, 10, BLUE);
|
||||
DrawText(TextFormat("Model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
|
||||
|
||||
DrawModel(models[currentModel], modelpos, 1.0f, WHITE);
|
||||
DrawGrid(10, 1.0);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// Draw spheres to show where the lights are
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, lights[i].color);
|
||||
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lights[i].color, 0.3f));
|
||||
}
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Unload models data (GPU VRAM)
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
|
||||
|
||||
EndMode3D();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Display info
|
||||
DrawRectangle(10, 400, 340, 60, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines(10, 400, 340, 60, Fade(DARKBLUE, 0.5f));
|
||||
DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);
|
||||
DrawText("MOUSE MIDDLE BUTTON to ZOOM OR ROTATE CAMERA", 40, 420, 10, BLUE);
|
||||
DrawText("UP-DOWN-LEFT-RIGHT KEYS to MOVE CAMERA", 40, 430, 10, BLUE);
|
||||
DrawText(TextFormat("File: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Unload models data (GPU VRAM)
|
||||
for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ int main(void)
|
||||
Mesh mesh = GenMeshPoints(numPoints);
|
||||
Model model = LoadModelFromMesh(mesh);
|
||||
|
||||
//SetTargetFPS(60);
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
@ -92,15 +92,12 @@ int main(void)
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(BLACK);
|
||||
|
||||
BeginMode3D(camera);
|
||||
|
||||
// The new method only uploads the points once to the GPU
|
||||
if (useDrawModelPoints)
|
||||
{
|
||||
DrawModelPoints(model, position, 1.0f, WHITE);
|
||||
}
|
||||
if (useDrawModelPoints) DrawModelPoints(model, position, 1.0f, WHITE);
|
||||
else
|
||||
{
|
||||
// The old method must continually draw the "points" (lines)
|
||||
@ -124,17 +121,16 @@ int main(void)
|
||||
|
||||
// Draw a unit sphere for reference
|
||||
DrawSphereWires(position, 1.0f, 10, 10, YELLOW);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
// Draw UI text
|
||||
DrawText(TextFormat("Point Count: %d", numPoints), 20, screenHeight - 50, 40, WHITE);
|
||||
DrawText("Up - increase points", 20, 70, 20, WHITE);
|
||||
DrawText("Down - decrease points", 20, 100, 20, WHITE);
|
||||
DrawText("Space - drawing function", 20, 130, 20, WHITE);
|
||||
DrawText(TextFormat("Point Count: %d", numPoints), 10, screenHeight - 50, 40, WHITE);
|
||||
DrawText("UP - Increase points", 10, 40, 20, WHITE);
|
||||
DrawText("DOWN - Decrease points", 10, 70, 20, WHITE);
|
||||
DrawText("SPACE - Drawing function", 10, 100, 20, WHITE);
|
||||
|
||||
if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 20, 160, 20, GREEN);
|
||||
else DrawText("Using: DrawPoint3D()", 20, 160, 20, RED);
|
||||
if (useDrawModelPoints) DrawText("Using: DrawModelPoints()", 10, 130, 20, GREEN);
|
||||
else DrawText("Using: DrawPoint3D()", 10, 130, 20, RED);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* 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,
|
||||
@ -48,7 +48,7 @@ int main(void)
|
||||
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
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -59,7 +59,7 @@ int main(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
rotation += 1.0f;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
@ -67,13 +67,13 @@ int main(void)
|
||||
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 },
|
||||
|
||||
// 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);
|
||||
|
||||
@ -54,7 +54,8 @@ int main(void)
|
||||
Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f);
|
||||
Model skybox = LoadModelFromMesh(cube);
|
||||
|
||||
// Set this to true to use an HDR Texture, Note that raylib must be built with HDR Support for this to work SUPPORT_FILEFORMAT_HDR
|
||||
// Set this to true to use an HDR Texture
|
||||
// NOTE: raylib must be built with HDR Support for this to work: SUPPORT_FILEFORMAT_HDR
|
||||
bool useHDR = false;
|
||||
|
||||
// Load skybox shader and set required locations
|
||||
@ -63,8 +64,8 @@ int main(void)
|
||||
TextFormat("resources/shaders/glsl%i/skybox.fs", GLSL_VERSION));
|
||||
|
||||
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "environmentMap"), (int[1]){ MATERIAL_MAP_CUBEMAP }, SHADER_UNIFORM_INT);
|
||||
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "doGamma"), (int[1]) { useHDR ? 1 : 0 }, SHADER_UNIFORM_INT);
|
||||
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ useHDR ? 1 : 0 }, SHADER_UNIFORM_INT);
|
||||
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "doGamma"), (int[1]){ useHDR? 1 : 0 }, SHADER_UNIFORM_INT);
|
||||
SetShaderValue(skybox.materials[0].shader, GetShaderLocation(skybox.materials[0].shader, "vflipped"), (int[1]){ useHDR? 1 : 0 }, SHADER_UNIFORM_INT);
|
||||
|
||||
// Load cubemap shader and setup required shader locations
|
||||
Shader shdrCubemap = LoadShader(TextFormat("resources/shaders/glsl%i/cubemap.vs", GLSL_VERSION),
|
||||
@ -91,9 +92,11 @@ int main(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
Image img = LoadImage("resources/skybox.png");
|
||||
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT); // CUBEMAP_LAYOUT_PANORAMA
|
||||
UnloadImage(img);
|
||||
// TODO: WARNING: On PLATFORM_WEB it requires a big amount of memory to process input image
|
||||
// and generate the required cubemap image to be passed to rlLoadTextureCubemap()
|
||||
Image image = LoadImage("resources/skybox.png");
|
||||
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
|
||||
UnloadImage(image);
|
||||
}
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
@ -132,9 +135,9 @@ int main(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
Image img = LoadImage(droppedFiles.paths[0]);
|
||||
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(img, CUBEMAP_LAYOUT_AUTO_DETECT);
|
||||
UnloadImage(img);
|
||||
Image image = LoadImage(droppedFiles.paths[0]);
|
||||
skybox.materials[0].maps[MATERIAL_MAP_CUBEMAP].texture = LoadTextureCubemap(image, CUBEMAP_LAYOUT_AUTO_DETECT);
|
||||
UnloadImage(image);
|
||||
}
|
||||
|
||||
TextCopy(skyboxFileName, droppedFiles.paths[0]);
|
||||
|
||||
@ -221,7 +221,7 @@ int main(void)
|
||||
}
|
||||
|
||||
|
||||
// NoEase function, used when "no easing" is selected for any axis
|
||||
// NoEase function, used when "no easing" is selected for any axis
|
||||
// It just ignores all parameters besides b
|
||||
static float NoEase(float t, float b, float c, float d)
|
||||
{
|
||||
|
||||
BIN
examples/shaders/resources/game_of_life/acorn.png
Normal file
|
After Width: | Height: | Size: 218 B |
BIN
examples/shaders/resources/game_of_life/breeder.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/shaders/resources/game_of_life/glider.png
Normal file
|
After Width: | Height: | Size: 216 B |
BIN
examples/shaders/resources/game_of_life/glider_gun.png
Normal file
|
After Width: | Height: | Size: 291 B |
BIN
examples/shaders/resources/game_of_life/oscillators.png
Normal file
|
After Width: | Height: | Size: 463 B |
BIN
examples/shaders/resources/game_of_life/puffer_train.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/shaders/resources/game_of_life/r_pentomino.png
Normal file
|
After Width: | Height: | Size: 213 B |
BIN
examples/shaders/resources/game_of_life/spaceships.png
Normal file
|
After Width: | Height: | Size: 828 B |
BIN
examples/shaders/resources/game_of_life/still_lifes.png
Normal file
|
After Width: | Height: | Size: 615 B |
44
examples/shaders/resources/shaders/glsl100/game_of_life.fs
Normal file
@ -0,0 +1,44 @@
|
||||
#version 100
|
||||
|
||||
precision highp float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Input size in pixels of the textures
|
||||
uniform vec2 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Size of one pixel in texture coordinates (from 0.0 to 1.0)
|
||||
float x = 1.0/resolution.x;
|
||||
float y = 1.0/resolution.y;
|
||||
|
||||
// Status of the current cell (1 = alive, 0 = dead)
|
||||
int origValue = (texture2D(texture0, fragTexCoord).r < 0.1)? 1 : 0;
|
||||
|
||||
// Sum of alive neighbors
|
||||
int sumValue = (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right
|
||||
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right
|
||||
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right
|
||||
|
||||
// Game of life rules:
|
||||
// Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise
|
||||
// Current cell goes from dead to alive when exactly 3 neighbors are alive
|
||||
if ((origValue == 1 && sumValue == 2) || sumValue == 3)
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black
|
||||
else
|
||||
gl_FragColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
#version 100
|
||||
|
||||
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
||||
#extension GL_EXT_frag_depth : enable // Extension required for writing depth
|
||||
|
||||
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
|
||||
#extension GL_EXT_frag_depth : enable //Extension required for writing depth
|
||||
#extension GL_OES_standard_derivatives : enable //Extension used for fwidth()
|
||||
|
||||
#define ZERO 0
|
||||
|
||||
precision mediump float; // Precision required for OpenGL ES2 (WebGL)
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
@ -17,8 +20,6 @@ uniform vec3 camPos;
|
||||
uniform vec3 camDir;
|
||||
uniform vec2 screenCenter;
|
||||
|
||||
#define ZERO 0
|
||||
|
||||
// SRC: https://learnopengl.com/Advanced-OpenGL/Depth-testing
|
||||
float CalcDepth(in vec3 rd, in float Idist)
|
||||
{
|
||||
@ -128,7 +129,7 @@ float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
|
||||
|
||||
float res = 1.0;
|
||||
float t = mint;
|
||||
for (int i=ZERO; i<24; i++)
|
||||
for (int i = ZERO; i < 24; i++)
|
||||
{
|
||||
float h = map(ro + rd*t).x;
|
||||
float s = clamp(8.0*h/t,0.0,1.0);
|
||||
@ -156,7 +157,7 @@ float calcAO(in vec3 pos, in vec3 nor)
|
||||
{
|
||||
float occ = 0.0;
|
||||
float sca = 1.0;
|
||||
for (int i=ZERO; i<5; i++)
|
||||
for (int i = ZERO; i < 5; i++)
|
||||
{
|
||||
float h = 0.01 + 0.12*float(i)/4.0;
|
||||
float d = map(pos + h*nor).x;
|
||||
@ -257,7 +258,8 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
return vec4(vec3(clamp(col,0.0,1.0)),t);
|
||||
}
|
||||
|
||||
vec3 CalcRayDir(vec2 nCoord){
|
||||
vec3 CalcRayDir(vec2 nCoord)
|
||||
{
|
||||
vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0)));
|
||||
vec3 vertical = normalize(cross(horizontal,camDir));
|
||||
return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y);
|
||||
@ -287,6 +289,7 @@ void main()
|
||||
color = res.xyz;
|
||||
depth = CalcDepth(rd,res.w);
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(color , 1.0);
|
||||
gl_FragDepthEXT = depth;
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
42
examples/shaders/resources/shaders/glsl120/game_of_life.fs
Normal file
@ -0,0 +1,42 @@
|
||||
#version 120
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Input size in pixels of the textures
|
||||
uniform vec2 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Size of one pixel in texture coordinates (from 0.0 to 1.0)
|
||||
float x = 1.0/resolution.x;
|
||||
float y = 1.0/resolution.y;
|
||||
|
||||
// Status of the current cell (1 = alive, 0 = dead)
|
||||
int origValue = (texture2D(texture0, fragTexCoord).r < 0.1)? 1 : 0;
|
||||
|
||||
// Sum of alive neighbors
|
||||
int sumValue = (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right
|
||||
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right
|
||||
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom
|
||||
sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right
|
||||
|
||||
// Game of life rules:
|
||||
// Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise
|
||||
// Current cell goes from dead to alive when exactly 3 neighbors are alive
|
||||
if (((origValue == 1) && (sumValue == 2)) || sumValue == 3)
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black
|
||||
else
|
||||
gl_FragColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE
|
||||
}
|
||||
45
examples/shaders/resources/shaders/glsl330/game_of_life.fs
Normal file
@ -0,0 +1,45 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// Input size in pixels of the textures
|
||||
uniform vec2 resolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Size of one pixel in texture coordinates (from 0.0 to 1.0)
|
||||
float x = 1.0/resolution.x;
|
||||
float y = 1.0/resolution.y;
|
||||
|
||||
// Status of the current cell (1 = alive, 0 = dead)
|
||||
int origValue = (texture(texture0, fragTexCoord).r < 0.1)? 1 : 0;
|
||||
|
||||
// Sum of alive neighbors
|
||||
int sumValue = (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left
|
||||
sumValue += (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top
|
||||
sumValue += (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right
|
||||
|
||||
sumValue += (texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left
|
||||
sumValue += (texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right
|
||||
|
||||
sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left
|
||||
sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom
|
||||
sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right
|
||||
|
||||
// Game of life rules:
|
||||
// Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise
|
||||
// Current cell goes from dead to alive when exactly 3 neighbors are alive
|
||||
if (((origValue == 1) && (sumValue == 2)) || sumValue == 3)
|
||||
finalColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black
|
||||
else
|
||||
finalColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE
|
||||
}
|
||||
@ -9,7 +9,7 @@ uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Output fragment color
|
||||
//out vec4 finalColor;
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
@ -17,6 +17,6 @@ void main()
|
||||
{
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
|
||||
gl_FragColor = texelColor*colDiffuse*fragColor;
|
||||
gl_FragDepth = gl_FragCoord.z;
|
||||
finalColor = texelColor*colDiffuse*fragColor;
|
||||
gl_FragDepth = finalColor.z;
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
# version 330
|
||||
|
||||
#define ZERO 0
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
@ -13,10 +15,12 @@ uniform vec3 camPos;
|
||||
uniform vec3 camDir;
|
||||
uniform vec2 screenCenter;
|
||||
|
||||
#define ZERO 0
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// https://learnopengl.com/Advanced-OpenGL/Depth-testing
|
||||
float CalcDepth(in vec3 rd, in float Idist){
|
||||
float CalcDepth(in vec3 rd, in float Idist)
|
||||
{
|
||||
float local_z = dot(normalize(camDir),rd)*Idist;
|
||||
return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01);
|
||||
}
|
||||
@ -26,15 +30,13 @@ float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
|
||||
{
|
||||
p.x = abs(p.x);
|
||||
float l = length(p.xy);
|
||||
p.xy = mat2(-c.x, c.y,
|
||||
c.y, c.x)*p.xy;
|
||||
p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
|
||||
(p.x>0.0)?p.y:l);
|
||||
p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
|
||||
p.xy = mat2(-c.x, c.y, c.y, c.x)*p.xy;
|
||||
p.xy = vec2(((p.y > 0.0) || (p.x > 0.0))? p.x : l*sign(-c.x), (p.x>0.0)? p.y : l);
|
||||
p.xy = vec2(p.x, abs(p.y - r)) - vec2(le, 0.0);
|
||||
|
||||
vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
|
||||
vec2 q = vec2(length(max(p.xy, 0.0)) + min(0.0, max(p.x, p.y)), p.z);
|
||||
vec2 d = abs(q) - w;
|
||||
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
|
||||
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
|
||||
}
|
||||
|
||||
// r = sphere's radius
|
||||
@ -44,17 +46,16 @@ float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
|
||||
{
|
||||
// Six way symetry Transformation
|
||||
vec3 ap = abs(p);
|
||||
if (ap.x < max(ap.y, ap.z)){
|
||||
if (ap.x < max(ap.y, ap.z))
|
||||
{
|
||||
if (ap.y < ap.z) ap.xz = ap.zx;
|
||||
else ap.xy = ap.yx;
|
||||
}
|
||||
|
||||
vec2 q = vec2(length(ap.yz), ap.x);
|
||||
|
||||
float w = sqrt(r*r-h*h);
|
||||
|
||||
return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) :
|
||||
abs(length(q)-r)) - t;
|
||||
return ((h*q.x < w*q.y)? length(q - vec2(w, h)) : abs(length(q) - r)) - t;
|
||||
}
|
||||
|
||||
// https://iquilezles.org/articles/boxfunctions
|
||||
@ -65,44 +66,47 @@ vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad)
|
||||
vec3 k = abs(m)*rad;
|
||||
vec3 t1 = -n - k;
|
||||
vec3 t2 = -n + k;
|
||||
return vec2(max(max(t1.x, t1.y), t1.z),
|
||||
min(min(t2.x, t2.y), t2.z));
|
||||
|
||||
return vec2(max(max(t1.x, t1.y), t1.z), min(min(t2.x, t2.y), t2.z));
|
||||
}
|
||||
|
||||
vec2 opU(vec2 d1, vec2 d2)
|
||||
{
|
||||
return (d1.x<d2.x) ? d1 : d2;
|
||||
return (d1.x < d2.x)? d1 : d2;
|
||||
}
|
||||
|
||||
vec2 map(in vec3 pos){
|
||||
vec2 res = vec2(sdHorseshoe( pos-vec3(-1.0,0.08, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5) ;
|
||||
res = opU(res, vec2(sdSixWayCutHollowSphere( pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5)) ;
|
||||
vec2 map(in vec3 pos)
|
||||
{
|
||||
vec2 res = vec2(sdHorseshoe(pos - vec3(-1.0, 0.08, 1.0), vec2(cos(1.3), sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5);
|
||||
res = opU(res, vec2(sdSixWayCutHollowSphere(pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// https://www.shadertoy.com/view/Xds3zN
|
||||
vec2 raycast(in vec3 ro, in vec3 rd){
|
||||
vec2 res = vec2(-1.0,-1.0);
|
||||
vec2 raycast(in vec3 ro, in vec3 rd)
|
||||
{
|
||||
vec2 res = vec2(-1.0, -1.0);
|
||||
|
||||
float tmin = 1.0;
|
||||
float tmax = 20.0;
|
||||
|
||||
// raytrace floor plane
|
||||
float tp1 = (-ro.y)/rd.y;
|
||||
if (tp1>0.0)
|
||||
if (tp1 > 0.0)
|
||||
{
|
||||
tmax = min(tmax, tp1);
|
||||
res = vec2(tp1, 1.0);
|
||||
}
|
||||
|
||||
float t = tmin;
|
||||
for (int i=0; i<70 ; i++)
|
||||
for (int i = 0; i < 70 ; i++)
|
||||
{
|
||||
if (t>tmax) break;
|
||||
vec2 h = map(ro+rd*t);
|
||||
if (abs(h.x)<(0.0001*t))
|
||||
if (t > tmax) break;
|
||||
vec2 h = map(ro + rd*t);
|
||||
if (abs(h.x )< (0.0001*t))
|
||||
{
|
||||
res = vec2(t,h.y);
|
||||
res = vec2(t, h.y);
|
||||
break;
|
||||
}
|
||||
t += h.x;
|
||||
@ -111,28 +115,28 @@ vec2 raycast(in vec3 ro, in vec3 rd){
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// https://iquilezles.org/articles/rmshadows
|
||||
float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
|
||||
{
|
||||
// bounding volume
|
||||
float tp = (0.8-ro.y)/rd.y; if (tp>0.0) tmax = min(tmax, tp);
|
||||
float tp = (0.8 - ro.y)/rd.y; if (tp > 0.0) tmax = min(tmax, tp);
|
||||
|
||||
float res = 1.0;
|
||||
float t = mint;
|
||||
for (int i=ZERO; i<24; i++)
|
||||
for (int i = ZERO; i < 24; i++)
|
||||
{
|
||||
float h = map(ro + rd*t).x;
|
||||
float s = clamp(8.0*h/t,0.0,1.0);
|
||||
float s = clamp(8.0*h/t, 0.0, 1.0);
|
||||
res = min(res, s);
|
||||
t += clamp(h, 0.01, 0.2);
|
||||
if (res<0.004 || t>tmax) break;
|
||||
if ((res < 0.004) || (t > tmax)) break;
|
||||
}
|
||||
|
||||
res = clamp(res, 0.0, 1.0);
|
||||
|
||||
return res*res*(3.0-2.0*res);
|
||||
}
|
||||
|
||||
|
||||
// https://iquilezles.org/articles/normalsSDF
|
||||
vec3 calcNormal(in vec3 pos)
|
||||
{
|
||||
@ -148,7 +152,7 @@ float calcAO(in vec3 pos, in vec3 nor)
|
||||
{
|
||||
float occ = 0.0;
|
||||
float sca = 1.0;
|
||||
for (int i=ZERO; i<5; i++)
|
||||
for (int i = ZERO; i < 5; i++)
|
||||
{
|
||||
float h = 0.01 + 0.12*float(i)/4.0;
|
||||
float d = map(pos + h*nor).x;
|
||||
@ -156,6 +160,7 @@ float calcAO(in vec3 pos, in vec3 nor)
|
||||
sca *= 0.95;
|
||||
if (occ>0.35) break;
|
||||
}
|
||||
|
||||
return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y);
|
||||
}
|
||||
|
||||
@ -165,9 +170,9 @@ float checkersGradBox(in vec2 p)
|
||||
// filter kernel
|
||||
vec2 w = fwidth(p) + 0.001;
|
||||
// analytical integral (box filter)
|
||||
vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
|
||||
vec2 i = 2.0*(abs(fract((p - 0.5*w)*0.5)-0.5) - abs(fract((p + 0.5*w)*0.5) - 0.5))/w;
|
||||
// xor pattern
|
||||
return 0.5 - 0.5*i.x*i.y;
|
||||
return (0.5 - 0.5*i.x*i.y);
|
||||
}
|
||||
|
||||
// https://www.shadertoy.com/view/tdS3DG
|
||||
@ -180,7 +185,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
vec2 res = raycast(ro,rd);
|
||||
float t = res.x;
|
||||
float m = res.y;
|
||||
if (m>-0.5)
|
||||
if (m > -0.5)
|
||||
{
|
||||
vec3 pos = ro + t*rd;
|
||||
vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
|
||||
@ -190,7 +195,7 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
|
||||
float ks = 1.0;
|
||||
|
||||
if (m<1.5)
|
||||
if (m < 1.5)
|
||||
{
|
||||
float f = checkersGradBox(3.0*pos.xz);
|
||||
col = 0.15 + f*vec3(0.05);
|
||||
@ -207,14 +212,14 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
vec3 lig = normalize(vec3(-0.5, 0.4, -0.6));
|
||||
vec3 hal = normalize(lig-rd);
|
||||
float dif = clamp(dot(nor, lig), 0.0, 1.0);
|
||||
//if (dif>0.0001)
|
||||
//if (dif>0.0001)
|
||||
dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
|
||||
float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0);
|
||||
spe *= dif;
|
||||
spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
|
||||
//spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0);
|
||||
lin += col*2.20*dif*vec3(1.30,1.00,0.70);
|
||||
lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks;
|
||||
lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks;
|
||||
}
|
||||
// sky
|
||||
{
|
||||
@ -249,7 +254,8 @@ vec4 render(in vec3 ro, in vec3 rd)
|
||||
return vec4(vec3(clamp(col,0.0,1.0)),t);
|
||||
}
|
||||
|
||||
vec3 CalcRayDir(vec2 nCoord){
|
||||
vec3 CalcRayDir(vec2 nCoord)
|
||||
{
|
||||
vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0)));
|
||||
vec3 vertical = normalize(cross(horizontal,camDir));
|
||||
return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y);
|
||||
@ -279,6 +285,7 @@ void main()
|
||||
color = res.xyz;
|
||||
depth = CalcDepth(rd,res.w);
|
||||
}
|
||||
gl_FragColor = vec4(color , 1.0);
|
||||
|
||||
finalColor = vec4(color , 1.0);
|
||||
gl_FragDepth = depth;
|
||||
}
|
||||
@ -87,15 +87,15 @@ int main(void)
|
||||
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 },
|
||||
DrawTextureRec(target.texture,
|
||||
(Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height },
|
||||
(Vector2){ 0, 0 }, WHITE);
|
||||
EndShaderMode();
|
||||
|
||||
|
||||
@ -242,7 +242,7 @@ int main(void)
|
||||
SetShaderValue(shader, emissiveColorLoc, &carEmissiveColor, SHADER_UNIFORM_VEC4);
|
||||
float emissiveIntensity = 0.01f;
|
||||
SetShaderValue(shader, emissiveIntensityLoc, &emissiveIntensity, SHADER_UNIFORM_FLOAT);
|
||||
|
||||
|
||||
// Set old car metallic and roughness values
|
||||
SetShaderValue(shader, metallicValueLoc, &car.materials[0].maps[MATERIAL_MAP_METALNESS].value, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(shader, roughnessValueLoc, &car.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value, SHADER_UNIFORM_FLOAT);
|
||||
@ -252,11 +252,11 @@ int main(void)
|
||||
// Draw spheres to show the lights positions
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
Color lightColor = (Color){
|
||||
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) };
|
||||
(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);
|
||||
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(lightColor, 0.3f));
|
||||
|
||||
@ -138,7 +138,7 @@ int main(void)
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < MAX_TEXTURES; ++i) UnloadTexture(texture[i]);
|
||||
for (int i = 0; i < MAX_TEXTURES; i++) UnloadTexture(texture[i]);
|
||||
UnloadShader(shdrColorCorrection);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
|
||||
353
examples/shaders/shaders_game_of_life.c
Normal file
@ -0,0 +1,353 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shaders] example - game of life
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Jordi Santonja (@JordSant) 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 Jordi Santonja (@JordSant)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h" // Required for GUI controls
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Interaction mode
|
||||
typedef enum {
|
||||
MODE_RUN = 0,
|
||||
MODE_PAUSE,
|
||||
MODE_DRAW,
|
||||
} InteractionMode;
|
||||
|
||||
// Struct to store example preset patterns
|
||||
typedef struct {
|
||||
char *name;
|
||||
Vector2 position;
|
||||
} PresetPattern;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Functions declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void FreeImageToDraw(Image **imageToDraw);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - game of life");
|
||||
|
||||
const int menuWidth = 100;
|
||||
const int windowWidth = screenWidth - menuWidth;
|
||||
const int windowHeight = screenHeight;
|
||||
|
||||
const int worldWidth = 2048;
|
||||
const int worldHeight = 2048;
|
||||
|
||||
const int randomTiles = 8; // Random preset: divide the world to compute random points in each tile
|
||||
|
||||
const Rectangle worldRectSource = { 0, 0, (float)worldWidth, (float)-worldHeight };
|
||||
const Rectangle worldRectDest = { 0, 0, (float)worldWidth, (float)worldHeight };
|
||||
const Rectangle textureOnScreen = { 0, 0, (float)windowWidth, (float)windowHeight };
|
||||
|
||||
const PresetPattern presetPatterns[] = {
|
||||
{ "Glider", { 0.5f, 0.5f } }, { "R-pentomino", { 0.5f, 0.5f } }, { "Acorn", { 0.5f,0.5f } },
|
||||
{ "Spaceships", { 0.1f, 0.5f } }, { "Still lifes", { 0.5f, 0.5f } }, { "Oscillators", { 0.5f, 0.5f } },
|
||||
{ "Puffer train", { 0.1f, 0.5f } }, { "Glider Gun", { 0.2f, 0.2f } }, { "Breeder", { 0.1f, 0.5f } },
|
||||
{ "Random", { 0.5f, 0.5f } }
|
||||
};
|
||||
|
||||
const int numberOfPresets = sizeof(presetPatterns)/sizeof(presetPatterns[0]);
|
||||
|
||||
int zoom = 1;
|
||||
float offsetX = (worldWidth - windowWidth)/2.0f; // Centered on window
|
||||
float offsetY = (worldHeight - windowHeight)/2.0f; // Centered on window
|
||||
int framesPerStep = 1;
|
||||
int frame = 0;
|
||||
|
||||
int preset = -1; // No button pressed for preset
|
||||
int mode = MODE_RUN; // Starting mode: running
|
||||
bool buttonZoomIn = false; // Button states: false not pressed
|
||||
bool buttonZomOut = false;
|
||||
bool buttonFaster = false;
|
||||
bool buttonSlower = false;
|
||||
|
||||
// Load shader
|
||||
Shader shdrGameOfLife = LoadShader(0, TextFormat("resources/shaders/glsl%i/game_of_life.fs", GLSL_VERSION));
|
||||
|
||||
// Set shader uniform size of the world
|
||||
int resolutionLoc = GetShaderLocation(shdrGameOfLife, "resolution");
|
||||
const float resolution[2] = { (float)worldWidth, (float)worldHeight };
|
||||
SetShaderValue(shdrGameOfLife, resolutionLoc, resolution, SHADER_UNIFORM_VEC2);
|
||||
|
||||
// Define two textures: the current world and the previous world
|
||||
RenderTexture2D world1 = LoadRenderTexture(worldWidth, worldHeight);
|
||||
RenderTexture2D world2 = LoadRenderTexture(worldWidth, worldHeight);
|
||||
BeginTextureMode(world2);
|
||||
ClearBackground(RAYWHITE);
|
||||
EndTextureMode();
|
||||
|
||||
Image startPattern = LoadImage("resources/game_of_life/r_pentomino.png");
|
||||
UpdateTextureRec(world2.texture, (Rectangle){ worldWidth/2.0f, worldHeight/2.0f, (float)(startPattern.width), (float)(startPattern.height) }, startPattern.data);
|
||||
UnloadImage(startPattern);
|
||||
|
||||
// Pointers to the two textures, to be swapped
|
||||
RenderTexture2D *currentWorld = &world2;
|
||||
RenderTexture2D *previousWorld = &world1;
|
||||
|
||||
// Image to be used in DRAW mode, to be changed with mouse input
|
||||
Image *imageToDraw = NULL;
|
||||
|
||||
SetTargetFPS(60); // Set at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
frame++;
|
||||
|
||||
// Change zoom: both by buttons or by mouse wheel
|
||||
float mouseWheelMove = GetMouseWheelMove();
|
||||
if (buttonZoomIn || (buttonZomOut && (zoom > 1)) || (mouseWheelMove != 0.0f))
|
||||
{
|
||||
FreeImageToDraw(&imageToDraw); // Zoom change: free the image to draw to be recreated again
|
||||
|
||||
const float centerX = offsetX + (windowWidth/2.0f)/zoom;
|
||||
const float centerY = offsetY + (windowHeight/2.0f)/zoom;
|
||||
if (buttonZoomIn || (mouseWheelMove > 0.0f)) zoom *= 2;
|
||||
if ((buttonZomOut || (mouseWheelMove < 0.0f)) && (zoom > 1)) zoom /= 2;
|
||||
offsetX = centerX - (windowWidth/2.0f)/zoom;
|
||||
offsetY = centerY - (windowHeight/2.0f)/zoom;
|
||||
}
|
||||
|
||||
// Change speed: number of frames per step
|
||||
if (buttonFaster && framesPerStep > 1) framesPerStep--;
|
||||
if (buttonSlower) framesPerStep++;
|
||||
|
||||
// Mouse management
|
||||
if ((mode == MODE_RUN) || (mode == MODE_PAUSE))
|
||||
{
|
||||
FreeImageToDraw(&imageToDraw); // Free the image to draw: no longer needed in these modes
|
||||
|
||||
// Pan with mouse left button
|
||||
static Vector2 previousMousePosition = { 0.0f, 0.0f };
|
||||
const Vector2 mousePosition = GetMousePosition();
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && (mousePosition.x < windowWidth))
|
||||
{
|
||||
offsetX -= (mousePosition.x - previousMousePosition.x)/zoom;
|
||||
offsetY -= (mousePosition.y - previousMousePosition.y)/zoom;
|
||||
}
|
||||
previousMousePosition = mousePosition;
|
||||
}
|
||||
else // MODE_DRAW
|
||||
{
|
||||
const float offsetDecimalX = offsetX - floorf(offsetX);
|
||||
const float offsetDecimalY = offsetY - floorf(offsetY);
|
||||
int sizeInWorldX = (int)(ceilf((float)(windowWidth + offsetDecimalX*zoom)/zoom));
|
||||
int sizeInWorldY = (int)(ceilf((float)(windowHeight + offsetDecimalY*zoom)/zoom));
|
||||
if (offsetX + sizeInWorldX >= worldWidth) sizeInWorldX = worldWidth - (int)floorf(offsetX);
|
||||
if (offsetY + sizeInWorldY >= worldHeight) sizeInWorldY = worldHeight - (int)floorf(offsetY);
|
||||
|
||||
// Create image to draw if not created yet
|
||||
if (imageToDraw == NULL)
|
||||
{
|
||||
RenderTexture2D worldOnScreen = LoadRenderTexture(sizeInWorldX, sizeInWorldY);
|
||||
BeginTextureMode(worldOnScreen);
|
||||
DrawTexturePro(currentWorld->texture, (Rectangle) { floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), -(float)(sizeInWorldY) },
|
||||
(Rectangle) { 0, 0, (float)(sizeInWorldX), (float)(sizeInWorldY) }, (Vector2) { 0, 0 }, 0.0f, WHITE);
|
||||
EndTextureMode();
|
||||
imageToDraw = (Image*)RL_MALLOC(sizeof(Image));
|
||||
*imageToDraw = LoadImageFromTexture(worldOnScreen.texture);
|
||||
|
||||
UnloadRenderTexture(worldOnScreen);
|
||||
}
|
||||
|
||||
const Vector2 mousePosition = GetMousePosition();
|
||||
static int firstColor = -1;
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && (mousePosition.x < windowWidth))
|
||||
{
|
||||
int mouseX = (int)(mousePosition.x + offsetDecimalX*zoom)/zoom;
|
||||
int mouseY = (int)(mousePosition.y + offsetDecimalY*zoom)/zoom;
|
||||
if (mouseX >= sizeInWorldX) mouseX = sizeInWorldX - 1;
|
||||
if (mouseY >= sizeInWorldY) mouseY = sizeInWorldY - 1;
|
||||
if (firstColor == -1) firstColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1;
|
||||
const int prevColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1;
|
||||
|
||||
ImageDrawPixel(imageToDraw, mouseX, mouseY, (firstColor) ? BLACK : RAYWHITE);
|
||||
|
||||
if (prevColor != firstColor) UpdateTextureRec(currentWorld->texture, (Rectangle){ floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), (float)(sizeInWorldY) }, imageToDraw->data);
|
||||
}
|
||||
else firstColor = -1;
|
||||
}
|
||||
|
||||
// Load selected preset
|
||||
if (preset >= 0)
|
||||
{
|
||||
Image pattern;
|
||||
if (preset < numberOfPresets - 1) // Preset with pattern image lo load
|
||||
{
|
||||
switch (preset)
|
||||
{
|
||||
case 0: pattern = LoadImage("resources/game_of_life/glider.png"); break;
|
||||
case 1: pattern = LoadImage("resources/game_of_life/r_pentomino.png"); break;
|
||||
case 2: pattern = LoadImage("resources/game_of_life/acorn.png"); break;
|
||||
case 3: pattern = LoadImage("resources/game_of_life/spaceships.png"); break;
|
||||
case 4: pattern = LoadImage("resources/game_of_life/still_lifes.png"); break;
|
||||
case 5: pattern = LoadImage("resources/game_of_life/oscillators.png"); break;
|
||||
case 6: pattern = LoadImage("resources/game_of_life/puffer_train.png"); break;
|
||||
case 7: pattern = LoadImage("resources/game_of_life/glider_gun.png"); break;
|
||||
case 8: pattern = LoadImage("resources/game_of_life/breeder.png"); break;
|
||||
}
|
||||
BeginTextureMode(*currentWorld);
|
||||
ClearBackground(RAYWHITE);
|
||||
EndTextureMode();
|
||||
|
||||
UpdateTextureRec(currentWorld->texture, (Rectangle){ worldWidth*presetPatterns[preset].position.x - pattern.width/2.0f,
|
||||
worldHeight*presetPatterns[preset].position.y - pattern.height/2.0f,
|
||||
(float)(pattern.width), (float)(pattern.height) }, pattern.data);
|
||||
}
|
||||
else // Last preset: Random values
|
||||
{
|
||||
pattern = GenImageColor(worldWidth/randomTiles, worldHeight/randomTiles, RAYWHITE);
|
||||
for (int i = 0; i < randomTiles; i++)
|
||||
{
|
||||
for (int j = 0; j < randomTiles; j++)
|
||||
{
|
||||
ImageClearBackground(&pattern, RAYWHITE);
|
||||
for (int x = 0; x < pattern.width; x++)
|
||||
{
|
||||
for (int y = 0; y < pattern.height; y++)
|
||||
{
|
||||
if (GetRandomValue(0, 100) < 15) ImageDrawPixel(&pattern, x, y, BLACK);
|
||||
}
|
||||
}
|
||||
UpdateTextureRec(currentWorld->texture,
|
||||
(Rectangle){ (float)(pattern.width*i), (float)(pattern.height*j),
|
||||
(float)(pattern.width), (float)(pattern.height) }, pattern.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UnloadImage(pattern);
|
||||
|
||||
mode = MODE_PAUSE;
|
||||
offsetX = worldWidth*presetPatterns[preset].position.x - windowWidth/zoom/2.0f;
|
||||
offsetY = worldHeight*presetPatterns[preset].position.y - windowHeight/zoom/2.0f;
|
||||
}
|
||||
|
||||
// Check window draw inside world limits
|
||||
if (offsetX < 0) offsetX = 0;
|
||||
if (offsetY < 0) offsetY = 0;
|
||||
if (offsetX > worldWidth - (float)(windowWidth)/zoom) offsetX = worldWidth - (float)(windowWidth)/zoom;
|
||||
if (offsetY > worldHeight - (float)(windowHeight)/zoom) offsetY = worldHeight - (float)(windowHeight)/zoom;
|
||||
|
||||
// Rectangles for drawing texture portion to screen
|
||||
const Rectangle textureSourceToScreen = { offsetX, offsetY, (float)windowWidth/zoom, (float)windowHeight/zoom };
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw to texture
|
||||
//----------------------------------------------------------------------------------
|
||||
if ((mode == MODE_RUN) && ((frame%framesPerStep) == 0))
|
||||
{
|
||||
// Swap worlds
|
||||
RenderTexture2D *tempWorld = currentWorld;
|
||||
currentWorld = previousWorld;
|
||||
previousWorld = tempWorld;
|
||||
|
||||
// Draw to texture
|
||||
BeginTextureMode(*currentWorld);
|
||||
BeginShaderMode(shdrGameOfLife);
|
||||
DrawTexturePro(previousWorld->texture, worldRectSource, worldRectDest, (Vector2){ 0, 0 }, 0.0f, RAYWHITE);
|
||||
EndShaderMode();
|
||||
EndTextureMode();
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw to screen
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
DrawTexturePro(currentWorld->texture, textureSourceToScreen, textureOnScreen, (Vector2){ 0, 0 }, 0.0f, WHITE);
|
||||
|
||||
DrawLine(windowWidth, 0, windowWidth, screenHeight, (Color){ 218, 218, 218, 255 });
|
||||
DrawRectangle(windowWidth, 0, screenWidth - windowWidth, screenHeight, (Color){ 232, 232, 232, 255 });
|
||||
|
||||
DrawText("Conway's", 704, 4, 20, DARKBLUE);
|
||||
DrawText(" game of", 704, 19, 20, DARKBLUE);
|
||||
DrawText(" life", 708, 34, 20, DARKBLUE);
|
||||
DrawText("in raylib", 757, 42, 6, BLACK);
|
||||
|
||||
DrawText("Presets", 710, 58, 8, GRAY);
|
||||
preset = -1;
|
||||
for (int i = 0; i < numberOfPresets; i++)
|
||||
if (GuiButton((Rectangle){ 710.0f, 70.0f + 18*i, 80.0f, 16.0f }, presetPatterns[i].name)) preset = i;
|
||||
|
||||
GuiToggleGroup((Rectangle){ 710, 258, 80, 16 }, "Run\nPause\nDraw", &mode);
|
||||
|
||||
DrawText(TextFormat("Zoom: %ix", zoom), 710, 316, 8, GRAY);
|
||||
buttonZoomIn = GuiButton((Rectangle){ 710, 328, 80, 16 }, "Zoom in");
|
||||
buttonZomOut = GuiButton((Rectangle){ 710, 346, 80, 16 }, "Zoom out");
|
||||
|
||||
DrawText(TextFormat("Speed: %i frame%s", framesPerStep, (framesPerStep > 1)? "s" : ""), 710, 370, 8, GRAY);
|
||||
buttonFaster = GuiButton((Rectangle){ 710, 382, 80, 16 }, "Faster");
|
||||
buttonSlower = GuiButton((Rectangle){ 710, 400, 80, 16 }, "Slower");
|
||||
|
||||
DrawFPS(712, 426);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(shdrGameOfLife);
|
||||
UnloadRenderTexture(world1);
|
||||
UnloadRenderTexture(world2);
|
||||
|
||||
FreeImageToDraw(&imageToDraw);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Functions definition
|
||||
//----------------------------------------------------------------------------------
|
||||
void FreeImageToDraw(Image **imageToDraw)
|
||||
{
|
||||
if (*imageToDraw != NULL)
|
||||
{
|
||||
UnloadImage(**imageToDraw);
|
||||
RL_FREE(*imageToDraw);
|
||||
*imageToDraw = NULL;
|
||||
}
|
||||
}
|
||||
BIN
examples/shaders/shaders_game_of_life.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
@ -118,7 +118,7 @@ int main(void)
|
||||
// Raymarch Scene
|
||||
rlEnableDepthTest(); // Manually enable Depth Test to handle multiple rendering methods
|
||||
BeginShaderMode(shdrRaymarch);
|
||||
DrawRectangleRec((Rectangle){0,0, (float)screenWidth, (float)screenHeight},WHITE);
|
||||
DrawRectangleRec((Rectangle){ 0,0, (float)screenWidth, (float)screenHeight },WHITE);
|
||||
EndShaderMode();
|
||||
|
||||
// Rasterize Scene
|
||||
@ -138,6 +138,7 @@ int main(void)
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawTextureRec(target.texture, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, (Vector2) { 0, 0 }, WHITE);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
#define GLSL_VERSION 100
|
||||
#endif
|
||||
|
||||
#define MAP_SIZE 10
|
||||
#define MAP_SIZE 16
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
@ -88,8 +88,6 @@ int main(void)
|
||||
|
||||
RenderTexture lightmap = LoadRenderTexture(MAP_SIZE, MAP_SIZE);
|
||||
|
||||
SetTextureFilter(lightmap.texture, TEXTURE_FILTER_TRILINEAR);
|
||||
|
||||
Material material = LoadMaterialDefault();
|
||||
material.shader = shader;
|
||||
material.maps[MATERIAL_MAP_ALBEDO].texture = texture;
|
||||
@ -103,30 +101,34 @@ int main(void)
|
||||
DrawTexturePro(
|
||||
light,
|
||||
(Rectangle){ 0, 0, (float)light.width, (float)light.height },
|
||||
(Rectangle){ 0, 0, 20, 20 },
|
||||
(Vector2){ 10.0, 10.0 },
|
||||
(Rectangle){ 0, 0, 2.0f*MAP_SIZE, 2.0f*MAP_SIZE },
|
||||
(Vector2){ (float)MAP_SIZE, (float)MAP_SIZE },
|
||||
0.0,
|
||||
RED
|
||||
);
|
||||
DrawTexturePro(
|
||||
light,
|
||||
(Rectangle){ 0, 0, (float)light.width, (float)light.height },
|
||||
(Rectangle){ 8, 4, 20, 20 },
|
||||
(Vector2){ 10.0, 10.0 },
|
||||
(Rectangle){ (float)MAP_SIZE*0.8f, (float)MAP_SIZE/2.0f, 2.0f*MAP_SIZE, 2.0f*MAP_SIZE },
|
||||
(Vector2){ (float)MAP_SIZE, (float)MAP_SIZE },
|
||||
0.0,
|
||||
BLUE
|
||||
);
|
||||
DrawTexturePro(
|
||||
light,
|
||||
(Rectangle){ 0, 0, (float)light.width, (float)light.height },
|
||||
(Rectangle){ 8, 8, 10, 10 },
|
||||
(Vector2){ 5.0, 5.0 },
|
||||
(Rectangle){ (float)MAP_SIZE*0.8f, (float)MAP_SIZE*0.8f, (float)MAP_SIZE, (float)MAP_SIZE },
|
||||
(Vector2){ (float)MAP_SIZE/2.0f, (float)MAP_SIZE/2.0f },
|
||||
0.0,
|
||||
GREEN
|
||||
);
|
||||
BeginBlendMode(BLEND_ALPHA);
|
||||
EndTextureMode();
|
||||
|
||||
// NOTE: To enable trilinear filtering we need mipmaps available for texture
|
||||
GenTextureMipmaps(&lightmap.texture);
|
||||
SetTextureFilter(lightmap.texture, TEXTURE_FILTER_TRILINEAR);
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
@ -141,24 +143,20 @@ int main(void)
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
DrawMesh(mesh, material, MatrixIdentity());
|
||||
EndMode3D();
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
DrawTexturePro(
|
||||
lightmap.texture,
|
||||
(Rectangle){ 0, 0, -MAP_SIZE, -MAP_SIZE },
|
||||
DrawTexturePro(lightmap.texture, (Rectangle){ 0, 0, -MAP_SIZE, -MAP_SIZE },
|
||||
(Rectangle){ (float)GetRenderWidth() - MAP_SIZE*8 - 10, 10, (float)MAP_SIZE*8, (float)MAP_SIZE*8 },
|
||||
(Vector2){ 0.0, 0.0 },
|
||||
0.0,
|
||||
WHITE);
|
||||
(Vector2){ 0.0, 0.0 }, 0.0, WHITE);
|
||||
|
||||
DrawText("lightmap", GetRenderWidth() - 66, 16 + MAP_SIZE*8, 10, GRAY);
|
||||
DrawText("10x10 pixels", GetRenderWidth() - 76, 30 + MAP_SIZE*8, 10, GRAY);
|
||||
DrawText(TextFormat("LIGHTMAP: %ix%i pixels", MAP_SIZE, MAP_SIZE), GetRenderWidth() - 130, 20 + MAP_SIZE*8, 10, GREEN);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -45,7 +45,7 @@ int main(void)
|
||||
// Shadows are a HUGE topic, and this example shows an extremely simple implementation of the shadowmapping algorithm,
|
||||
// which is the industry standard for shadows. This algorithm can be extended in a ridiculous number of ways to improve
|
||||
// realism and also adapt it for different scenes. This is pretty much the simplest possible implementation
|
||||
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - shadowmap rendering");
|
||||
|
||||
@ -59,7 +59,7 @@ int main(void)
|
||||
Shader shadowShader = LoadShader(TextFormat("resources/shaders/glsl%i/shadowmap.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/shadowmap.fs", GLSL_VERSION));
|
||||
shadowShader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shadowShader, "viewPos");
|
||||
|
||||
|
||||
Vector3 lightDir = Vector3Normalize((Vector3){ 0.35f, -1.0f, -0.35f });
|
||||
Color lightColor = WHITE;
|
||||
Vector4 lightColorNormalized = ColorNormalize(lightColor);
|
||||
@ -83,7 +83,7 @@ int main(void)
|
||||
ModelAnimation *robotAnimations = LoadModelAnimations("resources/models/robot.glb", &animCount);
|
||||
|
||||
RenderTexture2D shadowMap = LoadShadowmapRenderTexture(SHADOWMAP_RESOLUTION, SHADOWMAP_RESOLUTION);
|
||||
|
||||
|
||||
// For the shadowmapping algorithm, we will be rendering everything from the light's point of view
|
||||
Camera3D lightCamera = { 0 };
|
||||
lightCamera.position = Vector3Scale(lightDir, -15.0f);
|
||||
@ -91,9 +91,9 @@ int main(void)
|
||||
lightCamera.projection = CAMERA_ORTHOGRAPHIC; // Use an orthographic projection for directional lights
|
||||
lightCamera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
lightCamera.fovy = 20.0f;
|
||||
|
||||
|
||||
int frameCounter = 0;
|
||||
|
||||
|
||||
// Store the light matrices
|
||||
Matrix lightView = { 0 };
|
||||
Matrix lightProj = { 0 };
|
||||
@ -136,7 +136,7 @@ int main(void)
|
||||
{
|
||||
if (lightDir.z > -0.6f) lightDir.z -= cameraSpeed*60.0f*deltaTime;
|
||||
}
|
||||
|
||||
|
||||
lightDir = Vector3Normalize(lightDir);
|
||||
lightCamera.position = Vector3Scale(lightDir, -15.0f);
|
||||
SetShaderValue(shadowShader, lightDirLoc, &lightDir, SHADER_UNIFORM_VEC3);
|
||||
@ -151,13 +151,13 @@ int main(void)
|
||||
// to determine whether a given point is "visible" to the light
|
||||
BeginTextureMode(shadowMap);
|
||||
ClearBackground(WHITE);
|
||||
|
||||
|
||||
BeginMode3D(lightCamera);
|
||||
lightView = rlGetMatrixModelview();
|
||||
lightProj = rlGetMatrixProjection();
|
||||
DrawScene(cube, robot);
|
||||
EndMode3D();
|
||||
|
||||
|
||||
EndTextureMode();
|
||||
lightViewProj = MatrixMultiply(lightView, lightProj);
|
||||
|
||||
@ -167,7 +167,7 @@ int main(void)
|
||||
|
||||
SetShaderValueMatrix(shadowShader, lightVPLoc, lightViewProj);
|
||||
rlEnableShader(shadowShader.id);
|
||||
|
||||
|
||||
rlActiveTextureSlot(textureActiveSlot);
|
||||
rlEnableTexture(shadowMap.depth.id);
|
||||
rlSetUniform(shadowMapLoc, &textureActiveSlot, SHADER_UNIFORM_INT, 1);
|
||||
@ -178,7 +178,7 @@ int main(void)
|
||||
|
||||
DrawText("Use the arrow keys to rotate the light!", 10, 10, 30, RED);
|
||||
DrawText("Shadows in raylib using the shadowmapping algorithm!", screenWidth - 280, screenHeight - 20, 10, GRAY);
|
||||
|
||||
|
||||
EndDrawing();
|
||||
|
||||
if (IsKeyPressed(KEY_F)) TakeScreenshot("shaders_shadowmap.png");
|
||||
@ -200,7 +200,7 @@ int main(void)
|
||||
}
|
||||
|
||||
// Load render texture for shadowmap projection
|
||||
// NOTE: Load framebuffer with only a texture depth attachment,
|
||||
// NOTE: Load framebuffer with only a texture depth attachment,
|
||||
// no color attachment required for shadowmap
|
||||
static RenderTexture2D LoadShadowmapRenderTexture(int width, int height)
|
||||
{
|
||||
|
||||
@ -239,7 +239,7 @@ int main(void)
|
||||
static void ResetStar(Star *star)
|
||||
{
|
||||
star->position = (Vector2){ GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||
|
||||
|
||||
star->speed.x = (float)GetRandomValue(-1000, 1000)/100.0f;
|
||||
star->speed.y = (float)GetRandomValue(-1000, 1000)/100.0f;
|
||||
|
||||
@ -247,7 +247,7 @@ static void ResetStar(Star *star)
|
||||
{
|
||||
star->speed.x = (float)GetRandomValue(-1000, 1000)/100.0f;
|
||||
star->speed.y = (float)GetRandomValue(-1000, 1000)/100.0f;
|
||||
}
|
||||
}
|
||||
|
||||
star->position = Vector2Add(star->position, Vector2Multiply(star->speed, (Vector2){ 8.0f, 8.0f }));
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
*
|
||||
* static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)];
|
||||
*
|
||||
* guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
|
||||
* guiStyle size is by default: 16*(16 + 8) = 384 int = 384*4 bytes = 1536 bytes = 1.5 KB
|
||||
*
|
||||
* Note that the first set of BASE properties (by default guiStyle[0..15]) belong to the generic style
|
||||
* used for all controls, when any of those base values is set, it is automatically populated to all
|
||||
@ -141,7 +141,7 @@
|
||||
* Draw text bounds rectangles for debug
|
||||
*
|
||||
* VERSIONS HISTORY:
|
||||
* 5.0-dev (2025) Current dev version...
|
||||
* 5.0 (xx-Nov-2025) ADDED: Support up to 32 controls (v500)
|
||||
* ADDED: guiControlExclusiveMode and guiControlExclusiveRec for exclusive modes
|
||||
* ADDED: GuiValueBoxFloat()
|
||||
* ADDED: GuiDropdonwBox() properties: DROPDOWN_ARROW_HIDDEN, DROPDOWN_ROLL_UP
|
||||
@ -271,7 +271,7 @@
|
||||
* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria
|
||||
*
|
||||
* DEPENDENCIES:
|
||||
* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
|
||||
* raylib 5.6-dev - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
|
||||
*
|
||||
* STANDALONE MODE:
|
||||
* By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled
|
||||
@ -1010,28 +1010,28 @@ typedef enum {
|
||||
ICON_SLICING = 231,
|
||||
ICON_MANUAL_CONTROL = 232,
|
||||
ICON_COLLISION = 233,
|
||||
ICON_234 = 234,
|
||||
ICON_235 = 235,
|
||||
ICON_236 = 236,
|
||||
ICON_237 = 237,
|
||||
ICON_238 = 238,
|
||||
ICON_239 = 239,
|
||||
ICON_240 = 240,
|
||||
ICON_241 = 241,
|
||||
ICON_242 = 242,
|
||||
ICON_243 = 243,
|
||||
ICON_244 = 244,
|
||||
ICON_245 = 245,
|
||||
ICON_246 = 246,
|
||||
ICON_247 = 247,
|
||||
ICON_248 = 248,
|
||||
ICON_249 = 249,
|
||||
ICON_CIRCLE_ADD = 234,
|
||||
ICON_CIRCLE_ADD_FILL = 235,
|
||||
ICON_CIRCLE_WARNING = 236,
|
||||
ICON_CIRCLE_WARNING_FILL = 237,
|
||||
ICON_BOX_MORE = 238,
|
||||
ICON_BOX_MORE_FILL = 239,
|
||||
ICON_BOX_MINUS = 240,
|
||||
ICON_BOX_MINUS_FILL = 241,
|
||||
ICON_UNION = 242,
|
||||
ICON_INTERSECTION = 243,
|
||||
ICON_DIFFERENCE = 244,
|
||||
ICON_SPHERE = 245,
|
||||
ICON_CYLINDER = 246,
|
||||
ICON_CONE = 247,
|
||||
ICON_ELLIPSOID = 248,
|
||||
ICON_CAPSULE = 249,
|
||||
ICON_250 = 250,
|
||||
ICON_251 = 251,
|
||||
ICON_252 = 252,
|
||||
ICON_253 = 253,
|
||||
ICON_254 = 254,
|
||||
ICON_255 = 255,
|
||||
ICON_255 = 255
|
||||
} GuiIconName;
|
||||
#endif
|
||||
|
||||
@ -1078,7 +1078,7 @@ typedef enum {
|
||||
|
||||
// Check if two rectangles are equal, used to validate a slider bounds as an id
|
||||
#ifndef CHECK_BOUNDS_ID
|
||||
#define CHECK_BOUNDS_ID(src, dst) ((src.x == dst.x) && (src.y == dst.y) && (src.width == dst.width) && (src.height == dst.height))
|
||||
#define CHECK_BOUNDS_ID(src, dst) (((int)src.x == (int)dst.x) && ((int)src.y == (int)dst.y) && ((int)src.width == (int)dst.width) && ((int)src.height == (int)dst.height))
|
||||
#endif
|
||||
|
||||
#if !defined(RAYGUI_NO_ICONS) && !defined(RAYGUI_CUSTOM_ICONS)
|
||||
@ -1341,22 +1341,22 @@ static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] =
|
||||
0x7fe00000, 0x402e4020, 0x43ce5e0a, 0x40504078, 0x438e4078, 0x402e5e0a, 0x7fe04020, 0x00000000, // ICON_SLICING
|
||||
0x00000000, 0x40027ffe, 0x47c24002, 0x55425d42, 0x55725542, 0x50125552, 0x10105016, 0x00001ff0, // ICON_MANUAL_CONTROL
|
||||
0x7ffe0000, 0x43c24002, 0x48124422, 0x500a500a, 0x500a500a, 0x44224812, 0x400243c2, 0x00007ffe, // ICON_COLLISION
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_237
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_238
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_239
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_240
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_241
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_242
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_243
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_244
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_245
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_246
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_247
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_248
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_249
|
||||
0x03c00000, 0x10080c30, 0x21842184, 0x4ff24182, 0x41824ff2, 0x21842184, 0x0c301008, 0x000003c0, // ICON_CIRCLE_ADD
|
||||
0x03c00000, 0x1ff80ff0, 0x3e7c3e7c, 0x700e7e7e, 0x7e7e700e, 0x3e7c3e7c, 0x0ff01ff8, 0x000003c0, // ICON_CIRCLE_ADD_FILL
|
||||
0x03c00000, 0x10080c30, 0x21842184, 0x41824182, 0x40024182, 0x21842184, 0x0c301008, 0x000003c0, // ICON_CIRCLE_WARNING
|
||||
0x03c00000, 0x1ff80ff0, 0x3e7c3e7c, 0x7e7e7e7e, 0x7ffe7e7e, 0x3e7c3e7c, 0x0ff01ff8, 0x000003c0, // ICON_CIRCLE_WARNING_FILL
|
||||
0x00000000, 0x10041ffc, 0x10841004, 0x13e41084, 0x10841084, 0x10041004, 0x00001ffc, 0x00000000, // ICON_BOX_MORE
|
||||
0x00000000, 0x1ffc1ffc, 0x1f7c1ffc, 0x1c1c1f7c, 0x1f7c1f7c, 0x1ffc1ffc, 0x00001ffc, 0x00000000, // ICON_BOX_MORE_FILL
|
||||
0x00000000, 0x1ffc1ffc, 0x1ffc1ffc, 0x1c1c1ffc, 0x1ffc1ffc, 0x1ffc1ffc, 0x00001ffc, 0x00000000, // ICON_BOX_MINUS
|
||||
0x00000000, 0x10041ffc, 0x10041004, 0x13e41004, 0x10041004, 0x10041004, 0x00001ffc, 0x00000000, // ICON_BOX_MINUS_FILL
|
||||
0x07fe0000, 0x055606aa, 0x7ff606aa, 0x55766eba, 0x55766eaa, 0x55606ffe, 0x55606aa0, 0x00007fe0, // ICON_UNION
|
||||
0x07fe0000, 0x04020402, 0x7fe20402, 0x456246a2, 0x456246a2, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_INTERSECTION
|
||||
0x07fe0000, 0x055606aa, 0x7ff606aa, 0x4436442a, 0x4436442a, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_DIFFERENCE
|
||||
0x03c00000, 0x10080c30, 0x20042004, 0x60064002, 0x47e2581a, 0x20042004, 0x0c301008, 0x000003c0, // ICON_SPHERE
|
||||
0x03e00000, 0x08080410, 0x0c180808, 0x08080be8, 0x08080808, 0x08080808, 0x04100808, 0x000003e0, // ICON_CYLINDER
|
||||
0x00800000, 0x01400140, 0x02200220, 0x04100410, 0x08080808, 0x1c1c13e4, 0x08081004, 0x000007f0, // ICON_CONE
|
||||
0x00000000, 0x07e00000, 0x20841918, 0x40824082, 0x40824082, 0x19182084, 0x000007e0, 0x00000000, // ICON_ELLIPSOID
|
||||
0x00000000, 0x00000000, 0x20041ff8, 0x40024002, 0x40024002, 0x1ff82004, 0x00000000, 0x00000000, // ICON_CAPSULE
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_250
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_251
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_252
|
||||
@ -1743,7 +1743,7 @@ int GuiPanel(Rectangle bounds, const char *text)
|
||||
// NOTE: Using GuiToggle() for the TABS
|
||||
int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
|
||||
{
|
||||
#define RAYGUI_TABBAR_ITEM_WIDTH 160
|
||||
#define RAYGUI_TABBAR_ITEM_WIDTH 148
|
||||
|
||||
int result = -1;
|
||||
//GuiState state = guiState;
|
||||
@ -1776,12 +1776,12 @@ int GuiTabBar(Rectangle bounds, const char **text, int count, int *active)
|
||||
if (i == (*active))
|
||||
{
|
||||
toggle = true;
|
||||
GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle);
|
||||
GuiToggle(tabBounds, text[i], &toggle);
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = false;
|
||||
GuiToggle(tabBounds, GuiIconText(12, text[i]), &toggle);
|
||||
GuiToggle(tabBounds, text[i], &toggle);
|
||||
if (toggle) *active = i;
|
||||
}
|
||||
|
||||
@ -2590,7 +2590,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
int pasteLength = 0;
|
||||
int pasteCodepoint;
|
||||
int pasteCodepointSize;
|
||||
|
||||
|
||||
// Count how many codepoints to copy, stopping at the first unwanted control character
|
||||
while (true)
|
||||
{
|
||||
@ -2599,7 +2599,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
if (!(multiline && (pasteCodepoint == (int)'\n')) && !(pasteCodepoint >= 32)) break;
|
||||
pasteLength += pasteCodepointSize;
|
||||
}
|
||||
|
||||
|
||||
if (pasteLength > 0)
|
||||
{
|
||||
// Move forward data from cursor position
|
||||
@ -2662,7 +2662,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
while (offset < textLength)
|
||||
{
|
||||
if (!isspace(nextCodepoint & 0xff)) break;
|
||||
|
||||
|
||||
offset += nextCodepointSize;
|
||||
accCodepointSize += nextCodepointSize;
|
||||
nextCodepoint = GetCodepointNext(text + offset, &nextCodepointSize);
|
||||
@ -2673,11 +2673,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
|
||||
textLength -= accCodepointSize;
|
||||
}
|
||||
|
||||
|
||||
else if ((textLength > textBoxCursorIndex) && (IsKeyPressed(KEY_DELETE) || (IsKeyDown(KEY_DELETE) && autoCursorShouldTrigger)))
|
||||
{
|
||||
// Delete single codepoint from text, after current cursor position
|
||||
|
||||
|
||||
int nextCodepointSize = 0;
|
||||
GetCodepointNext(text + textBoxCursorIndex, &nextCodepointSize);
|
||||
|
||||
@ -2704,7 +2704,7 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
offset -= prevCodepointSize;
|
||||
accCodepointSize += prevCodepointSize;
|
||||
}
|
||||
|
||||
|
||||
// Check characters of the same type to delete (either ASCII punctuation or anything non-whitespace)
|
||||
// Not using isalnum() since it only works on ASCII characters
|
||||
bool puctuation = ispunct(prevCodepoint & 0xff);
|
||||
@ -2723,11 +2723,11 @@ int GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||
textLength -= accCodepointSize;
|
||||
textBoxCursorIndex -= accCodepointSize;
|
||||
}
|
||||
|
||||
|
||||
else if ((textBoxCursorIndex > 0) && (IsKeyPressed(KEY_BACKSPACE) || (IsKeyDown(KEY_BACKSPACE) && autoCursorShouldTrigger)))
|
||||
{
|
||||
// Delete single codepoint from text, before current cursor position
|
||||
|
||||
|
||||
int prevCodepointSize = 0;
|
||||
|
||||
GetCodepointPrevious(text + textBoxCursorIndex, &prevCodepointSize);
|
||||
@ -3033,7 +3033,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
|
||||
int result = 0;
|
||||
GuiState state = guiState;
|
||||
|
||||
char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0";
|
||||
char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = { 0 };
|
||||
snprintf(textValue, RAYGUI_VALUEBOX_MAX_CHARS + 1, "%i", *value);
|
||||
|
||||
Rectangle textBounds = { 0 };
|
||||
@ -3051,7 +3051,6 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
|
||||
if ((state != STATE_DISABLED) && !guiLocked && !guiControlExclusiveMode)
|
||||
{
|
||||
Vector2 mousePoint = GetMousePosition();
|
||||
|
||||
bool valueHasChanged = false;
|
||||
|
||||
if (editMode)
|
||||
@ -3070,7 +3069,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
|
||||
keyCount--;
|
||||
valueHasChanged = true;
|
||||
}
|
||||
else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS -1)
|
||||
else if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS)
|
||||
{
|
||||
if (keyCount == 0)
|
||||
{
|
||||
@ -3087,30 +3086,26 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
|
||||
}
|
||||
}
|
||||
|
||||
// Only allow keys in range [48..57]
|
||||
if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS)
|
||||
// Add new digit to text value
|
||||
if ((keyCount >= 0) && (keyCount < RAYGUI_VALUEBOX_MAX_CHARS) && (GuiGetTextWidth(textValue) < bounds.width))
|
||||
{
|
||||
if (GuiGetTextWidth(textValue) < bounds.width)
|
||||
int key = GetCharPressed();
|
||||
|
||||
// Only allow keys in range [48..57]
|
||||
if ((key >= 48) && (key <= 57))
|
||||
{
|
||||
int key = GetCharPressed();
|
||||
if ((key >= 48) && (key <= 57))
|
||||
{
|
||||
textValue[keyCount] = (char)key;
|
||||
keyCount++;
|
||||
valueHasChanged = true;
|
||||
}
|
||||
textValue[keyCount] = (char)key;
|
||||
keyCount++;
|
||||
valueHasChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete text
|
||||
if (keyCount > 0)
|
||||
if ((keyCount > 0) && IsKeyPressed(KEY_BACKSPACE))
|
||||
{
|
||||
if (IsKeyPressed(KEY_BACKSPACE))
|
||||
{
|
||||
keyCount--;
|
||||
textValue[keyCount] = '\0';
|
||||
valueHasChanged = true;
|
||||
}
|
||||
keyCount--;
|
||||
textValue[keyCount] = '\0';
|
||||
valueHasChanged = true;
|
||||
}
|
||||
|
||||
if (valueHasChanged) *value = TextToInteger(textValue);
|
||||
@ -3224,9 +3219,9 @@ int GuiValueBoxFloat(Rectangle bounds, const char *text, char *textValue, float
|
||||
textValue[1] = '\0';
|
||||
keyCount++;
|
||||
}
|
||||
|
||||
|
||||
for (int i = keyCount; i > -1; i--) textValue[i + 1] = textValue[i];
|
||||
|
||||
|
||||
textValue[0] = '-';
|
||||
keyCount++;
|
||||
valueHasChanged = true;
|
||||
@ -5084,25 +5079,18 @@ static const char **GetTextLines(const char *text, int *count)
|
||||
int textSize = (int)strlen(text);
|
||||
|
||||
lines[0] = text;
|
||||
int len = 0;
|
||||
*count = 1;
|
||||
//int lineSize = 0; // Stores current line size, not returned
|
||||
|
||||
for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
|
||||
{
|
||||
if (text[i] == '\n')
|
||||
{
|
||||
//lineSize = len;
|
||||
k++;
|
||||
lines[k] = &text[i + 1]; // WARNING: next value is valid?
|
||||
len = 0;
|
||||
lines[k] = &text[i + 1]; // WARNING: next value is valid?
|
||||
*count += 1;
|
||||
}
|
||||
else len++;
|
||||
}
|
||||
|
||||
//lines[*count - 1].size = len;
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
||||
221
examples/shapes/shapes_ball_physics.c
Normal file
@ -0,0 +1,221 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - ball physics
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
|
||||
*
|
||||
* Example contributed by David Buzatto (@davidbuzatto) 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 David Buzatto (@davidbuzatto)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_BALLS 5000 // Maximum quantity of balls
|
||||
|
||||
typedef struct Ball {
|
||||
Vector2 pos; // Position
|
||||
Vector2 vel; // Velocity
|
||||
Vector2 ppos; // Previous position
|
||||
float radius;
|
||||
float friction;
|
||||
float elasticity;
|
||||
Color color;
|
||||
bool grabbed;
|
||||
} Ball;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
|
||||
|
||||
Ball balls[MAX_BALLS] = {{
|
||||
.pos = { GetScreenWidth()/2, GetScreenHeight()/2 },
|
||||
.vel = { 200, 200 },
|
||||
.ppos = { 0 },
|
||||
.radius = 40,
|
||||
.friction = 0.99,
|
||||
.elasticity = 0.9,
|
||||
.color = BLUE,
|
||||
.grabbed = false
|
||||
}};
|
||||
|
||||
int ballCount = 1;
|
||||
Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed
|
||||
Vector2 pressOffset = {0}; // Mouse press offset relative to the ball that grabbedd
|
||||
|
||||
float gravity = 100; // World gravity
|
||||
|
||||
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 delta = GetFrameTime();
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
|
||||
// Checks if a ball was grabbed
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
for (int i = ballCount - 1; i >= 0; i--)
|
||||
{
|
||||
Ball *ball = &balls[i];
|
||||
pressOffset.x = mousePos.x - ball->pos.x;
|
||||
pressOffset.y = mousePos.y - ball->pos.y;
|
||||
|
||||
// If the distance between the ball position and the mouse press position
|
||||
// is less than or equal to the ball radius, the event occurred inside the ball
|
||||
if (hypot(pressOffset.x, pressOffset.y) <= ball->radius)
|
||||
{
|
||||
ball->grabbed = true;
|
||||
grabbedBall = ball;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Releases any ball the was grabbed
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
if (grabbedBall != NULL)
|
||||
{
|
||||
grabbedBall->grabbed = false;
|
||||
grabbedBall = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a new ball
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT) || (IsKeyDown(KEY_LEFT_CONTROL) && IsMouseButtonDown(MOUSE_BUTTON_RIGHT)))
|
||||
{
|
||||
if (ballCount < MAX_BALLS)
|
||||
{
|
||||
balls[ballCount++] = (Ball){
|
||||
.pos = mousePos,
|
||||
.vel = { GetRandomValue(-300, 300), GetRandomValue(-300, 300) },
|
||||
.ppos = { 0 },
|
||||
.radius = 20 + GetRandomValue(0, 30),
|
||||
.friction = 0.99,
|
||||
.elasticity = 0.9,
|
||||
.color = { GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 },
|
||||
.grabbed = false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Shake balls
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE))
|
||||
{
|
||||
for (int i = 0; i < ballCount; i++)
|
||||
{
|
||||
if (!balls[i].grabbed) balls[i].vel = (Vector2){ GetRandomValue(-2000, 2000), GetRandomValue(-2000, 2000) };
|
||||
}
|
||||
}
|
||||
|
||||
// Changes gravity
|
||||
gravity += GetMouseWheelMove()*5;
|
||||
|
||||
// Updates each ball state
|
||||
for (int i = 0; i < ballCount; i++)
|
||||
{
|
||||
Ball *ball = &balls[i];
|
||||
|
||||
// The ball is not grabbed
|
||||
if (!ball->grabbed)
|
||||
{
|
||||
// Ball repositioning using the velocity
|
||||
ball->pos.x += ball->vel.x * delta;
|
||||
ball->pos.y += ball->vel.y * delta;
|
||||
|
||||
// Does the ball hit the screen right boundary?
|
||||
if ((ball->pos.x + ball->radius) >= screenWidth)
|
||||
{
|
||||
ball->pos.x = screenWidth - ball->radius; // Ball repositioning
|
||||
ball->vel.x = -ball->vel.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit
|
||||
}
|
||||
// Does the ball hit the screen left boundary?
|
||||
else if ((ball->pos.x - ball->radius) <= 0)
|
||||
{
|
||||
ball->pos.x = ball->radius;
|
||||
ball->vel.x = -ball->vel.x*ball->elasticity;
|
||||
}
|
||||
|
||||
// The same for y axis
|
||||
if ((ball->pos.y + ball->radius) >= screenHeight)
|
||||
{
|
||||
ball->pos.y = screenHeight - ball->radius;
|
||||
ball->vel.y = -ball->vel.y*ball->elasticity;
|
||||
}
|
||||
else if ((ball->pos.y - ball->radius) <= 0)
|
||||
{
|
||||
ball->pos.y = ball->radius;
|
||||
ball->vel.y = -ball->vel.y*ball->elasticity;
|
||||
}
|
||||
|
||||
// Friction makes the ball lose 1% of its velocity each frame
|
||||
ball->vel.x = ball->vel.x*ball->friction;
|
||||
// Gravity affects only the y axis
|
||||
ball->vel.y = ball->vel.y*ball->friction + gravity;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ball repositioning using the mouse position
|
||||
ball->pos.x = mousePos.x - pressOffset.x;
|
||||
ball->pos.y = mousePos.y - pressOffset.y;
|
||||
|
||||
// While the ball is grabbed, recalculates its velocity
|
||||
ball->vel.x = (ball->pos.x - ball->ppos.x)/delta;
|
||||
ball->vel.y = (ball->pos.y - ball->ppos.y)/delta;
|
||||
ball->ppos = ball->pos;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
for (int i = 0; i < ballCount; i++)
|
||||
{
|
||||
DrawCircleV(balls[i].pos, balls[i].radius, balls[i].color);
|
||||
DrawCircleLinesV(balls[i].pos, balls[i].radius, BLACK);
|
||||
}
|
||||
|
||||
DrawText("grab a ball by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY);
|
||||
DrawText("right click to create new balls (keep left control pressed to create a lot)", 10, 30, 10, DARKGRAY);
|
||||
DrawText("use mouse wheel to change gravity", 10, 50, 10, DARKGRAY);
|
||||
DrawText("middle click to shake", 10, 70, 10, DARKGRAY);
|
||||
DrawText(TextFormat("BALL COUNT: %d", ballCount), 10, GetScreenHeight() - 70, 20, BLACK);
|
||||
DrawText(TextFormat("GRAVITY: %.2f", gravity), 10, GetScreenHeight() - 40, 20, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/shapes/shapes_ball_physics.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
@ -7,7 +7,7 @@
|
||||
* 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,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
@ -49,14 +49,14 @@ int main(void)
|
||||
//-----------------------------------------------------
|
||||
if (IsKeyPressed(KEY_G)) useGravity = !useGravity;
|
||||
if (IsKeyPressed(KEY_SPACE)) pause = !pause;
|
||||
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
ballPosition.x += ballSpeed.x;
|
||||
ballPosition.y += ballSpeed.y;
|
||||
|
||||
if (useGravity) ballSpeed.y += gravity;
|
||||
|
||||
|
||||
// Check walls collision for bouncing
|
||||
if ((ballPosition.x >= (GetScreenWidth() - ballRadius)) || (ballPosition.x <= ballRadius)) ballSpeed.x *= -1.0f;
|
||||
if ((ballPosition.y >= (GetScreenHeight() - ballRadius)) || (ballPosition.y <= ballRadius)) ballSpeed.y *= -0.95f;
|
||||
@ -72,7 +72,7 @@ int main(void)
|
||||
|
||||
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
|
||||
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);
|
||||
|
||||
@ -80,7 +80,7 @@ int main(void)
|
||||
if (pause && ((framesCounter/30)%2)) DrawText("PAUSED", 350, 200, 30, GRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ int main(void)
|
||||
|
||||
float bulletDirection = baseDirection + (degreesPerRow*row);
|
||||
|
||||
// Bullet speed * bullet direction, this will determine how much pixels will be incremented/decremented
|
||||
// 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
|
||||
|
||||
@ -14,9 +14,6 @@
|
||||
* Copyright (c) 2025 JP Mortiboys (@themushroompirates)
|
||||
*
|
||||
********************************************************************************************/
|
||||
#if defined(WIN32)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
@ -35,14 +32,14 @@ int main(void)
|
||||
|
||||
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
|
||||
@ -50,7 +47,7 @@ int main(void)
|
||||
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 },
|
||||
@ -63,24 +60,16 @@ int main(void)
|
||||
/* 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
|
||||
const float handsMoveDuration = 0.5f;
|
||||
|
||||
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
|
||||
@ -91,77 +80,64 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Get the current time
|
||||
time_t rawtime;
|
||||
struct tm *timeinfo;
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
||||
if (timeinfo->tm_sec != prevSeconds) {
|
||||
|
||||
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);
|
||||
|
||||
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++) {
|
||||
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];
|
||||
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
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;
|
||||
|
||||
|
||||
// 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++) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE)) hourMode = 36 - hourMode; // Toggle between 12 and 24 hour mode with space
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -169,52 +145,52 @@ int main(void)
|
||||
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++) {
|
||||
|
||||
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
|
||||
xOffset + col*(clockFaceSize+clockFaceSpacing) + clockFaceSize*0.5f,
|
||||
100 + row*(clockFaceSize+clockFaceSpacing) + clockFaceSize*0.5f
|
||||
};
|
||||
DrawRing(centre, clockFaceSize * 0.5f - 2.0f, clockFaceSize * 0.5f, 0, 360, 24, DARKGRAY);
|
||||
|
||||
|
||||
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},
|
||||
(Rectangle){centre.x, centre.y, clockFaceSize*0.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},
|
||||
(Rectangle){centre.x, centre.y, clockFaceSize*0.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) {
|
||||
|
||||
|
||||
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();
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -222,7 +198,6 @@ int main(void)
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -116,7 +116,7 @@ int main(void)
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw clock in selected mode
|
||||
if (clockMode == CLOCK_ANALOG) DrawClockAnalog(clock, (Vector2){ 400, 240 });
|
||||
if (clockMode == CLOCK_ANALOG) DrawClockAnalog(clock, (Vector2){ 400, 240 });
|
||||
else if (clockMode == CLOCK_DIGITAL)
|
||||
{
|
||||
DrawClockDigital(clock, (Vector2){ 30, 60 });
|
||||
@ -128,7 +128,7 @@ int main(void)
|
||||
DrawText(clockTime, GetScreenWidth()/2 - MeasureText(clockTime, 150)/2, 300, 150, BLACK);
|
||||
}
|
||||
|
||||
DrawText(TextFormat("Press [SPACE] to switch clock mode: %s",
|
||||
DrawText(TextFormat("Press [SPACE] to switch clock mode: %s",
|
||||
(clockMode == CLOCK_DIGITAL)? "DIGITAL CLOCK" : "ANALOGUE CLOCK"), 10, 10, 20, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
@ -183,13 +183,13 @@ static void DrawClockAnalog(Clock clock, Vector2 position)
|
||||
// Draw clock minutes/seconds lines
|
||||
for (int i = 0; i < 60; i++)
|
||||
{
|
||||
DrawLineEx((Vector2){ position.x + (clock.second.length + ((i%5)? 10 : 6))*cosf((6.0f*i - 90.0f)*DEG2RAD),
|
||||
position.y + (clock.second.length + ((i%5)? 10 : 6))*sinf((6.0f*i - 90.0f)*DEG2RAD) },
|
||||
(Vector2){ position.x + (clock.second.length + 20)*cosf((6.0f*i - 90.0f)*DEG2RAD),
|
||||
DrawLineEx((Vector2){ position.x + (clock.second.length + ((i%5)? 10 : 6))*cosf((6.0f*i - 90.0f)*DEG2RAD),
|
||||
position.y + (clock.second.length + ((i%5)? 10 : 6))*sinf((6.0f*i - 90.0f)*DEG2RAD) },
|
||||
(Vector2){ position.x + (clock.second.length + 20)*cosf((6.0f*i - 90.0f)*DEG2RAD),
|
||||
position.y + (clock.second.length + 20)*sinf((6.0f*i - 90.0f)*DEG2RAD) }, ((i%5)? 1.0f : 3.0f), DARKGRAY);
|
||||
|
||||
|
||||
// Draw seconds numbers
|
||||
//DrawText(TextFormat("%02i", i), centerPosition.x + (clock.second.length + 50)*cosf((6.0f*i - 90.0f)*DEG2RAD) - 10/2,
|
||||
//DrawText(TextFormat("%02i", i), centerPosition.x + (clock.second.length + 50)*cosf((6.0f*i - 90.0f)*DEG2RAD) - 10/2,
|
||||
// centerPosition.y + (clock.second.length + 50)*sinf((6.0f*i - 90.0f)*DEG2RAD) - 10/2, 10, GRAY);
|
||||
}
|
||||
|
||||
@ -256,25 +256,25 @@ static void Draw7SDisplay(Vector2 position, char segments, Color colorOn, Color
|
||||
float offsetYAdjust = segmentThick*0.3f; // HACK: Adjust gap space between segment limits
|
||||
|
||||
// Segment A
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + segmentThick },
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + segmentThick },
|
||||
segmentLen, segmentThick, false, (segments & 0b00000001)? colorOn : colorOff);
|
||||
// Segment B
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen + segmentThick/2.0f, position.y + 2*segmentThick + segmentLen/2.0f - offsetYAdjust },
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen + segmentThick/2.0f, position.y + 2*segmentThick + segmentLen/2.0f - offsetYAdjust },
|
||||
segmentLen, segmentThick, true, (segments & 0b00000010)? colorOn : colorOff);
|
||||
// Segment C
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen + segmentThick/2.0f, position.y + 4*segmentThick + segmentLen + segmentLen/2.0f - 3*offsetYAdjust },
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen + segmentThick/2.0f, position.y + 4*segmentThick + segmentLen + segmentLen/2.0f - 3*offsetYAdjust },
|
||||
segmentLen, segmentThick, true, (segments & 0b00000100)? colorOn : colorOff);
|
||||
// Segment D
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + 5*segmentThick + 2*segmentLen - 4*offsetYAdjust },
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + 5*segmentThick + 2*segmentLen - 4*offsetYAdjust },
|
||||
segmentLen, segmentThick, false, (segments & 0b00001000)? colorOn : colorOff);
|
||||
// Segment E
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick/2.0f, position.y + 4*segmentThick + segmentLen + segmentLen/2.0f - 3*offsetYAdjust },
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick/2.0f, position.y + 4*segmentThick + segmentLen + segmentLen/2.0f - 3*offsetYAdjust },
|
||||
segmentLen, segmentThick, true, (segments & 0b00010000)? colorOn : colorOff);
|
||||
// Segment F
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick/2.0f, position.y + 2*segmentThick + segmentLen/2.0f - offsetYAdjust },
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick/2.0f, position.y + 2*segmentThick + segmentLen/2.0f - offsetYAdjust },
|
||||
segmentLen, segmentThick, true, (segments & 0b00100000)? colorOn : colorOff);
|
||||
// Segment G
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + 3*segmentThick + segmentLen - 2*offsetYAdjust },
|
||||
DrawDisplaySegment((Vector2){ position.x + segmentThick + segmentLen/2.0f, position.y + 3*segmentThick + segmentLen - 2*offsetYAdjust },
|
||||
segmentLen, segmentThick, false, (segments & 0b01000000)? colorOn : colorOff);
|
||||
}
|
||||
|
||||
@ -284,11 +284,13 @@ static void DrawDisplaySegment(Vector2 center, int length, int thick, bool verti
|
||||
if (!vertical)
|
||||
{
|
||||
// Horizontal segment points
|
||||
// 3___________________________5
|
||||
// / \
|
||||
// /1 x 6\
|
||||
// \ /
|
||||
// \2___________________________4/
|
||||
/*
|
||||
3___________________________5
|
||||
/ \
|
||||
/1 x 6\
|
||||
\ /
|
||||
\2___________________________4/
|
||||
*/
|
||||
Vector2 segmentPointsH[6] = {
|
||||
(Vector2){ center.x - length/2.0f - thick/2.0f, center.y }, // Point 1
|
||||
(Vector2){ center.x - length/2.0f, center.y + thick/2.0f }, // Point 2
|
||||
|
||||
@ -42,7 +42,7 @@ int main(void)
|
||||
SetConfigFlags(FLAG_WINDOW_HIGHDPI);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - double pendulum");
|
||||
|
||||
// Simulation Paramters
|
||||
// Simulation Parameters
|
||||
float l1 = 15.0f, m1 = 0.2f, theta1 = DEG2RAD*170, w1 = 0;
|
||||
float l2 = 15.0f, m2 = 0.1f, theta2 = DEG2RAD*0, w2 = 0;
|
||||
float lengthScaler = 0.1f;
|
||||
@ -76,7 +76,7 @@ int main(void)
|
||||
float step = dt/SIMULATION_STEPS, step2 = step*step;
|
||||
|
||||
// Update Physics - larger steps = better approximation
|
||||
for (int i = 0; i < SIMULATION_STEPS; ++i)
|
||||
for (int i = 0; i < SIMULATION_STEPS; i++)
|
||||
{
|
||||
float delta = theta1 - theta2;
|
||||
float sinD = sinf(delta), cosD = cosf(delta), cos2D = cosf(2*delta);
|
||||
|
||||
@ -11,13 +11,29 @@
|
||||
* 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)
|
||||
* Copyright (c) 2025 Hugo ARNAL (@hugoarnal) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include <string.h>
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#define MAX_DRAW_LINES 8192
|
||||
|
||||
// Line data type
|
||||
typedef struct {
|
||||
Vector2 start;
|
||||
Vector2 end;
|
||||
} Line;
|
||||
|
||||
// Lines array as a global static variable to be stored
|
||||
// in heap and avoid potential stack overflow (on Web platform)
|
||||
static Line lines[MAX_DRAW_LINES] = { 0 };
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -30,22 +46,31 @@ int main(void)
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - kaleidoscope");
|
||||
|
||||
// Line drawing properties
|
||||
int symmetry = 6;
|
||||
float angle = 360.0f/(float)symmetry;
|
||||
float thickness = 3.0f;
|
||||
Rectangle resetButtonRec = { screenWidth - 55, 5, 50, 25 };
|
||||
Rectangle backButtonRec = { screenWidth - 55, screenHeight - 30, 25, 25 };
|
||||
Rectangle nextButtonRec = { screenWidth - 30, screenHeight - 30, 25, 25 };
|
||||
Vector2 mousePos = { 0 };
|
||||
Vector2 prevMousePos = { 0 };
|
||||
|
||||
SetTargetFPS(60);
|
||||
ClearBackground(BLACK);
|
||||
|
||||
Vector2 scaleVector = { 1.0f, -1.0f };
|
||||
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 };
|
||||
int currentLineCounter = 0;
|
||||
int totalLineCounter = 0;
|
||||
int resetButtonClicked = false;
|
||||
int backButtonClicked = false;
|
||||
int nextButtonClicked = false;
|
||||
|
||||
SetTargetFPS(20);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
@ -53,38 +78,93 @@ int main(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
prevMousePos = mousePos;
|
||||
mousePos = GetMousePosition();
|
||||
|
||||
Vector2 lineStart = Vector2Subtract(mousePos, offset);
|
||||
Vector2 lineEnd = Vector2Subtract(prevMousePos, offset);
|
||||
|
||||
if (
|
||||
IsMouseButtonDown(MOUSE_LEFT_BUTTON)
|
||||
&& (CheckCollisionPointRec(mousePos, resetButtonRec) == false)
|
||||
&& (CheckCollisionPointRec(mousePos, backButtonRec) == false)
|
||||
&& (CheckCollisionPointRec(mousePos, nextButtonRec) == false)
|
||||
)
|
||||
{
|
||||
for (int s = 0; (s < symmetry) && (totalLineCounter < (MAX_DRAW_LINES - 1)); s++)
|
||||
{
|
||||
lineStart = Vector2Rotate(lineStart, angle*DEG2RAD);
|
||||
lineEnd = Vector2Rotate(lineEnd, angle*DEG2RAD);
|
||||
|
||||
// Store mouse line
|
||||
lines[totalLineCounter].start = lineStart;
|
||||
lines[totalLineCounter].end = lineEnd;
|
||||
|
||||
// Store reflective line
|
||||
lines[totalLineCounter + 1].start = Vector2Multiply(lineStart, scaleVector);
|
||||
lines[totalLineCounter + 1].end = Vector2Multiply(lineEnd, scaleVector);
|
||||
|
||||
totalLineCounter += 2;
|
||||
currentLineCounter = totalLineCounter;
|
||||
}
|
||||
}
|
||||
|
||||
if (resetButtonClicked)
|
||||
{
|
||||
memset(&lines, 0, sizeof(Line)*MAX_DRAW_LINES);
|
||||
currentLineCounter = 0;
|
||||
totalLineCounter = 0;
|
||||
}
|
||||
|
||||
if (backButtonClicked && (currentLineCounter > 0))
|
||||
{
|
||||
currentLineCounter -= 1;
|
||||
}
|
||||
|
||||
if (nextButtonClicked && (currentLineCounter < MAX_DRAW_LINES) && ((currentLineCounter + 1) <= totalLineCounter))
|
||||
{
|
||||
currentLineCounter += 1;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
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);
|
||||
for (int s = 0; s < symmetry; s++)
|
||||
{
|
||||
for (int i = 0; i < currentLineCounter; i += 2)
|
||||
{
|
||||
DrawLineEx(lines[i].start, lines[i].end, thickness, BLACK);
|
||||
DrawLineEx(lines[i + 1].start, lines[i + 1].end, thickness, BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
prevMousePos = mousePos;
|
||||
EndMode2D();
|
||||
|
||||
if ((currentLineCounter - 1) < 0) GuiDisable();
|
||||
|
||||
backButtonClicked = GuiButton(backButtonRec, "<");
|
||||
GuiEnable();
|
||||
|
||||
if ((currentLineCounter + 1) > totalLineCounter) GuiDisable();
|
||||
|
||||
nextButtonClicked = GuiButton(nextButtonRec, ">");
|
||||
GuiEnable();
|
||||
resetButtonClicked = GuiButton(resetButtonRec, "Reset");
|
||||
|
||||
DrawText(TextFormat("LINES: %i/%i", currentLineCounter, MAX_DRAW_LINES), 10, screenHeight - 30, 20, MAROON);
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 81 KiB |
@ -16,6 +16,7 @@
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -23,124 +24,114 @@
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - lines drawing");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - lines drawing");
|
||||
|
||||
// Hint text that shows before you click the screen
|
||||
bool startText = true;
|
||||
// Hint text that shows before you click the screen
|
||||
bool startText = true;
|
||||
|
||||
// The mouse's position on the previous frame
|
||||
Vector2 mousePositionPrevious = GetMousePosition();
|
||||
// The mouse's position on the previous frame
|
||||
Vector2 mousePositionPrevious = GetMousePosition();
|
||||
|
||||
// The canvas to draw lines on
|
||||
RenderTexture canvas = LoadRenderTexture(screenWidth, screenHeight);
|
||||
// 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;
|
||||
|
||||
// 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(RAYWHITE);
|
||||
EndTextureMode();
|
||||
|
||||
// Clear the canvas to the background color
|
||||
BeginTextureMode(canvas);
|
||||
ClearBackground(backgroundColor);
|
||||
EndTextureMode();
|
||||
//--------------------------------------------------------------------------------------
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// 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;
|
||||
}
|
||||
// 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();
|
||||
}
|
||||
// Clear the canvas when the user middle-clicks
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE))
|
||||
{
|
||||
BeginTextureMode(canvas);
|
||||
ClearBackground(RAYWHITE);
|
||||
EndTextureMode();
|
||||
}
|
||||
|
||||
// Store whether the left and right buttons are down
|
||||
bool leftButtonDown = IsMouseButtonDown(MOUSE_BUTTON_LEFT);
|
||||
bool rightButtonDown = IsMouseButtonDown(MOUSE_BUTTON_RIGHT);
|
||||
// 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 || rightButtonDown)
|
||||
{
|
||||
// The color for the line
|
||||
Color drawColor = WHITE;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
// Create the final color
|
||||
drawColor = ColorFromHSV(lineHue, 1.0f, 1.0f);
|
||||
}
|
||||
else if (rightButtonDown) drawColor = RAYWHITE; // Use the background color as an "eraser"
|
||||
|
||||
// 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();
|
||||
}
|
||||
// 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 line thickness based on mousewheel
|
||||
lineThickness += GetMouseWheelMove();
|
||||
lineThickness = Clamp(lineThickness, 1.0, 500.0f);
|
||||
|
||||
// Update mouse's previous position
|
||||
mousePositionPrevious = GetMousePosition();
|
||||
//----------------------------------------------------------------------------------
|
||||
// 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
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
// Draw the preview circle
|
||||
if (!leftButtonDown) DrawCircleLinesV(GetMousePosition(), lineThickness/2.0f, (Color){ 127, 127, 127, 127 });
|
||||
// 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 hint text
|
||||
if (startText) DrawText("try clicking and dragging!", 275, 215, 20, LIGHTGRAY);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
// Draw the preview circle
|
||||
if (!leftButtonDown) DrawCircleLinesV(GetMousePosition(), lineThickness/2.0f, (Color){ 127, 127, 127, 127 });
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Unload the canvas render texture
|
||||
UnloadRenderTexture(canvas);
|
||||
// Draw the hint text
|
||||
if (startText) DrawText("try clicking and dragging!", 275, 215, 20, LIGHTGRAY);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
return 0;
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(canvas); // Unload the canvas render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -31,7 +31,7 @@ int main(void)
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - math angle rotation");
|
||||
SetTargetFPS(60);
|
||||
|
||||
Vector2 center = { screenWidth / 2.0f, screenHeight / 2.0f };
|
||||
Vector2 center = { screenWidth/2.0f, screenHeight/2.0f };
|
||||
const float lineLength = 150.0f;
|
||||
|
||||
// Predefined angles for fixed lines
|
||||
@ -60,9 +60,9 @@ int main(void)
|
||||
// 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 };
|
||||
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;
|
||||
@ -78,15 +78,15 @@ int main(void)
|
||||
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) };
|
||||
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 };
|
||||
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);
|
||||
|
||||
@ -35,13 +35,13 @@ int main(void)
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
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};
|
||||
Vector2 center = { (screenWidth/2.0f) - 30.0f, screenHeight/2.0f };
|
||||
Rectangle start = { 20.0f, screenHeight - 120.f , 200.0f, 100.0f};
|
||||
float radius = 130.0f;
|
||||
float angle = 0.0f;
|
||||
bool pause = false;
|
||||
@ -97,8 +97,8 @@ int main(void)
|
||||
|
||||
// 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);
|
||||
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.0f, GRAY);
|
||||
|
||||
// Wave graph axes
|
||||
DrawLineEx((Vector2){ start.x , start.y }, (Vector2){ start.x , start.y + start.height }, 2.0f, GRAY);
|
||||
@ -110,17 +110,17 @@ int main(void)
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
@ -135,32 +135,33 @@ int main(void)
|
||||
DrawText(TextFormat("Cotangent %.2f", cotangent), 640, 250, 6, ORANGE);
|
||||
|
||||
// Complementary angle (beige)
|
||||
DrawCircleSectorLines(center, radius*0.6f , -angle, -90.f , 36.0f, BEIGE);
|
||||
DrawCircleSectorLines(center, radius*0.6f , -angle, -90.0f , 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);
|
||||
DrawCircleSectorLines(center, radius*0.5f , -angle, -180.0f , 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);
|
||||
DrawCircleSectorLines(center, radius*0.4f , -angle, -360.0f , 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);
|
||||
DrawCircleSectorLines(center, radius*0.7f , -angle, 0.0f, 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);
|
||||
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);
|
||||
GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f°", angle), &angle, 0.0f, 360.0f);
|
||||
|
||||
// Angle values panel
|
||||
GuiGroupBox((Rectangle){ 620, 110, 140, 170}, "Angle Values");
|
||||
GuiGroupBox((Rectangle){ 620, 110, 140, 170}, "Angle Values");
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
|
||||
@ -35,7 +35,7 @@ int main(void)
|
||||
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 };
|
||||
Vector2 trailPositions[MAX_TRAIL_LENGTH] = { 0 };
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
@ -62,8 +62,8 @@ int main(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(BLACK);
|
||||
|
||||
ClearBackground(BLACK);
|
||||
|
||||
// Draw the trail by looping through the history array
|
||||
for (int i = 0; i < MAX_TRAIL_LENGTH; i++)
|
||||
{
|
||||
@ -71,22 +71,22 @@ int main(void)
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
Color trailColor = Fade(SKYBLUE, ratio*0.5f + 0.5f);
|
||||
|
||||
// Size effect: oldest positions are smaller
|
||||
float trailRadius = 15.0f*ratio;
|
||||
|
||||
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();
|
||||
|
||||
271
examples/shapes/shapes_penrose_tile.c
Normal file
@ -0,0 +1,271 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - penrose tile
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.6-dev
|
||||
* Based on: https://processing.org/examples/penrosetile.html
|
||||
*
|
||||
* Example contributed by David Buzatto (@davidbuzatto) 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 David Buzatto (@davidbuzatto)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define STR_MAX_SIZE 10000
|
||||
#define TURTLE_STACK_MAX_SIZE 50
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct TurtleState {
|
||||
Vector2 origin;
|
||||
double angle;
|
||||
} TurtleState;
|
||||
|
||||
typedef struct PenroseLSystem {
|
||||
int steps;
|
||||
char *production;
|
||||
const char *ruleW;
|
||||
const char *ruleX;
|
||||
const char *ruleY;
|
||||
const char *ruleZ;
|
||||
float drawLength;
|
||||
float theta;
|
||||
} PenroseLSystem;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static TurtleState turtleStack[TURTLE_STACK_MAX_SIZE];
|
||||
static int turtleTop = -1;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static void PushTurtleState(TurtleState state);
|
||||
static TurtleState PopTurtleState(void);
|
||||
static PenroseLSystem CreatePenroseLSystem(float drawLength);
|
||||
static void BuildProductionStep(PenroseLSystem *ls);
|
||||
static void DrawPenroseLSystem(PenroseLSystem *ls);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// 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 - penrose tile");
|
||||
|
||||
float drawLength = 460.0f;
|
||||
int minGenerations = 0;
|
||||
int maxGenerations = 4;
|
||||
int generations = 0;
|
||||
|
||||
// Initializee new penrose tile
|
||||
PenroseLSystem ls = CreatePenroseLSystem(drawLength*(generations/(float)maxGenerations));
|
||||
for (int i = 0; i < generations; i++) BuildProductionStep(&ls);
|
||||
|
||||
SetTargetFPS(120); // Set our game to run at 120 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
bool rebuild = false;
|
||||
if (IsKeyPressed(KEY_UP))
|
||||
{
|
||||
if (generations < maxGenerations)
|
||||
{
|
||||
generations++;
|
||||
rebuild = true;
|
||||
}
|
||||
}
|
||||
else if (IsKeyPressed(KEY_DOWN))
|
||||
{
|
||||
if (generations > minGenerations)
|
||||
{
|
||||
generations--;
|
||||
if (generations > 0) rebuild = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rebuild)
|
||||
{
|
||||
RL_FREE(ls.production); // Free previous production for re-creation
|
||||
ls = CreatePenroseLSystem(drawLength*(generations/(float)maxGenerations));
|
||||
for (int i = 0; i < generations; i++) BuildProductionStep(&ls);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground( RAYWHITE );
|
||||
|
||||
if (generations > 0) DrawPenroseLSystem(&ls);
|
||||
|
||||
DrawText("penrose l-system", 10, 10, 20, DARKGRAY);
|
||||
DrawText("press up or down to change generations", 10, 30, 20, DARKGRAY);
|
||||
DrawText(TextFormat("generations: %d", generations), 10, 50, 20, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Push turtle state for next step
|
||||
static void PushTurtleState(TurtleState state)
|
||||
{
|
||||
if (turtleTop < (TURTLE_STACK_MAX_SIZE - 1)) turtleStack[++turtleTop] = state;
|
||||
else TraceLog(LOG_WARNING, "TURTLE STACK OVERFLOW!");
|
||||
}
|
||||
|
||||
// Pop turtle state step
|
||||
static TurtleState PopTurtleState(void)
|
||||
{
|
||||
if (turtleTop >= 0) return turtleStack[turtleTop--];
|
||||
else TraceLog(LOG_WARNING, "TURTLE STACK UNDERFLOW!");
|
||||
|
||||
return (TurtleState){ 0 };
|
||||
}
|
||||
|
||||
// Create a new penrose tile structure
|
||||
static PenroseLSystem CreatePenroseLSystem(float drawLength)
|
||||
{
|
||||
// TODO: Review constant values assignment on recreation?
|
||||
PenroseLSystem ls = {
|
||||
.steps = 0,
|
||||
.ruleW = "YF++ZF4-XF[-YF4-WF]++",
|
||||
.ruleX = "+YF--ZF[3-WF--XF]+",
|
||||
.ruleY = "-WF++XF[+++YF++ZF]-",
|
||||
.ruleZ = "--YF++++WF[+ZF++++XF]--XF",
|
||||
.drawLength = drawLength,
|
||||
.theta = 36.0f // Degrees
|
||||
};
|
||||
|
||||
ls.production = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
|
||||
ls.production[0] = '\0';
|
||||
strncpy(ls.production, "[X]++[X]++[X]++[X]++[X]", STR_MAX_SIZE);
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
// Build next penrose step
|
||||
static void BuildProductionStep(PenroseLSystem *ls)
|
||||
{
|
||||
char *newProduction = (char *)RL_MALLOC(sizeof(char)*STR_MAX_SIZE);
|
||||
newProduction[0] = '\0';
|
||||
|
||||
int productionLength = strnlen(ls->production, STR_MAX_SIZE);
|
||||
|
||||
for (int i = 0; i < productionLength; i++)
|
||||
{
|
||||
char step = ls->production[i];
|
||||
int remainingSpace = STR_MAX_SIZE - strnlen(newProduction, STR_MAX_SIZE) - 1;
|
||||
switch (step)
|
||||
{
|
||||
case 'W': strncat(newProduction, ls->ruleW, remainingSpace); break;
|
||||
case 'X': strncat(newProduction, ls->ruleX, remainingSpace); break;
|
||||
case 'Y': strncat(newProduction, ls->ruleY, remainingSpace); break;
|
||||
case 'Z': strncat(newProduction, ls->ruleZ, remainingSpace); break;
|
||||
default:
|
||||
{
|
||||
if (step != 'F')
|
||||
{
|
||||
int t = strnlen(newProduction, STR_MAX_SIZE);
|
||||
newProduction[t] = step;
|
||||
newProduction[t + 1] = '\0';
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
ls->drawLength *= 0.5f;
|
||||
strncpy(ls->production, newProduction, STR_MAX_SIZE);
|
||||
|
||||
RL_FREE(newProduction);
|
||||
}
|
||||
|
||||
// Draw penrose tile lines
|
||||
static void DrawPenroseLSystem(PenroseLSystem *ls)
|
||||
{
|
||||
Vector2 screenCenter = { GetScreenWidth()/2, GetScreenHeight()/2 };
|
||||
|
||||
TurtleState turtle = {
|
||||
.origin = { 0 },
|
||||
.angle = -90.0f
|
||||
};
|
||||
|
||||
int repeats = 1;
|
||||
int productionLength = (int)strnlen(ls->production, STR_MAX_SIZE);
|
||||
ls->steps += 12;
|
||||
|
||||
if (ls->steps > productionLength) ls->steps = productionLength;
|
||||
|
||||
for (int i = 0; i < ls->steps; i++)
|
||||
{
|
||||
char step = ls->production[i];
|
||||
if (step == 'F')
|
||||
{
|
||||
for (int j = 0; j < repeats; j++)
|
||||
{
|
||||
Vector2 startPosWorld = turtle.origin;
|
||||
float radAngle = DEG2RAD*turtle.angle;
|
||||
turtle.origin.x += ls->drawLength*cosf(radAngle);
|
||||
turtle.origin.y += ls->drawLength*sinf(radAngle);
|
||||
Vector2 startPosScreen = { startPosWorld.x + screenCenter.x, startPosWorld.y + screenCenter.y };
|
||||
Vector2 endPosScreen = { turtle.origin.x + screenCenter.x, turtle.origin.y + screenCenter.y };
|
||||
|
||||
DrawLineEx(startPosScreen, endPosScreen, 2, Fade(BLACK, 0.2));
|
||||
}
|
||||
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '+')
|
||||
{
|
||||
for (int j = 0; j < repeats; j++) turtle.angle += ls->theta;
|
||||
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '-')
|
||||
{
|
||||
for (int j = 0; j < repeats; j++) turtle.angle += -ls->theta;
|
||||
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '[') PushTurtleState(turtle);
|
||||
else if (step == ']') turtle = PopTurtleState();
|
||||
else if ((step >= 48) && (step <= 57)) repeats = (int) step - 48;
|
||||
}
|
||||
|
||||
turtleTop = -1;
|
||||
}
|
||||
BIN
examples/shapes/shapes_penrose_tile.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
@ -67,7 +67,7 @@ int main(void)
|
||||
const Rectangle panelRect = {
|
||||
panelPos.x, panelPos.y,
|
||||
(float)panelWidth,
|
||||
(float)screenHeight - 2.0f*panelMargin
|
||||
(float)screenHeight - 2.0f*panelMargin
|
||||
};
|
||||
|
||||
// Pie chart geometry
|
||||
@ -108,13 +108,13 @@ int main(void)
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -182,11 +182,11 @@ int main(void)
|
||||
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
|
||||
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;
|
||||
|
||||
|
||||
@ -184,7 +184,7 @@ static void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, fl
|
||||
}
|
||||
|
||||
// End one even segments
|
||||
if ( segments % 2)
|
||||
if ( segments%2)
|
||||
{
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
|
||||
@ -45,7 +45,7 @@ int main(void)
|
||||
|
||||
Vector2 start = { (screenWidth/2.0f) - 125.0f, (float)screenHeight };
|
||||
float angle = 40.0f;
|
||||
float thick = 1.0f;
|
||||
float thick = 1.0f;
|
||||
float treeDepth = 10.0f;
|
||||
float branchDecay = 0.66f;
|
||||
float length = 120.0f;
|
||||
@ -67,21 +67,21 @@ int main(void)
|
||||
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++)
|
||||
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)
|
||||
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};
|
||||
@ -94,10 +94,10 @@ int main(void)
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Branch branch = branches[i];
|
||||
if (branch.length >= 2)
|
||||
if (branch.length >= 2)
|
||||
{
|
||||
if (bezier) DrawLineBezier(branch.start, branch.end, thick, RED);
|
||||
else DrawLineEx(branch.start, branch.end, thick, RED);
|
||||
@ -112,7 +112,7 @@ int main(void)
|
||||
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, 130, 120, 20 }, "Depth", TextFormat("%.0f", treeDepth), &treeDepth, 1.0f, 10.0f);
|
||||
GuiSliderBar((Rectangle){ 640, 160, 120, 20}, "Thick", TextFormat("%.0f", thick), &thick, 1, 8);
|
||||
GuiCheckBox((Rectangle){ 640, 190, 20, 20 }, "Bezier", &bezier);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
274
examples/shapes/shapes_rlgl_color_wheel.c
Normal file
@ -0,0 +1,274 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - rlgl color wheel
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/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 "rlgl.h"
|
||||
#include "raymath.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
// The minimum/maximum points the circle can have
|
||||
const unsigned int pointsMin = 3;
|
||||
const unsigned int pointsMax = 256;
|
||||
|
||||
// The current number of points and the radius of the circle
|
||||
unsigned int triangleCount = 64;
|
||||
float pointScale = 150.0f;
|
||||
|
||||
// Slider value, literally maps to value in HSV
|
||||
float value = 1.0f;
|
||||
|
||||
// The center of the screen
|
||||
Vector2 center = { (float)screenWidth/2.0f, (float)screenHeight/2.0f };
|
||||
// The location of the color wheel
|
||||
Vector2 circlePosition = center;
|
||||
|
||||
// The currently selected color
|
||||
Color color = { 255, 255, 255, 255 };
|
||||
|
||||
// Indicates if the slider is being clicked
|
||||
bool sliderClicked = false;
|
||||
|
||||
// Indicates if the current color going to be updated, as well as the handle position
|
||||
bool settingColor = false;
|
||||
|
||||
// How the color wheel will be rendered
|
||||
unsigned int renderType = RL_TRIANGLES;
|
||||
|
||||
// Enable anti-aliasing
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rlgl color wheel");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
triangleCount += (unsigned int)GetMouseWheelMove();
|
||||
triangleCount = (unsigned int)Clamp((float)triangleCount, (float)pointsMin, (float)pointsMax);
|
||||
|
||||
Rectangle sliderRectangle = { 42.0f, 16.0f + 64.0f + 45.0f, 64.0f, 16.0f };
|
||||
Vector2 mousePosition = GetMousePosition();
|
||||
|
||||
// Checks if the user is hovering over the value slider
|
||||
bool sliderHover = (mousePosition.x >= sliderRectangle.x && mousePosition.y >= sliderRectangle.y && mousePosition.x < sliderRectangle.x + sliderRectangle.width && mousePosition.y < sliderRectangle.y + sliderRectangle.height);
|
||||
|
||||
// Copy color as hex
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_C))
|
||||
{
|
||||
if (IsKeyPressed(KEY_C))
|
||||
{
|
||||
SetClipboardText(TextFormat("#%02X%02X%02X", color.r, color.g, color.b));
|
||||
}
|
||||
}
|
||||
|
||||
// Scale up the color wheel, adjusting the handle visually
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
pointScale *= 1.025f;
|
||||
|
||||
if (pointScale > (float)screenHeight/2.0f)
|
||||
{
|
||||
pointScale = (float)screenHeight/2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
circlePosition = Vector2Add(Vector2Multiply(Vector2Subtract(circlePosition, center), (Vector2){ 1.025f, 1.025f }), center);
|
||||
}
|
||||
}
|
||||
|
||||
// Scale down the wheel, adjusting the handle visually
|
||||
if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
pointScale *= 0.975f;
|
||||
|
||||
if (pointScale < 32.0f)
|
||||
{
|
||||
pointScale = 32.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
circlePosition = Vector2Add(Vector2Multiply(Vector2Subtract(circlePosition, center), (Vector2){ 0.975f, 0.975f }), center);
|
||||
}
|
||||
|
||||
float distance = Vector2Distance(center, circlePosition)/pointScale;
|
||||
float angle = ((Vector2Angle((Vector2){ 0.0f, -pointScale }, Vector2Subtract(center, circlePosition))/PI + 1.0f)/2.0f);
|
||||
|
||||
if (distance > 1.0f)
|
||||
{
|
||||
circlePosition = Vector2Add((Vector2){ sinf(angle*(PI*2.0f))*pointScale, -cosf(angle*(PI*2.0f))*pointScale }, center);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the user clicked on the color wheel
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && Vector2Distance(GetMousePosition(), center) <= pointScale + 10.0f)
|
||||
{
|
||||
settingColor = true;
|
||||
}
|
||||
|
||||
// Update flag when mouse button is released
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) settingColor = false;
|
||||
|
||||
// Check if the user clicked/released the slider for the color's value
|
||||
if (sliderHover && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) sliderClicked = true;
|
||||
|
||||
if (sliderClicked && IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) sliderClicked = false;
|
||||
|
||||
// Update render mode accordingly
|
||||
if (IsKeyPressed(KEY_SPACE)) renderType = RL_LINES;
|
||||
|
||||
if (IsKeyReleased(KEY_SPACE)) renderType = RL_TRIANGLES;
|
||||
|
||||
// If the slider or the wheel was clicked, update the current color
|
||||
if (settingColor || sliderClicked)
|
||||
{
|
||||
if (settingColor) circlePosition = GetMousePosition();
|
||||
|
||||
float distance = Vector2Distance(center, circlePosition)/pointScale;
|
||||
|
||||
float angle = ((Vector2Angle((Vector2){ 0.0f, -pointScale }, Vector2Subtract(center, circlePosition))/PI + 1.0f)/2.0f);
|
||||
if (settingColor && distance > 1.0f) circlePosition = Vector2Add((Vector2){ sinf(angle*(PI*2.0f))*pointScale, -cosf(angle*(PI* 2.0f))*pointScale }, center);
|
||||
|
||||
float angle360 = angle*360.0f;
|
||||
float valueActual = Clamp(distance, 0.0f, 1.0f);
|
||||
color = ColorLerp((Color){ (int)(value*255.0f), (int)(value*255.0f), (int)(value*255.0f), 255 }, ColorFromHSV(angle360, Clamp(distance, 0.0f, 1.0f), 1.0f), valueActual);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Begin rendering color wheel
|
||||
rlBegin(renderType);
|
||||
for (unsigned int i = 0; i < triangleCount; i++)
|
||||
{
|
||||
float angleOffset = ((PI*2.0f)/(float)triangleCount);
|
||||
float angle = angleOffset*(float)i;
|
||||
float angleOffsetCalculated = ((float)i + 1)*angleOffset;
|
||||
Vector2 scale = (Vector2){ pointScale, pointScale };
|
||||
|
||||
Vector2 offset = Vector2Multiply((Vector2){ sinf(angle), -cosf(angle) }, scale);
|
||||
Vector2 offset2 = Vector2Multiply((Vector2){ sinf(angleOffsetCalculated), -cosf(angleOffsetCalculated) }, scale);
|
||||
|
||||
Vector2 position = Vector2Add(center, offset);
|
||||
Vector2 position2 = Vector2Add(center, offset2);
|
||||
|
||||
float angleNonRadian = (angle/(2.0f*PI))*360.0f;
|
||||
float angleNonRadianOffset = (angleOffset/(2.0f*PI))*360.0f;
|
||||
|
||||
Color currentColor = ColorFromHSV(angleNonRadian, 1.0f, 1.0f);
|
||||
Color offsetColor = ColorFromHSV(angleNonRadian + angleNonRadianOffset, 1.0f, 1.0f);
|
||||
|
||||
// Input vertices differently depending on mode
|
||||
if (renderType == RL_TRIANGLES)
|
||||
{
|
||||
// RL_TRIANGLES expects three vertices per triangle
|
||||
rlColor4ub(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
|
||||
rlVertex2f(position.x, position.y);
|
||||
rlColor4f(value, value, value, 1.0f);
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlColor4ub(offsetColor.r, offsetColor.g, offsetColor.b, offsetColor.a);
|
||||
rlVertex2f(position2.x, position2.y);
|
||||
}
|
||||
else if (renderType == RL_LINES)
|
||||
{
|
||||
// RL_LINES expects two vertices per line
|
||||
rlColor4ub(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
|
||||
rlVertex2f(position.x, position.y);
|
||||
rlColor4ub(WHITE.r, WHITE.g, WHITE.b, WHITE.a);
|
||||
rlVertex2f(center.x, center.y);
|
||||
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlColor4ub(offsetColor.r, offsetColor.g, offsetColor.b, offsetColor.a);
|
||||
rlVertex2f(position2.x, position2.y);
|
||||
|
||||
rlVertex2f(position2.x, position2.y);
|
||||
rlColor4ub(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
|
||||
rlVertex2f(position.x, position.y);
|
||||
}
|
||||
}
|
||||
rlEnd();
|
||||
|
||||
// Make the handle slightly more visible overtop darker colors
|
||||
Color handleColor = BLACK;
|
||||
|
||||
if (Vector2Distance(center, circlePosition)/pointScale <= 0.5f && value <= 0.5f)
|
||||
{
|
||||
handleColor = DARKGRAY;
|
||||
}
|
||||
|
||||
// Draw the color handle
|
||||
DrawCircleLinesV(circlePosition, 4.0f, handleColor);
|
||||
|
||||
// Draw the color in a preview, with a darkened outline.
|
||||
DrawRectangleV((Vector2){ 8.0f, 8.0f }, (Vector2){ 64.0f, 64.0f }, color);
|
||||
DrawRectangleLinesEx((Rectangle){ 8.0f, 8.0f, 64.0f, 64.0f }, 2.0f, ColorLerp(color, BLACK, 0.5f));
|
||||
|
||||
// Draw current color as hex and decimal
|
||||
DrawText(TextFormat("#%02X%02X%02X\n(%d, %d, %d)", color.r, color.g, color.b, color.r, color.g, color.b), 8, 8 + 64 + 8, 20, DARKGRAY);
|
||||
|
||||
// Update the visuals for the copying text
|
||||
Color copyColor = DARKGRAY;
|
||||
unsigned int offset = 0;
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_C))
|
||||
{
|
||||
copyColor = DARKGREEN;
|
||||
offset = 4;
|
||||
}
|
||||
|
||||
// Draw the copying text
|
||||
DrawText("press ctrl+c to copy!", 8, 425 - offset, 20, copyColor);
|
||||
|
||||
// Display the number of rendered triangles
|
||||
DrawText(TextFormat("triangle count: %d", triangleCount), 8, 395, 20, DARKGRAY);
|
||||
|
||||
// Slider to change color's value
|
||||
GuiSliderBar(sliderRectangle, "value: ", "", &value, 0.0f, 1.0f);
|
||||
|
||||
// Draw FPS next to outlined color preview
|
||||
DrawFPS(64 + 16, 8);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||