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

This commit is contained in:
Jeffery Myers 2024-06-23 14:07:31 -07:00
commit 81d145fcfe
27 changed files with 1010 additions and 564 deletions

View File

@ -36,7 +36,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT | | [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT |
| [jaylib](https://github.com/electronstudio/jaylib/) | 4.5 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | | [jaylib](https://github.com/electronstudio/jaylib/) | 4.5 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE |
| [raylib-j](https://github.com/CreedVI/Raylib-J) | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | | [raylib-j](https://github.com/CreedVI/Raylib-J) | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib |
| [raylib.jl](https://github.com/irishgreencitrus/raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib | | [Raylib.jl](https://github.com/chengchingwen/Raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib |
| [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** | | [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** |
| [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib | | [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib |
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 4.5 | [Lua](http://www.lua.org) | ISC | | [raylib-lua](https://github.com/TSnake41/raylib-lua) | 4.5 | [Lua](http://www.lua.org) | ISC |

View File

@ -1,4 +1,4 @@
### Config options ### # ## Config options ###
include(CMakeDependentOption) include(CMakeDependentOption)
include(EnumOption) include(EnumOption)
@ -9,14 +9,14 @@ enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0" "Force a specific
# Configuration options # Configuration options
option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN}) option(BUILD_EXAMPLES "Build the examples." ${RAYLIB_IS_MAIN})
option(CUSTOMIZE_BUILD "Show options for customizing your Raylib library build." OFF) option(CUSTOMIZE_BUILD "Show options for customizing your Raylib library build." OFF)
option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF) option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF) option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF) option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
# Shared library is always PIC. Static library should be PIC too if linked into a shared library # Shared library is always PIC. Static library should be PIC too if linked into a shared library
option(WITH_PIC "Compile static library as position-independent code" OFF) option(WITH_PIC "Compile static library as position-independent code" OFF)
option(BUILD_SHARED_LIBS "Build raylib as a shared library" OFF) option(BUILD_SHARED_LIBS "Build raylib as a shared library" OFF)
option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" OFF) option(MACOS_FATLIB "Build fat library for both i386 and x86_64 on macOS" OFF)
cmake_dependent_option(USE_AUDIO "Build raylib with audio module" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(USE_AUDIO "Build raylib with audio module" ON CUSTOMIZE_BUILD ON)
enum_option(USE_EXTERNAL_GLFW "OFF;IF_POSSIBLE;ON" "Link raylib against system GLFW instead of embedded one") enum_option(USE_EXTERNAL_GLFW "OFF;IF_POSSIBLE;ON" "Link raylib against system GLFW instead of embedded one")
@ -28,77 +28,9 @@ option(GLFW_BUILD_X11 "Build the bundled GLFW with X11 support" ON)
option(INCLUDE_EVERYTHING "Include everything disabled by default (for CI usage" OFF) option(INCLUDE_EVERYTHING "Include everything disabled by default (for CI usage" OFF)
set(OFF ${INCLUDE_EVERYTHING} CACHE INTERNAL "Replace any OFF by default with \${OFF} to have it covered by this option") set(OFF ${INCLUDE_EVERYTHING} CACHE INTERNAL "Replace any OFF by default with \${OFF} to have it covered by this option")
# raylib modules included include(ParseConfigHeader)
cmake_dependent_option(SUPPORT_MODULE_RSHAPES "Include module: rshapes" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MODULE_RTEXTURES "Include module: rtextures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MODULE_RTEXT "Include module: rtext" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MODULE_RMODELS "Include module: rmodels" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MODULE_RAUDIO "Include module: raudio" ON CUSTOMIZE_BUILD ON)
# rcore.c foreach(FLAG IN LISTS CONFIG_HEADER_FLAGS)
cmake_dependent_option(SUPPORT_CAMERA_SYSTEM "Provide camera module (rcamera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON CUSTOMIZE_BUILD ON) string(REGEX MATCH "([^=]+)=(.+)" _ ${FLAG})
cmake_dependent_option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag" ON CUSTOMIZE_BUILD ON) cmake_dependent_option(${CMAKE_MATCH_1} "" ${CMAKE_MATCH_2} CUSTOMIZE_BUILD ${CMAKE_MATCH_2})
cmake_dependent_option(SUPPORT_RPRAND_GENERATOR "Include pseudo-random numbers generator (rprand.h), based on Xoshiro128** and SplitMix64" ON CUSTOMIZE_BUILD ON) endforeach()
cmake_dependent_option(SUPPORT_MOUSE_GESTURES "Mouse gestures are directly mapped like touches and processed by gestures system" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_SSH_KEYBOARD_RPI "Reconfigure standard input to receive key inputs, works with SSH connection" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_DEFAULT_FONT "Default font is loaded on window initialization to be available for the user to render simple text. If enabled, uses external module functions to load default raylib font (module: text)" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_SCREEN_CAPTURE "Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_GIF_RECORDING "Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_BUSY_WAIT_LOOP "Use busy wait loop for timing sync instead of a high-resolution timer" OFF CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_EVENTS_WAITING "Wait for events passively (sleeping while no events) instead of polling them actively every frame" OFF CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_WINMM_HIGHRES_TIMER "Setting a higher resolution can improve the accuracy of time-out intervals in wait functions" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_COMPRESSION_API "Support for compression API" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_EVENTS_AUTOMATION "Support automatic generated events, loading and recording of those events when required" OFF CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_CUSTOM_FRAME_CONTROL "Enabling this flag allows manual control of the frame processes, use at your own risk" OFF CUSTOMIZE_BUILD OFF)
# rshapes.c
cmake_dependent_option(SUPPORT_QUADS_DRAW_MODE "Use QUADS instead of TRIANGLES for drawing when possible. Some lines-based shapes could still use lines" ON CUSTOMIZE_BUILD ON)
# rtextures.c
cmake_dependent_option(SUPPORT_IMAGE_EXPORT "Support image exporting to file" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_IMAGE_GENERATION "Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_IMAGE_MANIPULATION "Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_PNG "Support loading PNG as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_DDS "Support loading DDS as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_HDR "Support loading HDR as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_PIC "Support loading PIC as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_PNM "Support loading PNM as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_KTX "Support loading KTX as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_ASTC "Support loading ASTC as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_BMP "Support loading BMP as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_TGA "Support loading TGA as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_JPG "Support loading JPG as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_GIF "Support loading GIF as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_QOI "Support loading QOI as textures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_PSD "Support loading PSD as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_PKM "Support loading PKM as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_PVR "Support loading PVR as textures" ${OFF} CUSTOMIZE_BUILD OFF)
cmake_dependent_option(SUPPORT_FILEFORMAT_SVG "Support loading SVG as textures" ${OFF} CUSTOMIZE_BUILD OFF)
# rtext.c
cmake_dependent_option(SUPPORT_FILEFORMAT_FNT "Support loading fonts in FNT format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_TTF "Support loading font in TTF/OTF format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_TEXT_MANIPULATION "Support text manipulation functions" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FONT_ATLAS_WHITE_REC "Support white rec on font atlas bottom-right corner" ON CUSTOMIZE_BUILD ON)
# rmodels.c
cmake_dependent_option(SUPPORT_MESH_GENERATION "Support procedural mesh generation functions, uses external par_shapes.h library. NOTE: Some generated meshes DO NOT include generated texture coordinates" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_OBJ "Support loading OBJ file format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_MTL "Support loading MTL file format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_IQM "Support loading IQM file format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_GLTF "Support loading GLTF file format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_VOX "Support loading VOX file format" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_M3D "Support loading M3D file format" ON CUSTOMIZE_BUILD ON)
# raudio.c
cmake_dependent_option(SUPPORT_FILEFORMAT_WAV "Support loading WAV for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_OGG "Support loading OGG for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_XM "Support loading XM for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_MOD "Support loading MOD for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_MP3 "Support loading MP3 for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_QOA "Support loading QOA for sound" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_FILEFORMAT_FLAC "Support loading FLAC for sound" ${OFF} CUSTOMIZE_BUILD OFF)
# utils.c
cmake_dependent_option(SUPPORT_STANDARD_FILEIO "Support standard file io library (stdio.h)" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_TRACELOG "Show TraceLog() output messages. NOTE: By default LOG_DEBUG traces not shown" ON CUSTOMIZE_BUILD ON)

View File

@ -3,126 +3,22 @@ target_compile_definitions("raylib" PUBLIC "${PLATFORM_CPP}")
target_compile_definitions("raylib" PUBLIC "${GRAPHICS}") target_compile_definitions("raylib" PUBLIC "${GRAPHICS}")
function(define_if target variable) function(define_if target variable)
if (${${variable}}) if(${${variable}})
message(STATUS "${variable}=${${variable}}") message(STATUS "${variable}=${${variable}}")
target_compile_definitions(${target} PUBLIC "${variable}") target_compile_definitions(${target} PRIVATE "${variable}")
endif () endif()
endfunction() endfunction()
if (${CUSTOMIZE_BUILD}) if(${CUSTOMIZE_BUILD})
target_compile_definitions("raylib" PUBLIC EXTERNAL_CONFIG_FLAGS) target_compile_definitions("raylib" PRIVATE EXTERNAL_CONFIG_FLAGS)
define_if("raylib" USE_AUDIO) define_if("raylib" USE_AUDIO)
define_if("raylib" SUPPORT_MODULE_RSHAPES)
define_if("raylib" SUPPORT_MODULE_RTEXTURES)
define_if("raylib" SUPPORT_MODULE_RTEXT)
define_if("raylib" SUPPORT_MODULE_RMODELS)
define_if("raylib" SUPPORT_MODULE_RAUDIO)
define_if("raylib" SUPPORT_CAMERA_SYSTEM)
define_if("raylib" SUPPORT_GESTURES_SYSTEM)
define_if("raylib" SUPPORT_MOUSE_GESTURES)
define_if("raylib" SUPPORT_SSH_KEYBOARD_RPI)
define_if("raylib" SUPPORT_DEFAULT_FONT)
define_if("raylib" SUPPORT_SCREEN_CAPTURE)
define_if("raylib" SUPPORT_GIF_RECORDING)
define_if("raylib" SUPPORT_BUSY_WAIT_LOOP)
define_if("raylib" SUPPORT_EVENTS_WAITING)
define_if("raylib" SUPPORT_WINMM_HIGHRES_TIMER)
define_if("raylib" SUPPORT_COMPRESSION_API)
define_if("raylib" SUPPORT_EVENTS_AUTOMATION)
define_if("raylib" SUPPORT_CUSTOM_FRAME_CONTROL)
define_if("raylib" SUPPORT_QUADS_DRAW_MODE)
define_if("raylib" SUPPORT_IMAGE_EXPORT)
define_if("raylib" SUPPORT_IMAGE_GENERATION)
define_if("raylib" SUPPORT_IMAGE_MANIPULATION)
define_if("raylib" SUPPORT_FILEFORMAT_PNG)
define_if("raylib" SUPPORT_FILEFORMAT_DDS)
define_if("raylib" SUPPORT_FILEFORMAT_HDR)
define_if("raylib" SUPPORT_FILEFORMAT_PIC)
define_if("raylib" SUPPORT_FILEFORMAT_PNM)
define_if("raylib" SUPPORT_FILEFORMAT_KTX)
define_if("raylib" SUPPORT_FILEFORMAT_ASTC)
define_if("raylib" SUPPORT_FILEFORMAT_BMP)
define_if("raylib" SUPPORT_FILEFORMAT_TGA)
define_if("raylib" SUPPORT_FILEFORMAT_JPG)
define_if("raylib" SUPPORT_FILEFORMAT_GIF)
define_if("raylib" SUPPORT_FILEFORMAT_QOI)
define_if("raylib" SUPPORT_FILEFORMAT_PSD)
define_if("raylib" SUPPORT_FILEFORMAT_PKM)
define_if("raylib" SUPPORT_FILEFORMAT_PVR)
define_if("raylib" SUPPORT_FILEFORMAT_SVG)
define_if("raylib" SUPPORT_FILEFORMAT_FNT)
define_if("raylib" SUPPORT_FILEFORMAT_TTF)
define_if("raylib" SUPPORT_TEXT_MANIPULATION)
define_if("raylib" SUPPORT_MESH_GENERATION)
define_if("raylib" SUPPORT_FILEFORMAT_OBJ)
define_if("raylib" SUPPORT_FILEFORMAT_MTL)
define_if("raylib" SUPPORT_FILEFORMAT_IQM)
define_if("raylib" SUPPORT_FILEFORMAT_GLTF)
define_if("raylib" SUPPORT_FILEFORMAT_VOX)
define_if("raylib" SUPPORT_FILEFORMAT_M3D)
define_if("raylib" SUPPORT_FILEFORMAT_WAV)
define_if("raylib" SUPPORT_FILEFORMAT_OGG)
define_if("raylib" SUPPORT_FILEFORMAT_XM)
define_if("raylib" SUPPORT_FILEFORMAT_MOD)
define_if("raylib" SUPPORT_FILEFORMAT_MP3)
define_if("raylib" SUPPORT_FILEFORMAT_QOA)
define_if("raylib" SUPPORT_FILEFORMAT_FLAC)
define_if("raylib" SUPPORT_STANDARD_FILEIO)
define_if("raylib" SUPPORT_TRACELOG)
if (UNIX AND NOT APPLE) foreach(FLAG IN LISTS CONFIG_HEADER_FLAGS)
target_compile_definitions("raylib" PUBLIC "MAX_FILEPATH_LENGTH=4096") string(REGEX MATCH "([^=]+)=(.+)" _ ${FLAG})
else () define_if("raylib" ${CMAKE_MATCH_1})
target_compile_definitions("raylib" PUBLIC "MAX_FILEPATH_LENGTH=512") endforeach()
endif ()
target_compile_definitions("raylib" PUBLIC "MAX_GAMEPADS=4")
target_compile_definitions("raylib" PUBLIC "MAX_GAMEPAD_AXIS=8")
target_compile_definitions("raylib" PUBLIC "MAX_GAMEPAD_BUTTONS=32")
target_compile_definitions("raylib" PUBLIC "MAX_TOUCH_POINTS=10")
target_compile_definitions("raylib" PUBLIC "MAX_KEY_PRESSED_QUEUE=16")
target_compile_definitions("raylib" PUBLIC "STORAGE_DATA_FILE=\"storage.data\"")
target_compile_definitions("raylib" PUBLIC "MAX_CHAR_PRESSED_QUEUE=16")
target_compile_definitions("raylib" PUBLIC "MAX_DECOMPRESSION_SIZE=64")
if (${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_33" OR ${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_11")
target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_BUFFER_ELEMENTS=8192")
elseif (${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES2")
target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_BUFFER_ELEMENTS=2048")
endif ()
target_compile_definitions("raylib" PUBLIC "DEFAULT_BATCH_DRAWCALLS=256")
target_compile_definitions("raylib" PUBLIC "MAX_MATRIX_STACK_SIZE=32")
target_compile_definitions("raylib" PUBLIC "MAX_SHADER_LOCATIONS=32")
target_compile_definitions("raylib" PUBLIC "MAX_MATERIAL_MAPS=12")
target_compile_definitions("raylib" PUBLIC "RL_CULL_DISTANCE_NEAR=0.01")
target_compile_definitions("raylib" PUBLIC "RL_CULL_DISTANCE_FAR=1000.0")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION=0")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD=1")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL=2")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR=3")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT=4")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2=5")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION=\"vertexPosition\"")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD=\"vertexTexCoord\"")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL=\"vertexNormal\"")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR=\"vertexColor\"")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT=\"vertexTangent\"")
target_compile_definitions("raylib" PUBLIC "RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2=\"vertexTexCoord2\"")
target_compile_definitions("raylib" PUBLIC "MAX_TEXT_BUFFER_LENGTH=1024")
target_compile_definitions("raylib" PUBLIC "MAX_TEXT_UNICODE_CHARS=512")
target_compile_definitions("raylib" PUBLIC "MAX_TEXTSPLIT_COUNT=128")
target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_FORMAT=ma_format_f32")
target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_CHANNELS=2")
target_compile_definitions("raylib" PUBLIC "AUDIO_DEVICE_SAMPLE_RATE=44100")
target_compile_definitions("raylib" PUBLIC "DEFAULT_AUDIO_BUFFER_SIZE=4096")
target_compile_definitions("raylib" PUBLIC "MAX_TRACELOG_MSG_LENGTH=128")
target_compile_definitions("raylib" PUBLIC "MAX_UWP_MESSAGES=512")
endif ()
foreach(VALUE IN LISTS CONFIG_HEADER_VALUES)
target_compile_definitions("raylib" PRIVATE ${VALUE})
endforeach()
endif()

View File

@ -58,8 +58,9 @@ if (${PLATFORM} MATCHES "Desktop")
elseif (${PLATFORM} MATCHES "Web") elseif (${PLATFORM} MATCHES "Web")
set(PLATFORM_CPP "PLATFORM_WEB") set(PLATFORM_CPP "PLATFORM_WEB")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") if(NOT GRAPHICS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 --profiling") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
endif()
set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
elseif (${PLATFORM} MATCHES "Android") elseif (${PLATFORM} MATCHES "Android")

View File

@ -0,0 +1,17 @@
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/src/config.h" CONFIG_HEADER_CONTENT)
set(BLANK_OR_BACKSLASH_PATTERN "[ \t\r\n\\]")
set(VALID_IDENTIFIER_PATTERN "[A-Za-z_]+[A-Za-z_0-9]*")
set(VALID_VALUE_PATTERN [=["?[A-Za-z_0-9.-]+"?]=]) # not really correct but does the job since the config.h file hopefully will have been checked by a C preprocessor.
set(MACRO_REGEX "(//${BLANK_OR_BACKSLASH_PATTERN}*)?\#define${BLANK_OR_BACKSLASH_PATTERN}+(${VALID_IDENTIFIER_PATTERN})${BLANK_OR_BACKSLASH_PATTERN}+(${VALID_VALUE_PATTERN})")
string(REGEX MATCHALL ${MACRO_REGEX} MACRO_LIST ${CONFIG_HEADER_CONTENT})
set(CONFIG_HEADER_FLAGS ${MACRO_LIST})
list(FILTER CONFIG_HEADER_FLAGS INCLUDE REGEX "^.+SUPPORT_")
list(TRANSFORM CONFIG_HEADER_FLAGS REPLACE ${MACRO_REGEX} [[\2=OFF]] REGEX "^//")
list(TRANSFORM CONFIG_HEADER_FLAGS REPLACE ${MACRO_REGEX} [[\2=ON]])
set(CONFIG_HEADER_VALUES ${MACRO_LIST})
list(FILTER CONFIG_HEADER_VALUES EXCLUDE REGEX "(^.+SUPPORT_)|(^//)")
list(TRANSFORM CONFIG_HEADER_VALUES REPLACE ${MACRO_REGEX} [[\2=\3]])

View File

@ -96,10 +96,9 @@ if (${PLATFORM} MATCHES "Android")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c)
elseif (${PLATFORM} MATCHES "Web") elseif (${PLATFORM} MATCHES "Web")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os")
# Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads # Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1 -s ASYNCIFY -s ALLOW_MEMORY_GROWTH=1 --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
set(CMAKE_EXECUTABLE_SUFFIX ".html") set(CMAKE_EXECUTABLE_SUFFIX ".html")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)

View File

@ -75,6 +75,7 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.Reso
const install_cmd = b.addInstallArtifact(exe, .{}); const install_cmd = b.addInstallArtifact(exe, .{});
const run_cmd = b.addRunArtifact(exe); const run_cmd = b.addRunArtifact(exe);
run_cmd.cwd = b.path(module);
run_cmd.step.dependOn(&install_cmd.step); run_cmd.step.dependOn(&install_cmd.step);
const run_step = b.step(name, name); const run_step = b.step(name, name);

View File

@ -89,6 +89,8 @@ int main()
}; };
// Pick a color with a hue depending on cube position for the rainbow color effect // Pick a color with a hue depending on cube position for the rainbow color effect
// NOTE: This function is quite costly to be done per cube and frame,
// pre-catching the results into a separate array could improve performance
Color cubeColor = ColorFromHSV((float)(((x + y + z)*18)%360), 0.75f, 0.9f); Color cubeColor = ColorFromHSV((float)(((x + y + z)*18)%360), 0.75f, 0.9f);
// Calculate cube size // Calculate cube size

View File

@ -22,15 +22,12 @@ out vec3 fragNormal;
void main() void main()
{ {
// Compute MVP for current instance
mat4 mvpi = mvp*instanceTransform;
// Send vertex attributes to fragment shader // Send vertex attributes to fragment shader
fragPosition = vec3(mvpi*vec4(vertexPosition, 1.0)); fragPosition = vec3(instanceTransform*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord; fragTexCoord = vertexTexCoord;
//fragColor = vertexColor; //fragColor = vertexColor;
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0))); fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
// Calculate final vertex position // Calculate final vertex position, note that we multiply mvp by instanceTransform
gl_Position = mvpi*vec4(vertexPosition, 1.0); gl_Position = mvp*instanceTransform*vec4(vertexPosition, 1.0);
} }

View File

@ -56,6 +56,10 @@ int main(void)
{ 710.0f, 260.0f }, { 710.0f, 260.0f },
}; };
// Array required for spline bezier-cubic,
// including control points interleaved with start-end segment points
Vector2 pointsInterleaved[3*(MAX_SPLINE_POINTS - 1) + 1] = { 0 };
int pointCount = 5; int pointCount = 5;
int selectedPoint = -1; int selectedPoint = -1;
int focusedPoint = -1; int focusedPoint = -1;
@ -63,7 +67,7 @@ int main(void)
Vector2 *focusedControlPoint = NULL; Vector2 *focusedControlPoint = NULL;
// Cubic Bezier control points initialization // Cubic Bezier control points initialization
ControlPoint control[MAX_SPLINE_POINTS] = { 0 }; ControlPoint control[MAX_SPLINE_POINTS-1] = { 0 };
for (int i = 0; i < pointCount - 1; i++) for (int i = 0; i < pointCount - 1; i++)
{ {
control[i].start = (Vector2){ points[i].x + 50, points[i].y }; control[i].start = (Vector2){ points[i].x + 50, points[i].y };
@ -88,6 +92,9 @@ int main(void)
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_SPLINE_POINTS)) if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_SPLINE_POINTS))
{ {
points[pointCount] = GetMousePosition(); points[pointCount] = GetMousePosition();
int i = pointCount - 1;
control[i].start = (Vector2){ points[i].x + 50, points[i].y };
control[i].end = (Vector2){ points[i + 1].x - 50, points[i + 1].y };
pointCount++; pointCount++;
} }
@ -114,7 +121,7 @@ int main(void)
if ((splineTypeActive == SPLINE_BEZIER) && (focusedPoint == -1)) if ((splineTypeActive == SPLINE_BEZIER) && (focusedPoint == -1))
{ {
// Spline control point focus and selection logic // Spline control point focus and selection logic
for (int i = 0; i < pointCount; i++) for (int i = 0; i < pointCount - 1; i++)
{ {
if (CheckCollisionPointCircle(GetMousePosition(), control[i].start, 6.0f)) if (CheckCollisionPointCircle(GetMousePosition(), control[i].start, 6.0f))
{ {
@ -185,13 +192,32 @@ int main(void)
} }
else if (splineTypeActive == SPLINE_BEZIER) else if (splineTypeActive == SPLINE_BEZIER)
{ {
// NOTE: Cubic-bezier spline requires the 2 control points of each segnment to be
// provided interleaved with the start and end point of every segment
for (int i = 0; i < (pointCount - 1); i++)
{
pointsInterleaved[3*i] = points[i];
pointsInterleaved[3*i + 1] = control[i].start;
pointsInterleaved[3*i + 2] = control[i].end;
}
pointsInterleaved[3*(pointCount - 1)] = points[pointCount - 1];
// Draw spline: cubic-bezier (with control points) // Draw spline: cubic-bezier (with control points)
for (int i = 0; i < pointCount - 1; i++) DrawSplineBezierCubic(pointsInterleaved, 3*(pointCount - 1) + 1, splineThickness, RED);
/*
for (int i = 0; i < 3*(pointCount - 1); i += 3)
{ {
// Drawing individual segments, not considering thickness connection compensation // Drawing individual segments, not considering thickness connection compensation
DrawSplineSegmentBezierCubic(points[i], control[i].start, control[i].end, points[i + 1], splineThickness, RED); DrawSplineSegmentBezierCubic(pointsInterleaved[i], pointsInterleaved[i + 1], pointsInterleaved[i + 2], pointsInterleaved[i + 3], splineThickness, MAROON);
}
*/
// Every cubic bezier point should have two control points // Draw spline control points
for (int i = 0; i < pointCount - 1; i++)
{
// Every cubic bezier point have two control points
DrawCircleV(control[i].start, 6, GOLD); DrawCircleV(control[i].start, 6, GOLD);
DrawCircleV(control[i].end, 6, GOLD); DrawCircleV(control[i].end, 6, GOLD);
if (focusedControlPoint == &control[i].start) DrawCircleV(control[i].start, 8, GREEN); if (focusedControlPoint == &control[i].start) DrawCircleV(control[i].start, 8, GREEN);
@ -244,4 +270,4 @@ int main(void)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -5345,7 +5345,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6022,7 +6022,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6041,7 +6041,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6145,7 +6145,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6168,7 +6168,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6191,7 +6191,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6214,7 +6214,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6237,7 +6237,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6644,7 +6644,7 @@
"name": "point" "name": "point"
}, },
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -7359,7 +7359,7 @@
"name": "image" "name": "image"
}, },
{ {
"type": "float*", "type": "float *",
"name": "kernel" "name": "kernel"
}, },
{ {
@ -8013,6 +8013,141 @@
} }
] ]
}, },
{
"name": "ImageDrawTriangle",
"description": "Draw triangle within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2",
"name": "v1"
},
{
"type": "Vector2",
"name": "v2"
},
{
"type": "Vector2",
"name": "v3"
},
{
"type": "Color",
"name": "color"
}
]
},
{
"name": "ImageDrawTriangleEx",
"description": "Draw triangle with interpolated colors within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2",
"name": "v1"
},
{
"type": "Vector2",
"name": "v2"
},
{
"type": "Vector2",
"name": "v3"
},
{
"type": "Color",
"name": "c1"
},
{
"type": "Color",
"name": "c2"
},
{
"type": "Color",
"name": "c3"
}
]
},
{
"name": "ImageDrawTriangleLines",
"description": "Draw triangle outline within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2",
"name": "v1"
},
{
"type": "Vector2",
"name": "v2"
},
{
"type": "Vector2",
"name": "v3"
},
{
"type": "Color",
"name": "color"
}
]
},
{
"name": "ImageDrawTriangleFan",
"description": "Draw a triangle fan defined by points within an image (first vertex is the center)",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2 *",
"name": "points"
},
{
"type": "int",
"name": "pointCount"
},
{
"type": "Color",
"name": "color"
}
]
},
{
"name": "ImageDrawTriangleStrip",
"description": "Draw a triangle strip defined by points within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2 *",
"name": "points"
},
{
"type": "int",
"name": "pointCount"
},
{
"type": "Color",
"name": "color"
}
]
},
{ {
"name": "ImageDraw", "name": "ImageDraw",
"description": "Draw a source image within a destination image (tint applied to source)", "description": "Draw a source image within a destination image (tint applied to source)",
@ -9613,7 +9748,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector3 *", "type": "const Vector3 *",
"name": "points" "name": "points"
}, },
{ {

View File

@ -4636,7 +4636,7 @@ return {
description = "Draw lines sequence (using gl lines)", description = "Draw lines sequence (using gl lines)",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
@ -4947,7 +4947,7 @@ return {
description = "Draw a triangle fan defined by points (first vertex is the center)", description = "Draw a triangle fan defined by points (first vertex is the center)",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
@ -4957,7 +4957,7 @@ return {
description = "Draw a triangle strip defined by points", description = "Draw a triangle strip defined by points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
@ -5004,7 +5004,7 @@ return {
description = "Draw spline: Linear, minimum 2 points", description = "Draw spline: Linear, minimum 2 points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5015,7 +5015,7 @@ return {
description = "Draw spline: B-Spline, minimum 4 points", description = "Draw spline: B-Spline, minimum 4 points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5026,7 +5026,7 @@ return {
description = "Draw spline: Catmull-Rom, minimum 4 points", description = "Draw spline: Catmull-Rom, minimum 4 points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5037,7 +5037,7 @@ return {
description = "Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]", description = "Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5048,7 +5048,7 @@ return {
description = "Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]", description = "Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5239,7 +5239,7 @@ return {
returnType = "bool", returnType = "bool",
params = { params = {
{type = "Vector2", name = "point"}, {type = "Vector2", name = "point"},
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"} {type = "int", name = "pointCount"}
} }
}, },
@ -5621,7 +5621,7 @@ return {
returnType = "void", returnType = "void",
params = { params = {
{type = "Image *", name = "image"}, {type = "Image *", name = "image"},
{type = "float*", name = "kernel"}, {type = "float *", name = "kernel"},
{type = "int", name = "kernelSize"} {type = "int", name = "kernelSize"}
} }
}, },
@ -5970,6 +5970,66 @@ return {
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
}, },
{
name = "ImageDrawTriangle",
description = "Draw triangle within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2", name = "v1"},
{type = "Vector2", name = "v2"},
{type = "Vector2", name = "v3"},
{type = "Color", name = "color"}
}
},
{
name = "ImageDrawTriangleEx",
description = "Draw triangle with interpolated colors within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2", name = "v1"},
{type = "Vector2", name = "v2"},
{type = "Vector2", name = "v3"},
{type = "Color", name = "c1"},
{type = "Color", name = "c2"},
{type = "Color", name = "c3"}
}
},
{
name = "ImageDrawTriangleLines",
description = "Draw triangle outline within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2", name = "v1"},
{type = "Vector2", name = "v2"},
{type = "Vector2", name = "v3"},
{type = "Color", name = "color"}
}
},
{
name = "ImageDrawTriangleFan",
description = "Draw a triangle fan defined by points within an image (first vertex is the center)",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2 *", name = "points"},
{type = "int", name = "pointCount"},
{type = "Color", name = "color"}
}
},
{
name = "ImageDrawTriangleStrip",
description = "Draw a triangle strip defined by points within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2 *", name = "points"},
{type = "int", name = "pointCount"},
{type = "Color", name = "color"}
}
},
{ {
name = "ImageDraw", name = "ImageDraw",
description = "Draw a source image within a destination image (tint applied to source)", description = "Draw a source image within a destination image (tint applied to source)",
@ -6855,7 +6915,7 @@ return {
description = "Draw a triangle strip defined by points", description = "Draw a triangle strip defined by points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector3 *", name = "points"}, {type = "const Vector3 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }

File diff suppressed because it is too large Load Diff

View File

@ -670,7 +670,7 @@
<Param type="unsigned int" name="frames" desc="" /> <Param type="unsigned int" name="frames" desc="" />
</Callback> </Callback>
</Callbacks> </Callbacks>
<Functions count="566"> <Functions count="571">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context"> <Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" /> <Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" /> <Param type="int" name="height" desc="" />
@ -1317,7 +1317,7 @@
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawLineStrip" retType="void" paramCount="3" desc="Draw lines sequence (using gl lines)"> <Function name="DrawLineStrip" retType="void" paramCount="3" desc="Draw lines sequence (using gl lines)">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
@ -1493,12 +1493,12 @@
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawTriangleFan" retType="void" paramCount="3" desc="Draw a triangle fan defined by points (first vertex is the center)"> <Function name="DrawTriangleFan" retType="void" paramCount="3" desc="Draw a triangle fan defined by points (first vertex is the center)">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawTriangleStrip" retType="void" paramCount="3" desc="Draw a triangle strip defined by points"> <Function name="DrawTriangleStrip" retType="void" paramCount="3" desc="Draw a triangle strip defined by points">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
@ -1525,31 +1525,31 @@
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineLinear" retType="void" paramCount="4" desc="Draw spline: Linear, minimum 2 points"> <Function name="DrawSplineLinear" retType="void" paramCount="4" desc="Draw spline: Linear, minimum 2 points">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineBasis" retType="void" paramCount="4" desc="Draw spline: B-Spline, minimum 4 points"> <Function name="DrawSplineBasis" retType="void" paramCount="4" desc="Draw spline: B-Spline, minimum 4 points">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineCatmullRom" retType="void" paramCount="4" desc="Draw spline: Catmull-Rom, minimum 4 points"> <Function name="DrawSplineCatmullRom" retType="void" paramCount="4" desc="Draw spline: Catmull-Rom, minimum 4 points">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineBezierQuadratic" retType="void" paramCount="4" desc="Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]"> <Function name="DrawSplineBezierQuadratic" retType="void" paramCount="4" desc="Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineBezierCubic" retType="void" paramCount="4" desc="Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]"> <Function name="DrawSplineBezierCubic" retType="void" paramCount="4" desc="Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
@ -1655,7 +1655,7 @@
</Function> </Function>
<Function name="CheckCollisionPointPoly" retType="bool" paramCount="3" desc="Check if point is within a polygon described by array of vertices"> <Function name="CheckCollisionPointPoly" retType="bool" paramCount="3" desc="Check if point is within a polygon described by array of vertices">
<Param type="Vector2" name="point" desc="" /> <Param type="Vector2" name="point" desc="" />
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
</Function> </Function>
<Function name="CheckCollisionLines" retType="bool" paramCount="5" desc="Check the collision between two lines defined by two points each, returns collision point by reference"> <Function name="CheckCollisionLines" retType="bool" paramCount="5" desc="Check the collision between two lines defined by two points each, returns collision point by reference">
@ -1844,7 +1844,7 @@
</Function> </Function>
<Function name="ImageKernelConvolution" retType="void" paramCount="3" desc="Apply Custom Square image convolution kernel"> <Function name="ImageKernelConvolution" retType="void" paramCount="3" desc="Apply Custom Square image convolution kernel">
<Param type="Image *" name="image" desc="" /> <Param type="Image *" name="image" desc="" />
<Param type="float*" name="kernel" desc="" /> <Param type="float *" name="kernel" desc="" />
<Param type="int" name="kernelSize" desc="" /> <Param type="int" name="kernelSize" desc="" />
</Function> </Function>
<Function name="ImageResize" retType="void" paramCount="3" desc="Resize image (Bicubic scaling algorithm)"> <Function name="ImageResize" retType="void" paramCount="3" desc="Resize image (Bicubic scaling algorithm)">
@ -2017,6 +2017,41 @@
<Param type="int" name="thick" desc="" /> <Param type="int" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="ImageDrawTriangle" retType="void" paramCount="5" desc="Draw triangle within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="v1" desc="" />
<Param type="Vector2" name="v2" desc="" />
<Param type="Vector2" name="v3" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawTriangleEx" retType="void" paramCount="7" desc="Draw triangle with interpolated colors within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="v1" desc="" />
<Param type="Vector2" name="v2" desc="" />
<Param type="Vector2" name="v3" desc="" />
<Param type="Color" name="c1" desc="" />
<Param type="Color" name="c2" desc="" />
<Param type="Color" name="c3" desc="" />
</Function>
<Function name="ImageDrawTriangleLines" retType="void" paramCount="5" desc="Draw triangle outline within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="v1" desc="" />
<Param type="Vector2" name="v2" desc="" />
<Param type="Vector2" name="v3" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawTriangleFan" retType="void" paramCount="4" desc="Draw a triangle fan defined by points within an image (first vertex is the center)">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawTriangleStrip" retType="void" paramCount="4" desc="Draw a triangle strip defined by points within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDraw" retType="void" paramCount="5" desc="Draw a source image within a destination image (tint applied to source)"> <Function name="ImageDraw" retType="void" paramCount="5" desc="Draw a source image within a destination image (tint applied to source)">
<Param type="Image *" name="dst" desc="" /> <Param type="Image *" name="dst" desc="" />
<Param type="Image" name="src" desc="" /> <Param type="Image" name="src" desc="" />
@ -2440,7 +2475,7 @@
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawTriangleStrip3D" retType="void" paramCount="3" desc="Draw a triangle strip defined by points"> <Function name="DrawTriangleStrip3D" retType="void" paramCount="3" desc="Draw a triangle strip defined by points">
<Param type="Vector3 *" name="points" desc="" /> <Param type="const Vector3 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>

View File

@ -1100,7 +1100,7 @@ static void ShowCommandLineInfo(void)
printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n"); printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n");
printf(" -f, --format <type> : Define output format for parser data.\n"); printf(" -f, --format <type> : Define output format for parser data.\n");
printf(" Supported types: DEFAULT, JSON, XML, LUA, CODE\n\n"); printf(" Supported types: DEFAULT, JSON, XML, LUA, CODE\n\n");
printf(" -d, --define <DEF> : Define functions specifiers (i.e. RLAPI for raylib.h, RMDEF for raymath.h, etc.)\n"); printf(" -d, --define <DEF> : Define functions specifiers (i.e. RLAPI for raylib.h, RMAPI for raymath.h, etc.)\n");
printf(" NOTE: If no specifier defined, defaults to: RLAPI\n\n"); printf(" NOTE: If no specifier defined, defaults to: RLAPI\n\n");
printf(" -t, --truncate <after> : Define string to truncate input after (i.e. \"RLGL IMPLEMENTATION\" for rlgl.h)\n"); printf(" -t, --truncate <after> : Define string to truncate input after (i.e. \"RLGL IMPLEMENTATION\" for rlgl.h)\n");
printf(" NOTE: If not specified, the full input file is parsed.\n\n"); printf(" NOTE: If not specified, the full input file is parsed.\n\n");
@ -1110,7 +1110,7 @@ static void ShowCommandLineInfo(void)
printf(" Process <raylib.h> to generate <api.json>\n\n"); printf(" Process <raylib.h> to generate <api.json>\n\n");
printf(" > raylib_parser --output raylib_data.info --format XML\n"); printf(" > raylib_parser --output raylib_data.info --format XML\n");
printf(" Process <raylib.h> to generate <raylib_data.info> as XML text data\n\n"); printf(" Process <raylib.h> to generate <raylib_data.info> as XML text data\n\n");
printf(" > raylib_parser --input raymath.h --output raymath_data.info --format XML\n"); printf(" > raylib_parser --input raymath.h --output raymath_data.info --format XML --define RMAPI\n");
printf(" Process <raymath.h> to generate <raymath_data.info> as XML text data\n\n"); printf(" Process <raymath.h> to generate <raymath_data.info> as XML text data\n\n");
} }

View File

@ -69,7 +69,10 @@ else()
endif() endif()
if (${PLATFORM} MATCHES "Web") if (${PLATFORM} MATCHES "Web")
target_link_options(raylib PRIVATE "-sUSE_GLFW=3") target_link_options(raylib PUBLIC "-sUSE_GLFW=3")
if(${GRAPHICS} MATCHES "GRAPHICS_API_OPENGL_ES3")
target_link_options(raylib PUBLIC "-sFULL_ES3")
endif()
endif() endif()
set_target_properties(raylib PROPERTIES set_target_properties(raylib PROPERTIES

View File

@ -316,7 +316,7 @@ endif
# -D_GNU_SOURCE access to lots of nonstandard GNU/Linux extension functions # -D_GNU_SOURCE access to lots of nonstandard GNU/Linux extension functions
# -Werror=pointer-arith catch unportable code that does direct arithmetic on void pointers # -Werror=pointer-arith catch unportable code that does direct arithmetic on void pointers
# -fno-strict-aliasing jar_xm.h does shady stuff (breaks strict aliasing) # -fno-strict-aliasing jar_xm.h does shady stuff (breaks strict aliasing)
CFLAGS = -Wall -D_GNU_SOURCE -D$(PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing $(CUSTOM_CFLAGS) CFLAGS = -Wall -D_GNU_SOURCE -D$(PLATFORM) -D$(GRAPHICS) -Wno-missing-braces -Werror=pointer-arith -fno-strict-aliasing
ifneq ($(RAYLIB_CONFIG_FLAGS), NONE) ifneq ($(RAYLIB_CONFIG_FLAGS), NONE)
CFLAGS += -DEXTERNAL_CONFIG_FLAGS $(RAYLIB_CONFIG_FLAGS) CFLAGS += -DEXTERNAL_CONFIG_FLAGS $(RAYLIB_CONFIG_FLAGS)
@ -449,6 +449,8 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
endif endif
endif endif
CFLAGS += $(CUSTOM_CFLAGS)
# Define include paths for required headers: INCLUDE_PATHS # Define include paths for required headers: INCLUDE_PATHS
# NOTE: Several external required libraries (stb and others) # NOTE: Several external required libraries (stb and others)
#------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------

View File

@ -217,6 +217,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
}, },
} }
raylib.addIncludePath(b.path("src"));
raylib.root_module.addCSourceFiles(.{ raylib.root_module.addCSourceFiles(.{
.root = b.path("src"), .root = b.path("src"),
.files = c_source_files.items, .files = c_source_files.items,

View File

@ -171,6 +171,10 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
*width = header->width; *width = header->width;
*height = header->height; *height = header->height;
if (*width % 4 != 0) LOG("WARNING: IMAGE: DDS file width must be multiple of 4. Image will not display correctly");
if (*height % 4 != 0) LOG("WARNING: IMAGE: DDS file height must be multiple of 4. Image will not display correctly");
image_pixel_size = header->width*header->height; image_pixel_size = header->width*header->height;
if (header->mipmap_count == 0) *mips = 1; // Parameter not used if (header->mipmap_count == 0) *mips = 1; // Parameter not used

View File

@ -666,6 +666,9 @@ void SetWindowMaxSize(int width, int height)
// Set window dimensions // Set window dimensions
void SetWindowSize(int width, int height) void SetWindowSize(int width, int height)
{ {
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
glfwSetWindowSize(platform.handle, width, height); glfwSetWindowSize(platform.handle, width, height);
} }

View File

@ -1304,8 +1304,8 @@ float *LoadWaveSamples(Wave wave)
for (unsigned int i = 0; i < wave.frameCount*wave.channels; i++) for (unsigned int i = 0; i < wave.frameCount*wave.channels; i++)
{ {
if (wave.sampleSize == 8) samples[i] = (float)(((unsigned char *)wave.data)[i] - 127)/256.0f; if (wave.sampleSize == 8) samples[i] = (float)(((unsigned char *)wave.data)[i] - 128)/128.0f;
else if (wave.sampleSize == 16) samples[i] = (float)(((short *)wave.data)[i])/32767.0f; else if (wave.sampleSize == 16) samples[i] = (float)(((short *)wave.data)[i])/32768.0f;
else if (wave.sampleSize == 32) samples[i] = ((float *)wave.data)[i]; else if (wave.sampleSize == 32) samples[i] = ((float *)wave.data)[i];
} }
@ -1428,7 +1428,9 @@ Music LoadMusicStream(const char *fileName)
{ {
music.ctxType = MUSIC_AUDIO_FLAC; music.ctxType = MUSIC_AUDIO_FLAC;
music.ctxData = ctxFlac; music.ctxData = ctxFlac;
music.stream = LoadAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels); int sampleSize = ctxFlac->bitsPerSample;
if (ctxFlac->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream()
music.stream = LoadAudioStream(ctxFlac->sampleRate, sampleSize, ctxFlac->channels);
music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount; music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount;
music.looping = true; // Looping enabled by default music.looping = true; // Looping enabled by default
musicLoaded = true; musicLoaded = true;

View File

@ -1141,7 +1141,7 @@ RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize
// Automation events functionality // Automation events functionality
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file
RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file
RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to
RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
@ -1233,7 +1233,7 @@ RLAPI void DrawPixelV(Vector2 position, Color color);
RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines) RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines)
RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads) RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads)
RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines) RLAPI void DrawLineStrip(const Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines)
RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle
@ -1260,18 +1260,18 @@ RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segment
RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!)
RLAPI void DrawTriangleFan(Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) RLAPI void DrawTriangleFan(const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
RLAPI void DrawTriangleStrip(Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points RLAPI void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
// Splines drawing functions // Splines drawing functions
RLAPI void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
RLAPI void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
RLAPI void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
RLAPI void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
RLAPI void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points
RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points
RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points
@ -1292,7 +1292,7 @@ RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec);
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
RLAPI bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices RLAPI bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices
RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2] RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
@ -1342,10 +1342,10 @@ RLAPI void ImageAlphaClear(Image *image, Color color, float threshold);
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel
RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation
RLAPI void ImageKernelConvolution(Image *image, float* kernel, int kernelSize); // Apply Custom Square image convolution kernel RLAPI void ImageKernelConvolution(Image *image, float *kernel, int kernelSize); // Apply Custom Square image convolution kernel
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm)
RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm)
RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color
RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
@ -1381,6 +1381,11 @@ RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int hei
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image
RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image
RLAPI void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image
RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image
RLAPI void ImageDrawTriangleFan(Image *dst, Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
RLAPI void ImageDrawTriangleStrip(Image *dst, Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source)
RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination) RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination)
RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination) RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination)
@ -1436,7 +1441,7 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
// Font loading/unloading functions // Font loading/unloading functions
RLAPI Font GetFontDefault(void); // Get the default Font RLAPI Font GetFontDefault(void); // Get the default Font
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
RLAPI bool IsFontReady(Font font); // Check if a font is ready RLAPI bool IsFontReady(Font font); // Check if a font is ready
@ -1504,7 +1509,7 @@ RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color);
RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line
RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points RLAPI void DrawTriangleStrip3D(const Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires

View File

@ -4518,7 +4518,7 @@ Matrix rlGetMatrixTransform(void)
} }
// Get internal projection matrix for stereo render (selected eye) // Get internal projection matrix for stereo render (selected eye)
RLAPI Matrix rlGetMatrixProjectionStereo(int eye) Matrix rlGetMatrixProjectionStereo(int eye)
{ {
Matrix mat = rlMatrixIdentity(); Matrix mat = rlMatrixIdentity();
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
@ -4528,7 +4528,7 @@ RLAPI Matrix rlGetMatrixProjectionStereo(int eye)
} }
// Get internal view offset matrix for stereo render (selected eye) // Get internal view offset matrix for stereo render (selected eye)
RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye) Matrix rlGetMatrixViewOffsetStereo(int eye)
{ {
Matrix mat = rlMatrixIdentity(); Matrix mat = rlMatrixIdentity();
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)

View File

@ -226,7 +226,7 @@ void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color)
} }
// Draw a triangle strip defined by points // Draw a triangle strip defined by points
void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color) void DrawTriangleStrip3D(const Vector3 *points, int pointCount, Color color)
{ {
if (pointCount < 3) return; // Security check if (pointCount < 3) return; // Security check
@ -3436,7 +3436,12 @@ void GenMeshTangents(Mesh *mesh)
Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3)); Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3)); Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
for (int i = 0; i < mesh->vertexCount - 3; i += 3) if (mesh->vertexCount % 3 != 0)
{
TRACELOG(LOG_WARNING, "MESH: vertexCount expected to be a multiple of 3. Expect uninitialized values.");
}
for (int i = 0; i <= mesh->vertexCount - 3; i += 3)
{ {
// Get triangle vertices // Get triangle vertices
Vector3 v1 = { mesh->vertices[(i + 0)*3 + 0], mesh->vertices[(i + 0)*3 + 1], mesh->vertices[(i + 0)*3 + 2] }; Vector3 v1 = { mesh->vertices[(i + 0)*3 + 0], mesh->vertices[(i + 0)*3 + 1], mesh->vertices[(i + 0)*3 + 2] };
@ -4321,6 +4326,8 @@ static Model LoadIQM(const char *fileName)
model.materials[i] = LoadMaterialDefault(); model.materials[i] = LoadMaterialDefault();
model.materials[i].maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture(TextFormat("%s/%s", basePath, material)); model.materials[i].maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture(TextFormat("%s/%s", basePath, material));
model.meshMaterial[i] = i;
TRACELOG(LOG_DEBUG, "MODEL: [%s] mesh name (%s), material (%s)", fileName, name, material); TRACELOG(LOG_DEBUG, "MODEL: [%s] mesh name (%s), material (%s)", fileName, name, material);
model.meshes[i].vertexCount = imesh[i].num_vertexes; model.meshes[i].vertexCount = imesh[i].num_vertexes;
@ -4864,7 +4871,7 @@ static BoneInfo *LoadBoneInfoGLTF(cgltf_skin skin, int *boneCount)
for (unsigned int i = 0; i < skin.joints_count; i++) for (unsigned int i = 0; i < skin.joints_count; i++)
{ {
cgltf_node node = *skin.joints[i]; cgltf_node node = *skin.joints[i];
strncpy(bones[i].name, node.name, sizeof(bones[i].name)); if (node.name != NULL) strncpy(bones[i].name, node.name, sizeof(bones[i].name));
// Find parent bone index // Find parent bone index
unsigned int parentIndex = -1; unsigned int parentIndex = -1;
@ -4890,6 +4897,7 @@ static Model LoadGLTF(const char *fileName)
/********************************************************************************************* /*********************************************************************************************
Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend) Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend)
Transform handling implemented by Paul Melis (@paulmelis).
Reviewed by Ramon Santamaria (@raysan5) Reviewed by Ramon Santamaria (@raysan5)
FEATURES: FEATURES:
@ -4899,6 +4907,10 @@ static Model LoadGLTF(const char *fileName)
PBR specular/glossiness flow and extended texture flows not supported PBR specular/glossiness flow and extended texture flows not supported
- Supports multiple meshes per model (every primitives is loaded as a separate mesh) - Supports multiple meshes per model (every primitives is loaded as a separate mesh)
- Supports basic animations - Supports basic animations
- Transforms, including parent-child relations, are applied on the mesh data, but the
hierarchy is not kept (as it can't be represented).
- Mesh instances in the glTF file (i.e. same mesh linked from multiple nodes)
are turned into separate raylib Meshes.
RESTRICTIONS: RESTRICTIONS:
- Only triangle meshes supported - Only triangle meshes supported
@ -4908,7 +4920,8 @@ static Model LoadGLTF(const char *fileName)
> Texcoords: vec2: float > Texcoords: vec2: float
> Colors: vec4: u8, u16, f32 (normalized) > Colors: vec4: u8, u16, f32 (normalized)
> Indices: u16, u32 (truncated to u16) > Indices: u16, u32 (truncated to u16)
- Node hierarchies or transforms not supported - Scenes defined in the glTF file are ignored. All nodes in the file
are used.
***********************************************************************************************/ ***********************************************************************************************/
@ -4960,8 +4973,22 @@ static Model LoadGLTF(const char *fileName)
if (result != cgltf_result_success) TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load mesh/material buffers", fileName); if (result != cgltf_result_success) TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load mesh/material buffers", fileName);
int primitivesCount = 0; int primitivesCount = 0;
// NOTE: We will load every primitive in the glTF as a separate raylib mesh // NOTE: We will load every primitive in the glTF as a separate raylib Mesh.
for (unsigned int i = 0; i < data->meshes_count; i++) primitivesCount += (int)data->meshes[i].primitives_count; // Determine total number of meshes needed from the node hierarchy.
for (unsigned int i = 0; i < data->nodes_count; i++)
{
cgltf_node *node = &(data->nodes[i]);
cgltf_mesh *mesh = node->mesh;
if (!mesh)
continue;
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{
if (mesh->primitives[p].type == cgltf_primitive_type_triangles)
primitivesCount++;
}
}
TRACELOG(LOG_DEBUG, " > Primitives (triangles only) count based on hierarchy : %i", primitivesCount);
// Load our model data: meshes and materials // Load our model data: meshes and materials
model.meshCount = primitivesCount; model.meshCount = primitivesCount;
@ -5064,27 +5091,51 @@ static Model LoadGLTF(const char *fileName)
// has_clearcoat, has_transmission, has_volume, has_ior, has specular, has_sheen // has_clearcoat, has_transmission, has_volume, has_ior, has specular, has_sheen
} }
// Load meshes data // Visit each node in the hierarchy and process any mesh linked from it.
// Each primitive within a glTF node becomes a Raylib Mesh.
// The local-to-world transform of each node is used to transform the
// points/normals/tangents of the created Mesh(es).
// Any glTF mesh linked from more than one Node (i.e. instancing)
// is turned into multiple Mesh's, as each Node will have its own
// transform applied.
// Note: the code below disregards the scenes defined in the file, all nodes are used.
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
for (unsigned int i = 0, meshIndex = 0; i < data->meshes_count; i++) int meshIndex = 0;
for (unsigned int i = 0; i < data->nodes_count; i++)
{ {
// NOTE: meshIndex accumulates primitives cgltf_node *node = &(data->nodes[i]);
for (unsigned int p = 0; p < data->meshes[i].primitives_count; p++) cgltf_mesh *mesh = node->mesh;
if (!mesh)
continue;
cgltf_float worldTransform[16];
cgltf_node_transform_world(node, worldTransform);
Matrix worldMatrix = {
worldTransform[0], worldTransform[4], worldTransform[8], worldTransform[12],
worldTransform[1], worldTransform[5], worldTransform[9], worldTransform[13],
worldTransform[2], worldTransform[6], worldTransform[10], worldTransform[14],
worldTransform[3], worldTransform[7], worldTransform[11], worldTransform[15]
};
Matrix worldMatrixNormals = MatrixTranspose(MatrixInvert(worldMatrix));
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{ {
// NOTE: We only support primitives defined by triangles // NOTE: We only support primitives defined by triangles
// Other alternatives: points, lines, line_strip, triangle_strip // Other alternatives: points, lines, line_strip, triangle_strip
if (data->meshes[i].primitives[p].type != cgltf_primitive_type_triangles) continue; if (mesh->primitives[p].type != cgltf_primitive_type_triangles) continue;
// NOTE: Attributes data could be provided in several data formats (8, 8u, 16u, 32...), // NOTE: Attributes data could be provided in several data formats (8, 8u, 16u, 32...),
// Only some formats for each attribute type are supported, read info at the top of this function! // Only some formats for each attribute type are supported, read info at the top of this function!
for (unsigned int j = 0; j < data->meshes[i].primitives[p].attributes_count; j++) for (unsigned int j = 0; j < mesh->primitives[p].attributes_count; j++)
{ {
// Check the different attributes for every primitive // Check the different attributes for every primitive
if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_position) // POSITION, vec3, float if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_position) // POSITION, vec3, float
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
// WARNING: SPECS: POSITION accessor MUST have its min and max properties defined // WARNING: SPECS: POSITION accessor MUST have its min and max properties defined
@ -5096,12 +5147,22 @@ static Model LoadGLTF(const char *fileName)
// Load 3 components of float data type into mesh.vertices // Load 3 components of float data type into mesh.vertices
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices) LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices)
// Transform the vertices
float *vertices = model.meshes[meshIndex].vertices;
for (int k = 0; k < attribute->count; k++)
{
Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix);
vertices[3*k] = vt.x;
vertices[3*k+1] = vt.y;
vertices[3*k+2] = vt.z;
}
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL, vec3, float else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL, vec3, float
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f)) if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
{ {
@ -5110,12 +5171,22 @@ static Model LoadGLTF(const char *fileName)
// Load 3 components of float data type into mesh.normals // Load 3 components of float data type into mesh.normals
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals) LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals)
// Transform the normals
float *normals = model.meshes[meshIndex].normals;
for (int k = 0; k < attribute->count; k++)
{
Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals);
normals[3*k] = nt.x;
normals[3*k+1] = nt.y;
normals[3*k+2] = nt.z;
}
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Normal attribute data format not supported, use vec3 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Normal attribute data format not supported, use vec3 float", fileName);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT, vec3, float else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT, vec3, float
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f)) if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f))
{ {
@ -5124,15 +5195,25 @@ static Model LoadGLTF(const char *fileName)
// Load 4 components of float data type into mesh.tangents // Load 4 components of float data type into mesh.tangents
LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents) LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents)
// Transform the tangents
float *tangents = model.meshes[meshIndex].tangents;
for (int k = 0; k < attribute->count; k++)
{
Vector3 tt = Vector3Transform((Vector3){ tangents[3*k], tangents[3*k+1], tangents[3*k+2] }, worldMatrix);
tangents[3*k] = tt.x;
tangents[3*k+1] = tt.y;
tangents[3*k+2] = tt.z;
}
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n
{ {
// Support up to 2 texture coordinates attributes // Support up to 2 texture coordinates attributes
float *texcoordPtr = NULL; float *texcoordPtr = NULL;
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
if (attribute->type == cgltf_type_vec2) if (attribute->type == cgltf_type_vec2)
{ {
@ -5176,7 +5257,7 @@ static Model LoadGLTF(const char *fileName)
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName);
int index = data->meshes[i].primitives[p].attributes[j].index; int index = mesh->primitives[p].attributes[j].index;
if (index == 0) model.meshes[meshIndex].texcoords = texcoordPtr; if (index == 0) model.meshes[meshIndex].texcoords = texcoordPtr;
else if (index == 1) model.meshes[meshIndex].texcoords2 = texcoordPtr; else if (index == 1) model.meshes[meshIndex].texcoords2 = texcoordPtr;
else else
@ -5185,9 +5266,9 @@ static Model LoadGLTF(const char *fileName)
if (texcoordPtr != NULL) RL_FREE(texcoordPtr); if (texcoordPtr != NULL) RL_FREE(texcoordPtr);
} }
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color) // COLOR_n, vec3/vec4, float/u8n/u16n else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_color) // COLOR_n, vec3/vec4, float/u8n/u16n
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
// WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range // WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range
@ -5304,9 +5385,9 @@ static Model LoadGLTF(const char *fileName)
} }
// Load primitive indices data (if provided) // Load primitive indices data (if provided)
if (data->meshes[i].primitives[p].indices != NULL) if (mesh->primitives[p].indices != NULL)
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].indices; cgltf_accessor *attribute = mesh->primitives[p].indices;
model.meshes[meshIndex].triangleCount = (int)attribute->count/3; model.meshes[meshIndex].triangleCount = (int)attribute->count/3;
@ -5346,7 +5427,7 @@ static Model LoadGLTF(const char *fileName)
// raylib instead assigns to the mesh the by its index, as loaded in model.materials array // raylib instead assigns to the mesh the by its index, as loaded in model.materials array
// To get the index, we check if material pointers match, and we assign the corresponding index, // To get the index, we check if material pointers match, and we assign the corresponding index,
// skipping index 0, the default material // skipping index 0, the default material
if (&data->materials[m] == data->meshes[i].primitives[p].material) if (&data->materials[m] == mesh->primitives[p].material)
{ {
model.meshMaterial[meshIndex] = m + 1; model.meshMaterial[meshIndex] = m + 1;
break; break;
@ -5396,20 +5477,27 @@ static Model LoadGLTF(const char *fileName)
TRACELOG(LOG_ERROR, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count); TRACELOG(LOG_ERROR, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
} }
for (unsigned int i = 0, meshIndex = 0; i < data->meshes_count; i++) meshIndex = 0;
for (unsigned int i = 0; i < data->nodes_count; i++)
{ {
for (unsigned int p = 0; p < data->meshes[i].primitives_count; p++) cgltf_node *node = &(data->nodes[i]);
cgltf_mesh *mesh = node->mesh;
if (!mesh)
continue;
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{ {
// NOTE: We only support primitives defined by triangles // NOTE: We only support primitives defined by triangles
if (data->meshes[i].primitives[p].type != cgltf_primitive_type_triangles) continue; if (mesh->primitives[p].type != cgltf_primitive_type_triangles) continue;
for (unsigned int j = 0; j < data->meshes[i].primitives[p].attributes_count; j++) for (unsigned int j = 0; j < mesh->primitives[p].attributes_count; j++)
{ {
// NOTE: JOINTS_1 + WEIGHT_1 will be used for +4 joints influencing a vertex -> Not supported by raylib // NOTE: JOINTS_1 + WEIGHT_1 will be used for +4 joints influencing a vertex -> Not supported by raylib
if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_joints) // JOINTS_n (vec4: 4 bones max per vertex / u8, u16) if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_joints) // JOINTS_n (vec4: 4 bones max per vertex / u8, u16)
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
// NOTE: JOINTS_n can only be vec4 and u8/u16 // NOTE: JOINTS_n can only be vec4 and u8/u16
// SPECS: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview // SPECS: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview
@ -5457,9 +5545,9 @@ static Model LoadGLTF(const char *fileName)
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported", fileName);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_weights) // WEIGHTS_n (vec4, u8n/u16n/f32) else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_weights) // WEIGHTS_n (vec4, u8n/u16n/f32)
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
if (attribute->type == cgltf_type_vec4) if (attribute->type == cgltf_type_vec4)
{ {

View File

@ -196,7 +196,7 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
} }
// Draw lines sequuence (using gl lines) // Draw lines sequuence (using gl lines)
void DrawLineStrip(Vector2 *points, int pointCount, Color color) void DrawLineStrip(const Vector2 *points, int pointCount, Color color)
{ {
if (pointCount < 2) return; // Security check if (pointCount < 2) return; // Security check
@ -1385,7 +1385,7 @@ void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
// Draw a triangle fan defined by points // Draw a triangle fan defined by points
// NOTE: First vertex provided is the center, shared by all triangles // NOTE: First vertex provided is the center, shared by all triangles
// By default, following vertex should be provided in counter-clockwise order // By default, following vertex should be provided in counter-clockwise order
void DrawTriangleFan(Vector2 *points, int pointCount, Color color) void DrawTriangleFan(const Vector2 *points, int pointCount, Color color)
{ {
if (pointCount >= 3) if (pointCount >= 3)
{ {
@ -1416,7 +1416,7 @@ void DrawTriangleFan(Vector2 *points, int pointCount, Color color)
// Draw a triangle strip defined by points // Draw a triangle strip defined by points
// NOTE: Every new vertex connects with previous two // NOTE: Every new vertex connects with previous two
void DrawTriangleStrip(Vector2 *points, int pointCount, Color color) void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color)
{ {
if (pointCount >= 3) if (pointCount >= 3)
{ {
@ -1570,7 +1570,7 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw spline: linear, minimum 2 points // Draw spline: linear, minimum 2 points
void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 2) return; if (pointCount < 2) return;
@ -1687,7 +1687,7 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color)
} }
// Draw spline: B-Spline, minimum 4 points // Draw spline: B-Spline, minimum 4 points
void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 4) return; if (pointCount < 4) return;
@ -1759,11 +1759,12 @@ void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color)
DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
} }
DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap // Cap circle drawing at the end of every segment
DrawCircleV(currentPoint, thick/2.0f, color);
} }
// Draw spline: Catmull-Rom, minimum 4 points // Draw spline: Catmull-Rom, minimum 4 points
void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 4) return; if (pointCount < 4) return;
@ -1825,28 +1826,31 @@ void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color co
DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
} }
DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap // Cap circle drawing at the end of every segment
DrawCircleV(currentPoint, thick/2.0f, color);
} }
// Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 3) return; if (pointCount >= 3)
for (int i = 0; i < pointCount - 2; i++)
{ {
DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color); for (int i = 0; i < pointCount - 2; i += 2) DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color);
// Cap circle drawing at the end of every segment
//for (int i = 2; i < pointCount - 2; i += 2) DrawCircleV(points[i], thick/2.0f, color);
} }
} }
// Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 4) return; if (pointCount >= 4)
for (int i = 0; i < pointCount - 3; i++)
{ {
DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color); for (int i = 0; i < pointCount - 3; i += 3) DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color);
// Cap circle drawing at the end of every segment
//for (int i = 3; i < pointCount - 3; i += 3) DrawCircleV(points[i], thick/2.0f, color);
} }
} }
@ -2195,7 +2199,7 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2
// Check if point is within a polygon described by array of vertices // Check if point is within a polygon described by array of vertices
// NOTE: Based on http://jeffreythompson.org/collision-detection/poly-point.php // NOTE: Based on http://jeffreythompson.org/collision-detection/poly-point.php
bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount) bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount)
{ {
bool inside = false; bool inside = false;
@ -2233,9 +2237,10 @@ bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, floa
float dx = center2.x - center1.x; // X distance between centers float dx = center2.x - center1.x; // X distance between centers
float dy = center2.y - center1.y; // Y distance between centers float dy = center2.y - center1.y; // Y distance between centers
float distance = sqrtf(dx*dx + dy*dy); // Distance between centers float distanceSquared = dx * dx + dy * dy; // Distance between centers squared
float radiusSum = radius1 + radius2;
if (distance <= (radius1 + radius2)) collision = true; collision = (distanceSquared <= (radiusSum * radiusSum));
return collision; return collision;
} }

View File

@ -1892,8 +1892,7 @@ int *LoadCodepoints(const char *text, int *count)
} }
// Re-allocate buffer to the actual number of codepoints loaded // Re-allocate buffer to the actual number of codepoints loaded
int *temp = (int *)RL_REALLOC(codepoints, codepointCount*sizeof(int)); codepoints = (int *)RL_REALLOC(codepoints, codepointCount*sizeof(int));
if (temp != NULL) codepoints = temp;
*count = codepointCount; *count = codepointCount;

View File

@ -3627,6 +3627,194 @@ void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color)
ImageDrawRectangle(dst, (int)rec.x, (int)(rec.y + rec.height - thick), (int)rec.width, thick, color); ImageDrawRectangle(dst, (int)rec.x, (int)(rec.y + rec.height - thick), (int)rec.width, thick, color);
} }
// Draw triangle within an image
void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{
// Calculate the 2D bounding box of the triangle
// Determine the minimum and maximum x and y coordinates of the triangle vertices
int xMin = (v1.x < v2.x)? ((v1.x < v3.x)? v1.x : v3.x) : ((v2.x < v3.x)? v2.x : v3.x);
int yMin = (v1.y < v2.y)? ((v1.y < v3.y)? v1.y : v3.y) : ((v2.y < v3.y)? v2.y : v3.y);
int xMax = (v1.x > v2.x)? ((v1.x > v3.x)? v1.x : v3.x) : ((v2.x > v3.x)? v2.x : v3.x);
int yMax = (v1.y > v2.y)? ((v1.y > v3.y)? v1.y : v3.y) : ((v2.y > v3.y)? v2.y : v3.y);
// Clamp the bounding box to the image dimensions
if (xMin < 0) xMin = 0;
if (yMin < 0) yMin = 0;
if (xMax > dst->width) xMax = dst->width;
if (yMax > dst->height) yMax = dst->height;
// Check the order of the vertices to determine if it's a front or back face
// NOTE: if signedArea is equal to 0, the face is degenerate
float signedArea = (v2.x - v1.x)*(v3.y - v1.y) - (v3.x - v1.x)*(v2.y - v1.y);
bool isBackFace = (signedArea > 0);
// Barycentric interpolation setup
// Calculate the step increments for the barycentric coordinates
int w1XStep = v3.y - v2.y, w1YStep = v2.x - v3.x;
int w2XStep = v1.y - v3.y, w2YStep = v3.x - v1.x;
int w3XStep = v2.y - v1.y, w3YStep = v1.x - v2.x;
// If the triangle is a back face, invert the steps
if (isBackFace)
{
w1XStep = -w1XStep, w1YStep = -w1YStep;
w2XStep = -w2XStep, w2YStep = -w2YStep;
w3XStep = -w3XStep, w3YStep = -w3YStep;
}
// Calculate the initial barycentric coordinates for the top-left point of the bounding box
int w1Row = (xMin - v2.x)*w1XStep + w1YStep*(yMin - v2.y);
int w2Row = (xMin - v3.x)*w2XStep + w2YStep*(yMin - v3.y);
int w3Row = (xMin - v1.x)*w3XStep + w3YStep*(yMin - v1.y);
// Rasterization loop
// Iterate through each pixel in the bounding box
for (int y = yMin; y <= yMax; y++)
{
int w1 = w1Row;
int w2 = w2Row;
int w3 = w3Row;
for (int x = xMin; x <= xMax; x++)
{
// Check if the pixel is inside the triangle using barycentric coordinates
// If it is then we can draw the pixel with the given color
if ((w1 | w2 | w3) >= 0) ImageDrawPixel(dst, x, y, color);
// Increment the barycentric coordinates for the next pixel
w1 += w1XStep;
w2 += w2XStep;
w3 += w3XStep;
}
// Move to the next row in the bounding box
w1Row += w1YStep;
w2Row += w2YStep;
w3Row += w3YStep;
}
}
// Draw triangle with interpolated colors within an image
void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3)
{
// Calculate the 2D bounding box of the triangle
// Determine the minimum and maximum x and y coordinates of the triangle vertices
int xMin = (v1.x < v2.x)? ((v1.x < v3.x)? v1.x : v3.x) : ((v2.x < v3.x)? v2.x : v3.x);
int yMin = (v1.y < v2.y)? ((v1.y < v3.y)? v1.y : v3.y) : ((v2.y < v3.y)? v2.y : v3.y);
int xMax = (v1.x > v2.x)? ((v1.x > v3.x)? v1.x : v3.x) : ((v2.x > v3.x)? v2.x : v3.x);
int yMax = (v1.y > v2.y)? ((v1.y > v3.y)? v1.y : v3.y) : ((v2.y > v3.y)? v2.y : v3.y);
// Clamp the bounding box to the image dimensions
if (xMin < 0) xMin = 0;
if (yMin < 0) yMin = 0;
if (xMax > dst->width) xMax = dst->width;
if (yMax > dst->height) yMax = dst->height;
// Check the order of the vertices to determine if it's a front or back face
// NOTE: if signedArea is equal to 0, the face is degenerate
float signedArea = (v2.x - v1.x)*(v3.y - v1.y) - (v3.x - v1.x)*(v2.y - v1.y);
bool isBackFace = (signedArea > 0);
// Barycentric interpolation setup
// Calculate the step increments for the barycentric coordinates
int w1XStep = v3.y - v2.y, w1YStep = v2.x - v3.x;
int w2XStep = v1.y - v3.y, w2YStep = v3.x - v1.x;
int w3XStep = v2.y - v1.y, w3YStep = v1.x - v2.x;
// If the triangle is a back face, invert the steps
if (isBackFace)
{
w1XStep = -w1XStep, w1YStep = -w1YStep;
w2XStep = -w2XStep, w2YStep = -w2YStep;
w3XStep = -w3XStep, w3YStep = -w3YStep;
}
// Calculate the initial barycentric coordinates for the top-left point of the bounding box
int w1Row = (xMin - v2.x)*w1XStep + w1YStep*(yMin - v2.y);
int w2Row = (xMin - v3.x)*w2XStep + w2YStep*(yMin - v3.y);
int w3Row = (xMin - v1.x)*w3XStep + w3YStep*(yMin - v1.y);
// Calculate the inverse of the sum of the barycentric coordinates for normalization
// NOTE 1: Here, we act as if we multiply by 255 the reciprocal, which avoids additional
// calculations in the loop. This is acceptable because we are only interpolating colors.
// NOTE 2: This sum remains constant throughout the triangle
float wInvSum = 255.0f/(w1Row + w2Row + w3Row);
// Rasterization loop
// Iterate through each pixel in the bounding box
for (int y = yMin; y <= yMax; y++)
{
int w1 = w1Row;
int w2 = w2Row;
int w3 = w3Row;
for (int x = xMin; x <= xMax; x++)
{
// Check if the pixel is inside the triangle using barycentric coordinates
if ((w1 | w2 | w3) >= 0)
{
// Compute the normalized barycentric coordinates
unsigned char aW1 = (unsigned char)((float)w1*wInvSum);
unsigned char aW2 = (unsigned char)((float)w2*wInvSum);
unsigned char aW3 = (unsigned char)((float)w3*wInvSum);
// Interpolate the color using the barycentric coordinates
Color finalColor = { 0 };
finalColor.r = (c1.r*aW1 + c2.r*aW2 + c3.r*aW3)/255;
finalColor.g = (c1.g*aW1 + c2.g*aW2 + c3.g*aW3)/255;
finalColor.b = (c1.b*aW1 + c2.b*aW2 + c3.b*aW3)/255;
finalColor.a = (c1.a*aW1 + c2.a*aW2 + c3.a*aW3)/255;
// Draw the pixel with the interpolated color
ImageDrawPixel(dst, x, y, finalColor);
}
// Increment the barycentric coordinates for the next pixel
w1 += w1XStep;
w2 += w2XStep;
w3 += w3XStep;
}
// Move to the next row in the bounding box
w1Row += w1YStep;
w2Row += w2YStep;
w3Row += w3YStep;
}
}
// Draw triangle outline within an image
void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{
ImageDrawLine(dst, v1.x, v1.y, v2.x, v2.y, color);
ImageDrawLine(dst, v2.x, v2.y, v3.x, v3.y, color);
ImageDrawLine(dst, v3.x, v3.y, v1.x, v1.y, color);
}
// Draw a triangle fan defined by points within an image (first vertex is the center)
void ImageDrawTriangleFan(Image *dst, Vector2 *points, int pointCount, Color color)
{
if (pointCount >= 3)
{
for (int i = 1; i < pointCount - 1; i++)
{
ImageDrawTriangle(dst, points[0], points[i], points[i + 1], color);
}
}
}
// Draw a triangle strip defined by points within an image
void ImageDrawTriangleStrip(Image *dst, Vector2 *points, int pointCount, Color color)
{
if (pointCount >= 3)
{
for (int i = 2; i < pointCount; i++)
{
if ((i%2) == 0) ImageDrawTriangle(dst, points[i], points[i - 2], points[i - 1], color);
else ImageDrawTriangle(dst, points[i], points[i - 1], points[i - 2], color);
}
}
}
// Draw an image (source) within an image (destination) // Draw an image (source) within an image (destination)
// NOTE: Color tint is applied to source image // NOTE: Color tint is applied to source image
void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint) void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint)