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

This commit is contained in:
ColleagueRiley 2024-12-24 15:02:19 -05:00
commit dbfc10ca72
47 changed files with 1872 additions and 907 deletions

View File

@ -6,11 +6,11 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| Name | raylib Version | Language | License |
| :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: |
| [raylib](https://github.com/raysan5/raylib) | **5.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
| [raylib](https://github.com/raysan5/raylib) | **5.5** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
| [raylib-boo](https://github.com/Rabios/raylib-boo) | 3.7 | [Boo](http://boo-language.github.io) | MIT |
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
| [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib55.c3l) | **5.5** | [C3](https://c3-lang.org) | MIT |
| [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib |
| [Raylib-CsLo](https://github.com/NotNotTech/Raylib-CsLo) | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
| [Raylib-CSharp-Vinculum](https://github.com/ZeroElectric/Raylib-CSharp-Vinculum) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 |
| [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.1-dev** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
@ -18,36 +18,41 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [claylib/wrap](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
| [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
| [chez-raylib](https://github.com/Yunoinsky/chez-raylib) | **auto** | [Chez Scheme](https://cisco.github.io/ChezScheme) | GPLv3 |
| [CLIPSraylib](https://github.com/mrryanjohnston/CLIPSraylib) | **auto** | [CLIPS](https://www.clipsrules.net/) | MIT |
| [raylib-cr](https://github.com/sol-vin/raylib-cr) | 4.6-dev (5e1a81) | [Crystal](https://crystal-lang.org) | Apache-2.0 |
| [ray-cyber](https://github.com/fubark/ray-cyber) | **5.0** | [Cyber](https://cyberscript.dev) | MIT |
| [dart-raylib](https://gitlab.com/wolfenrain/dart-raylib) | 4.0 | [Dart](https://dart.dev) | MIT |
| [bindbc-raylib3](https://github.com/o3o/bindbc-raylib3) | **5.0** | [D](https://dlang.org) | BSL-1.0 |
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
| [dray](https://github.com/redthing1/dray) | **5.0** | [D](https://dlang.org) | Apache-2.0 |
| [raylib-d](https://github.com/schveiguy/raylib-d) | **5.5** | [D](https://dlang.org) | Zlib |
| [rayex](https://github.com/shiryel/rayex) | 3.7 | [elixir](https://elixir-lang.org) | Apache-2.0 |
| [raylib-factor](https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor) | 4.5 | [Factor](https://factorcode.org) | BSD |
| [raylib-freebasic](https://github.com/WIITD/raylib-freebasic) | **5.0** | [FreeBASIC](https://www.freebasic.net) | MIT |
| [fortran-raylib](https://github.com/interkosmos/fortran-raylib) | **5.5** | [Fortran](https://fortran-lang.org) | ISC |
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.0** | [Go](https://golang.org) | Zlib |
| [raylib-go](https://github.com/gen2brain/raylib-go) | **5.5** | [Go](https://golang.org) | Zlib |
| [raylib-guile](https://github.com/petelliott/raylib-guile) | **auto** | [Guile](https://www.gnu.org/software/guile) | Zlib |
| [gforth-raylib](https://github.com/ArnautDaniel/gforth-raylib) | 3.5 | [Gforth](https://gforth.org) | **???** |
| [h-raylib](https://github.com/Anut-py/h-raylib) | **5.5-dev** | [Haskell](https://haskell.org) | Apache-2.0 |
| [raylib-hx](https://github.com/foreignsasquatch/raylib-hx) | 4.2 | [Haxe](https://haxe.org) | Zlib |
| [hb-raylib](https://github.com/MarcosLeonardoMendezGerencir/hb-raylib) | 3.5 | [Harbour](https://harbour.github.io) | MIT |
| [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT |
| [jaylib](https://github.com/electronstudio/jaylib/) | 4.5 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE |
| [jaylib](https://github.com/electronstudio/jaylib/) | **5.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.jl](https://github.com/chengchingwen/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) | **???** |
| [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 |
| [raylua](https://github.com/Rabios/raylua) | 4.0 | [Lua](http://www.lua.org) | MIT |
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | MIT |
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 5.0 | [Lua](http://www.lua.org) | ISC |
| [raylib-lua-bindings (WIP)](https://github.com/legendaryredfox/raylib-lua-bindings) | 5.5 | [Lua](http://www.lua.org) | ISC |
| [ReiLua](https://github.com/nullstare/ReiLua) | 5.5 | [Lua](http://www.lua.org) | MIT |
| [raylib-lua-sol](https://github.com/RobLoach/raylib-lua-sol) | 5.5 | [Lua](http://www.lua.org) | Zlib |
| [raylib-luajit](https://github.com/homma/raylib-luajit) | 5.5 | [Lua](http://www.lua.org) | MIT |
| [raylib-luajit-generated](https://github.com/james2doyle/raylib-luajit-generated) | 5.5 | [Lua](http://www.lua.org) | MIT |
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | **???** |
| [Raylib.nelua](https://github.com/AuzFox/Raylib.nelua) | **5.0** | [nelua](https://nelua.io) | Zlib |
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 4.5 | [Ruby](https://www.ruby-lang.org/en) | Zlib |
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib |
| [naylib](https://github.com/planetis-m/naylib) | **5.1-dev** | [Nim](https://nim-lang.org) | MIT |
| [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib |
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.0** | [Odin](https://odin-lang.org) | BSD-3Clause |
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | BSD-3Clause |
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
| [raylib-ocaml](https://github.com/tjammer/raylib-ocaml) | **5.0** | [OCaml](https://ocaml.org) | MIT |
| [TurboRaylib](https://github.com/turborium/TurboRaylib) | 4.5 | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT |
@ -55,25 +60,26 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [Raylib.4.0.Pascal](https://github.com/sysrpl/Raylib.4.0.Pascal) | 4.0 | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal) | Zlib |
| [pyraylib](https://github.com/Ho011/pyraylib) | 3.7 | [Python](https://www.python.org) | Zlib |
| [raylib-python-cffi](https://github.com/electronstudio/raylib-python-cffi) | **5.5** | [Python](https://www.python.org) | EPL-2.0 |
| [raylibpyctbg](https://github.com/overdev/raylibpyctbg) | 4.5 | [Python](https://www.python.org) | MIT |
| [raylibpyctbg](https://github.com/overdev/raylibpyctbg) | 5.5 | [Python](https://www.python.org) | MIT |
| [raylib-py](https://github.com/overdev/raylib-py) | 5.5 | [Python](https://www.python.org) | MIT |
| [raylib-python-ctypes](https://github.com/sDos280/raylib-python-ctypes) | 4.6-dev | [Python](https://www.python.org) | MIT |
| [raylib-pkpy-bindings](https://github.com/blueloveTH/pkpy-bindings) | 4.6-dev | [pocketpy](https://pocketpy.dev) | MIT |
| [raylib-pkpy-bindings](https://github.com/blueloveTH/pkpy-bindings) | 5.1-dev | [pocketpy](https://pocketpy.dev) | MIT |
| [raylib-php](https://github.com/joseph-montanez/raylib-php) | 4.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib |
| [raylib-phpcpp](https://github.com/oraoto/raylib-phpcpp) | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib |
| [raylibr](https://github.com/jeroenjanssens/raylibr) | 4.0 | [R](https://www.r-project.org) | MIT |
| [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 4.5 | [Rust](https://www.rust-lang.org) | GPLv3 |
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.0** | [Rust](https://www.rust-lang.org) | Zlib |
| [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 5.5 | [Rust](https://www.rust-lang.org) | GPLv3 |
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib |
| [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** |
| [racket-raylib](https://github.com/eutro/racket-raylib) | 4.0 | [Racket](https://racket-lang.org) | MIT/Apache-2.0 |
| [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT |
| [raylib-scopes](https://github.com/salotz/raylib-scopes) | auto | [Scopes](http://scopes.rocks) | MIT |
| [raylib-SmallBASIC](https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib) | **5.0** | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 |
| [raylib-SmallBASIC](https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib) | **5.5** | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 |
| [raylib-umka](https://github.com/robloach/raylib-umka) | 4.5 | [Umka](https://github.com/vtereshkov/umka-lang) | Zlib |
| [raylib-for-v](https://github.com/EmmaTheMartian/raylib-for-v) | 5.5 | [V](https://vlang.io) | MIT/Unlicense |
| [raylib.v](https://github.com/irishgreencitrus/raylib.v) | 4.2 | [V](https://vlang.io) | Zlib |
| [raylib-vapi](https://github.com/lxmcf/raylib-vapi) | **5.0** | [Vala](https://vala.dev) | Zlib |
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.0 | [Wren](http://wren.io) | ISC |
| [raylib-zig](https://github.com/Not-Nik/raylib-zig) | **5.0** | [Zig](https://ziglang.org) | MIT |
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.5 | [Wren](http://wren.io) | ISC |
| [raylib-zig](https://github.com/Not-Nik/raylib-zig) | **5.5** | [Zig](https://ziglang.org) | MIT |
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [Zig](https://ziglang.org) | MIT |
| [raylib-zig-bindings](https://github.com/L-Briand/raylib-zig-bindings) | **5.0** | [Zig](https://ziglang.org) | Zlib |
| [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
@ -84,6 +90,8 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [Raylib.lean](https://github.com/KislyjKisel/Raylib.lean) | **5.5-dev** | [Lean4](https://lean-lang.org) | BSD-3-Clause |
| [raylib-cobol](https://codeberg.org/glowiak/raylib-cobol) | **auto** | [COBOL](https://gnucobol.sourceforge.io) | Public domain |
| [raylib-apl](https://github.com/Brian-ED/raylib-apl) | **5.0** | [Dyalog APL](https://www.dyalog.com/) | MIT |
| [raylib-jai](https://github.com/ahmedqarmout2/raylib-jai) | **5.5** | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | MIT |
| [fnl-raylib](https://github.com/0riginaln0/fnl-raylib) | **5.5** | [Fennel](https://fennel-lang.org/) | MIT |
### Utility Wrapers
@ -93,6 +101,7 @@ These are utility wrappers for specific languages, they are not required to use
| [raylib-cpp](https://github.com/robloach/raylib-cpp) | **5.5** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib |
| [claylib](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib |
| [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **5.0** | [BQN](https://mlochbaum.github.io/BQN) | MIT |
| [DOOR](https://github.com/RealDoigt/DOOR) | 4.0 | [D](https://dlang.org) | MIT |
### Older or Unmaintained Language Bindings
@ -152,7 +161,7 @@ These are older raylib bindings that are more than 2 versions old or have not be
| [ray.mod](https://github.com/bmx-ng/ray.mod) | 3.0 | [BlitzMax](https://blitzmax.org) |
| [raylib-mosaic](https://github.com/pluckyporcupine/raylib-mosaic) | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) |
| [raylib-xdpw](https://github.com/vtereshkov/raylib-xdpw) | 2.6 | [XD Pascal](https://github.com/vtereshkov/xdpw) |
| [raylib-carp](https://github.com/sacredbirdman/raylib-carp) | 3.0 | [Carp](https://github.com/carp-lang/Carp) |
| [raylib-carp](https://github.com/sacredbirdman/raylib-carp) | 3.0 | [Carp](https://github.com/carp-lang/Carp) |
| [raylib-fb](https://github.com/IchMagBier/raylib-fb) | 3.0 | [FreeBasic](https://www.freebasic.net) |
| [raylib-purebasic](https://github.com/D-a-n-i-l-o/raylib-purebasic) | 3.0 | [PureBasic](https://www.purebasic.com) |
| [raylib-ats2](https://github.com/mephistopheles-8/raylib-ats2) | 3.0 | [ATS2](http://www.ats-lang.org) |

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.12)
project(raylib)
# Avoid excessive expansion of variables in conditionals. In particular, if

View File

@ -24,7 +24,7 @@ enum_option(USE_EXTERNAL_GLFW "OFF;IF_POSSIBLE;ON" "Link raylib against system G
option(GLFW_BUILD_WAYLAND "Build the bundled GLFW with Wayland support" OFF)
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")
include(ParseConfigHeader)

View File

@ -54,7 +54,7 @@ To open new issues for raylib (bug, enhancement, discussion...), just try to fol
- If applicable, attach some screenshot of the issue and a .zip file with the code sample and required resources.
- On issue description, add a brackets tag about the raylib module that relates to this issue.
If don't know which module, just report the issue, I will review it.
- You can check other issues to see how is being done!
- You can check other issues to see how it's being done!
### Sending a Pull-Request

2
FAQ.md
View File

@ -90,7 +90,7 @@ I personally consider raylib a graphics library with some high-level features ra
### What does raylib provide that other engines or libraries don't?
I would say "simplicity" and "enjoyment" at a really low level of coding but actually is up to the user to discover it, to try it and to see if it fits their needs. raylib is not good for everyone but it's worth a try.
I would say "simplicity" and "enjoyment" at a really low level of coding but actually it is up to the user to discover it, to try it and to see if it fits their needs. raylib is not good for everyone but it's worth a try.
### How does raylib compare to Unity/Unreal/Godot?

View File

@ -401,6 +401,7 @@ pub fn build(b: *std.Build) !void {
const lib = try compileRaylib(b, target, optimize, Options.getOptions(b));
lib.installHeader(b.path("src/raylib.h"), "raylib.h");
lib.installHeader(b.path("src/rcamera.h"), "rcamera.h");
lib.installHeader(b.path("src/raymath.h"), "raymath.h");
lib.installHeader(b.path("src/rlgl.h"), "rlgl.h");

View File

@ -12,18 +12,12 @@ endif()
# Also adding only on desktop (web also uses glfw but it is more limited and is added using an emcc linker flag)
if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MATCHES "Desktop")
MESSAGE(STATUS "Using raylib's GLFW")
set(INTERNAL_GLFW ON CACHE INTERNAL "" FORCE)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
set(GLFW_LIBRARY_TYPE "OBJECT" CACHE STRING "" FORCE)
if (NOT BUILD_SHARED_LIBS)
message(STATUS "Enabling install of GLFW static libs because raylib will be built statically")
set(GLFW_INSTALL ON CACHE BOOL "" FORCE)
endif ()
add_subdirectory(external/glfw)
@ -31,7 +25,7 @@ if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MAT
if (BUILD_SHARED_LIBS)
set_property(TARGET glfw PROPERTY C_VISIBILITY_PRESET hidden)
endif()
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw>)
include_directories(BEFORE SYSTEM external/glfw/include)
elseif("${PLATFORM}" STREQUAL "DRM")

View File

@ -18,8 +18,10 @@ endif ()
join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(../raylib.pc.in raylib.pc @ONLY)
configure_file(../cmake/raylib-config-version.cmake raylib-config-version.cmake @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
include(SetupCmakeConfig)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
install(FILES ${PROJECT_SOURCE_DIR}/../cmake/raylib-config.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/raylib")
# populates raylib_{FOUND, INCLUDE_DIRS, LIBRARIES, LDFLAGS, DEFINITIONS}
include(PopulateConfigVariablesLocally)

View File

@ -125,3 +125,7 @@ if (NOT GRAPHICS)
endif ()
set(LIBS_PRIVATE ${LIBS_PRIVATE} ${OPENAL_LIBRARY})
if (${PLATFORM} MATCHES "Desktop")
set(LIBS_PRIVATE ${LIBS_PRIVATE} glfw)
endif ()

View File

@ -1,23 +0,0 @@
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
# Setup install of exported targets
install(EXPORT raylib-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/raylib
)
# Macro to write config
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake"
VERSION ${raylib_VERSION}
COMPATIBILITY SameMajorVersion
)
# Setup install of version config
install(
FILES
"../cmake/raylib-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/raylib-config-version.cmake"
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/raylib
)

View File

@ -0,0 +1,21 @@
set(PACKAGE_VERSION "@PROJECT_VERSION@")
if(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
if(NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else(NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif(NOT PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
return()
endif()
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
math(EXPR installedBits "8 * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

View File

@ -1 +1,79 @@
include("${CMAKE_CURRENT_LIST_DIR}/raylib-targets.cmake")
# - Try to find raylib
# Options:
# raylib_USE_STATIC_LIBS - OFF by default
# raylib_VERBOSE - OFF by default
# Once done, this defines a raylib target that can be passed to
# target_link_libraries as well as following variables:
#
# raylib_FOUND - System has raylib installed
# raylib_INCLUDE_DIRS - The include directories for the raylib header(s)
# raylib_LIBRARIES - The libraries needed to use raylib
# raylib_LDFLAGS - The linker flags needed with raylib
# raylib_DEFINITIONS - Compiler switches required for using raylib
if (NOT TARGET raylib)
set(XPREFIX PC_RAYLIB)
find_package(PkgConfig QUIET)
pkg_check_modules(${XPREFIX} QUIET raylib)
if (raylib_USE_STATIC_LIBS)
set(XPREFIX ${XPREFIX}_STATIC)
endif()
set(raylib_DEFINITIONS ${${XPREFIX}_CFLAGS})
find_path(raylib_INCLUDE_DIR
NAMES raylib.h
HINTS ${${XPREFIX}_INCLUDE_DIRS}
)
set(RAYLIB_NAMES raylib)
if (raylib_USE_STATIC_LIBS)
set(RAYLIB_NAMES libraylib.a raylib.lib ${RAYLIB_NAMES})
endif()
find_library(raylib_LIBRARY
NAMES ${RAYLIB_NAMES}
HINTS ${${XPREFIX}_LIBRARY_DIRS}
)
set(raylib_LIBRARIES ${raylib_LIBRARY})
set(raylib_LIBRARY_DIRS ${${XPREFIX}_LIBRARY_DIRS})
set(raylib_LIBRARY_DIR ${raylib_LIBRARY_DIRS})
set(raylib_INCLUDE_DIRS ${raylib_INCLUDE_DIR})
set(raylib_LDFLAGS ${${XPREFIX}_LDFLAGS})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(raylib DEFAULT_MSG
raylib_LIBRARY
raylib_INCLUDE_DIR
)
mark_as_advanced(raylib_LIBRARY raylib_INCLUDE_DIR)
if (raylib_USE_STATIC_LIBS)
add_library(raylib STATIC IMPORTED GLOBAL)
else()
add_library(raylib SHARED IMPORTED GLOBAL)
endif()
string (REPLACE ";" " " raylib_LDFLAGS "${raylib_LDFLAGS}")
set_target_properties(raylib
PROPERTIES
IMPORTED_LOCATION "${raylib_LIBRARIES}"
IMPORTED_IMPLIB "${raylib_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${raylib_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${raylib_LDFLAGS}"
INTERFACE_COMPILE_OPTIONS "${raylib_DEFINITIONS}"
)
if (raylib_VERBOSE)
message(STATUS "raylib_FOUND: ${raylib_FOUND}")
message(STATUS "raylib_INCLUDE_DIRS: ${raylib_INCLUDE_DIRS}")
message(STATUS "raylib_LIBRARIES: ${raylib_LIBRARIES}")
message(STATUS "raylib_LDFLAGS: ${raylib_LDFLAGS}")
message(STATUS "raylib_DEFINITIONS: ${raylib_DEFINITIONS}")
endif()
endif()

View File

@ -56,10 +56,15 @@
# Define target platform: PLATFORM_DESKTOP, PLATFORM_DESKTOP_SDL, PLATFORM_DRM, PLATFORM_ANDROID, PLATFORM_WEB, PLATFORM_WEB_RGFW
PLATFORM ?= PLATFORM_DESKTOP
ifeq ($(PLATFORM), PLATFORM_DESKTOP)
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW))
TARGET_PLATFORM := $(PLATFORM)
override PLATFORM = PLATFORM_DESKTOP
else
TARGET_PLATFORM = $(PLATFORM)
ifeq ($(PLATFORM), PLATFORM_DESKTOP)
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW
else
TARGET_PLATFORM = $(PLATFORM)
endif
endif
# Define required raylib variables
@ -484,7 +489,7 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
# Libraries for web (HTML5) compiling
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.a
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.web.a
endif
# Define source code object files required
@ -660,7 +665,7 @@ OTHERS = \
ifeq ($(TARGET_PLATFORM), PLATFORM_DESKTOP_GFLW)
OTHERS += others/rlgl_standalone
endif
CURRENT_MAKEFILE = $(lastword $(MAKEFILE_LIST))

View File

@ -370,7 +370,7 @@ ifeq ($(PLATFORM),PLATFORM_DRM)
endif
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
# Libraries for web (HTML5) compiling
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.a
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.web.a
endif
# Define source code object files required

View File

@ -6,7 +6,8 @@
*
* Example create by GreenSnakeLinux (@GreenSnakeLinux),
* lighter by oblerion (@oblerion) and
* reviewed by Ramon Santamaria (@raysan5)
* reviewed by Ramon Santamaria (@raysan5) and
* improved by danilwhale (@danilwhale)
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
@ -17,6 +18,16 @@
#include "raylib.h"
#include <math.h>
typedef enum {
BUTTON_NONE = -1,
BUTTON_UP,
BUTTON_LEFT,
BUTTON_RIGHT,
BUTTON_DOWN,
BUTTON_MAX
} PadButton;
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@ -29,24 +40,38 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls");
const float dpadX = 90;
const float dpadY = 300;
const float dpadRad = 25.0f;//radius of each pad
Color dpadColor = BLUE;
int dpadKeydown = -1;//-1 if not down, else 0,1,2,3
Vector2 padPosition = { 100, 350 };
float buttonRadius = 30;
const float dpadCollider[4][2]= // collider array with x,y position
Vector2 buttonPositions[BUTTON_MAX] =
{
{dpadX,dpadY-dpadRad*1.5f},//up
{dpadX-dpadRad*1.5f,dpadY},//left
{dpadX+dpadRad*1.5f,dpadY},//right
{dpadX,dpadY+dpadRad*1.5f}//down
{ padPosition.x,padPosition.y - buttonRadius*1.5f }, // Up
{ padPosition.x - buttonRadius*1.5f, padPosition.y }, // Left
{ padPosition.x + buttonRadius*1.5f, padPosition.y }, // Right
{ padPosition.x, padPosition.y + buttonRadius*1.5f } // Down
};
const char dpadLabel[4]="XYBA";//label of Dpad
float playerX=100;
float playerY=100;
const char *buttonLabels[BUTTON_MAX] =
{
"Y", // Up
"X", // Left
"B", // Right
"A" // Down
};
Color buttonLabelColors[BUTTON_MAX] =
{
YELLOW, // Up
BLUE, // Left
RED, // Right
GREEN // Down
};
int pressedButton = BUTTON_NONE;
Vector2 inputPosition = { 0, 0 };
Vector2 playerPosition = { (float)screenWidth/2, (float)screenHeight/2 };
float playerSpeed = 75;
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
@ -54,63 +79,89 @@ int main(void)
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//--------------------------------------------------------------------------
dpadKeydown = -1; //reset
int inputX = 0;
int inputY = 0;
if(GetTouchPointCount()>0)
{//use touch pos
inputX = GetTouchX();
inputY = GetTouchY();
// Update
//--------------------------------------------------------------------------
if ((GetTouchPointCount() > 0))
{
// Use touch position
inputPosition = GetTouchPosition(0);
}
else
{//use mouse pos
inputX = GetMouseX();
inputY = GetMouseY();
}
for(int i=0;i<4;i++)
{
//test distance each collider and input < radius
if( fabsf(dpadCollider[i][1]-inputY) + fabsf(dpadCollider[i][0]-inputX) < dpadRad)
{
dpadKeydown = i;
break;
}
// Use mouse position
inputPosition = GetMousePosition();
}
// move player
switch(dpadKeydown){
case 0: playerY -= 50*GetFrameTime();
break;
case 1: playerX -= 50*GetFrameTime();
break;
case 2: playerX += 50*GetFrameTime();
break;
case 3: playerY += 50*GetFrameTime();
default:;
};
//--------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
for(int i=0;i<4;i++)
// Reset pressed button to none
pressedButton = BUTTON_NONE;
// Make sure user is pressing left mouse button if they're from desktop
if ((GetTouchPointCount() > 0) || ((GetTouchPointCount() == 0) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)))
{
// Find nearest D-Pad button to the input position
for (int i = 0; i < BUTTON_MAX; i++)
{
//draw all pad
DrawCircleV((Vector2) { dpadCollider[i][0], dpadCollider[i][1] }, dpadRad, dpadColor);
if(i!=dpadKeydown)
float distX = fabsf(buttonPositions[i].x - inputPosition.x);
float distY = fabsf(buttonPositions[i].y - inputPosition.y);
if ((distX + distY < buttonRadius))
{
//draw label
DrawText(TextSubtext(dpadLabel,i,1),
(int)dpadCollider[i][0]-7,
(int)dpadCollider[i][1]-8,20,BLACK);
pressedButton = i;
break;
}
}
}
// Move player according to pressed button
switch (pressedButton)
{
case BUTTON_UP:
{
playerPosition.y -= playerSpeed*GetFrameTime();
break;
}
case BUTTON_LEFT:
{
playerPosition.x -= playerSpeed*GetFrameTime();
break;
}
case BUTTON_RIGHT:
{
playerPosition.x += playerSpeed*GetFrameTime();
break;
}
case BUTTON_DOWN:
{
playerPosition.y += playerSpeed*GetFrameTime();
break;
}
default: break;
};
//--------------------------------------------------------------------------
// Draw
//--------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw world
DrawCircleV(playerPosition, 50, MAROON);
// Draw GUI
for (int i = 0; i < BUTTON_MAX; i++)
{
DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton)? DARKGRAY : BLACK);
DrawText(buttonLabels[i],
(int)buttonPositions[i].x - 7, (int)buttonPositions[i].y - 8,
20, buttonLabelColors[i]);
}
DrawText("move the player with D-Pad buttons", 10, 10, 20, DARKGRAY);
DrawRectangleRec((Rectangle) { playerX - 4, playerY - 4, 75, 28 }, RED);
DrawText("Player", (int)playerX, (int)playerY, 20, WHITE);
EndDrawing();
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
}
// De-Initialization

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,6 +1,6 @@
#version 100
precision highp float;
precision highp float;
#define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0
@ -24,7 +24,6 @@ varying vec3 fragNormal;
varying vec4 shadowPos;
varying mat3 TBN;
// Input uniform values
uniform int numOfLights;
uniform sampler2D albedoMap;
@ -153,4 +152,4 @@ void main()
gl_FragColor = vec4(color,1.0);
}
}

View File

@ -1,11 +1,11 @@
#version 100
// Input vertex attributes
attribute vec3 vertexPosition;
attribute vec2 vertexTexCoord;
attribute vec3 vertexNormal;
attribute vec3 vertexTangent;
attribute vec4 vertexColor;
attribute vec3 vertexPosition;
attribute vec2 vertexTexCoord;
attribute vec3 vertexNormal;
attribute vec3 vertexTangent;
attribute vec4 vertexColor;
// Input uniform values
uniform mat4 mvp;
@ -72,4 +72,4 @@ void main()
// Calculate final vertex position
gl_Position = mvp * vec4(vertexPosition, 1.0);
}
}

View File

@ -25,7 +25,7 @@ void main()
// Send vertex attributes to fragment shader
fragPosition = vec3(instanceTransform*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
//fragColor = vertexColor;
fragColor = vec4(1.0);
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
// Calculate final vertex position, note that we multiply mvp by instanceTransform

View File

@ -95,11 +95,19 @@ int main(void)
rlEnableFramebuffer(gBuffer.framebuffer);
// Since we are storing position and normal data in these textures,
// we need to use a floating point format.
gBuffer.positionTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, 1);
// NOTE: Vertex positions are stored in a texture for simplicity. A better approach would use a depth texture
// (instead of a detph renderbuffer) to reconstruct world positions in the final render shader via clip-space position,
// depth, and the inverse view/projection matrices.
// 16-bit precision ensures OpenGL ES 3 compatibility, though it may lack precision for real scenarios.
// But as mentioned above, the positions could be reconstructed instead of stored. If not targeting OpenGL ES
// and you wish to maintain this approach, consider using `RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32`.
gBuffer.positionTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1);
// Similarly, 16-bit precision is used for normals ensures OpenGL ES 3 compatibility.
// This is generally sufficient, but a 16-bit fixed-point format offer a better uniform precision in all orientations.
gBuffer.normalTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16, 1);
gBuffer.normalTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, 1);
// Albedo (diffuse color) and specular strength can be combined into one texture.
// The color in RGB, and the specular strength in the alpha channel.
gBuffer.albedoSpecTexture = rlLoadTexture(NULL, screenWidth, screenHeight, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);

View File

@ -61,7 +61,7 @@ int main(void)
{
Matrix translation = MatrixTranslate((float)GetRandomValue(-50, 50), (float)GetRandomValue(-50, 50), (float)GetRandomValue(-50, 50));
Vector3 axis = Vector3Normalize((Vector3){ (float)GetRandomValue(0, 360), (float)GetRandomValue(0, 360), (float)GetRandomValue(0, 360) });
float angle = (float)GetRandomValue(0, 10)*DEG2RAD;
float angle = (float)GetRandomValue(0, 180)*DEG2RAD;
Matrix rotation = MatrixRotate(axis, angle);
transforms[i] = MatrixMultiply(rotation, translation);
@ -73,7 +73,6 @@ int main(void)
// Get shader locations
shader.locs[SHADER_LOC_MATRIX_MVP] = GetShaderLocation(shader, "mvp");
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocationAttrib(shader, "instanceTransform");
// Set shader value: ambient light level
int ambientLoc = GetShaderLocation(shader, "ambient");

View File

@ -2543,6 +2543,11 @@
"name": "SHADER_LOC_BONE_MATRICES",
"value": 28,
"description": "Shader location: array of matrices uniform: boneMatrices"
},
{
"name": "SHADER_LOC_VERTEX_INSTANCE_TX",
"value": 29,
"description": "Shader location: vertex attribute: instanceTransform"
}
]
},
@ -2591,8 +2596,28 @@
"description": "Shader uniform type: ivec4 (4 int)"
},
{
"name": "SHADER_UNIFORM_SAMPLER2D",
"name": "SHADER_UNIFORM_UINT",
"value": 8,
"description": "Shader uniform type: unsigned int"
},
{
"name": "SHADER_UNIFORM_UIVEC2",
"value": 9,
"description": "Shader uniform type: uivec2 (2 unsigned int)"
},
{
"name": "SHADER_UNIFORM_UIVEC3",
"value": 10,
"description": "Shader uniform type: uivec3 (3 unsigned int)"
},
{
"name": "SHADER_UNIFORM_UIVEC4",
"value": 11,
"description": "Shader uniform type: uivec4 (4 unsigned int)"
},
{
"name": "SHADER_UNIFORM_SAMPLER2D",
"value": 12,
"description": "Shader uniform type: sampler2d"
}
]
@ -4881,6 +4906,17 @@
"description": "Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty",
"returnType": "int"
},
{
"name": "GetKeyName",
"description": "Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)",
"returnType": "const char *",
"params": [
{
"type": "int",
"name": "key"
}
]
},
{
"name": "SetExitKey",
"description": "Set a custom key to exit program (default is ESC)",
@ -9765,7 +9801,7 @@
},
{
"name": "TextToInteger",
"description": "Get integer value from text (negative values not supported)",
"description": "Get integer value from text",
"returnType": "int",
"params": [
{
@ -9776,7 +9812,7 @@
},
{
"name": "TextToFloat",
"description": "Get float value from text (negative values not supported)",
"description": "Get float value from text",
"returnType": "float",
"params": [
{

View File

@ -2543,6 +2543,11 @@ return {
name = "SHADER_LOC_BONE_MATRICES",
value = 28,
description = "Shader location: array of matrices uniform: boneMatrices"
},
{
name = "SHADER_LOC_VERTEX_INSTANCE_TX",
value = 29,
description = "Shader location: vertex attribute: instanceTransform"
}
}
},
@ -2591,8 +2596,28 @@ return {
description = "Shader uniform type: ivec4 (4 int)"
},
{
name = "SHADER_UNIFORM_SAMPLER2D",
name = "SHADER_UNIFORM_UINT",
value = 8,
description = "Shader uniform type: unsigned int"
},
{
name = "SHADER_UNIFORM_UIVEC2",
value = 9,
description = "Shader uniform type: uivec2 (2 unsigned int)"
},
{
name = "SHADER_UNIFORM_UIVEC3",
value = 10,
description = "Shader uniform type: uivec3 (3 unsigned int)"
},
{
name = "SHADER_UNIFORM_UIVEC4",
value = 11,
description = "Shader uniform type: uivec4 (4 unsigned int)"
},
{
name = "SHADER_UNIFORM_SAMPLER2D",
value = 12,
description = "Shader uniform type: sampler2d"
}
}
@ -4326,6 +4351,14 @@ return {
description = "Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty",
returnType = "int"
},
{
name = "GetKeyName",
description = "Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)",
returnType = "const char *",
params = {
{type = "int", name = "key"}
}
},
{
name = "SetExitKey",
description = "Set a custom key to exit program (default is ESC)",
@ -6936,7 +6969,7 @@ return {
},
{
name = "TextToInteger",
description = "Get integer value from text (negative values not supported)",
description = "Get integer value from text",
returnType = "int",
params = {
{type = "const char *", name = "text"}
@ -6944,7 +6977,7 @@ return {
},
{
name = "TextToFloat",
description = "Get float value from text (negative values not supported)",
description = "Get float value from text",
returnType = "float",
params = {
{type = "const char *", name = "text"}

File diff suppressed because it is too large Load Diff

View File

@ -507,7 +507,7 @@
<Value name="MATERIAL_MAP_PREFILTER" integer="9" desc="Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP)" />
<Value name="MATERIAL_MAP_BRDF" integer="10" desc="Brdf material" />
</Enum>
<Enum name="ShaderLocationIndex" valueCount="29" desc="Shader location index">
<Enum name="ShaderLocationIndex" valueCount="30" desc="Shader location index">
<Value name="SHADER_LOC_VERTEX_POSITION" integer="0" desc="Shader location: vertex attribute: position" />
<Value name="SHADER_LOC_VERTEX_TEXCOORD01" integer="1" desc="Shader location: vertex attribute: texcoord01" />
<Value name="SHADER_LOC_VERTEX_TEXCOORD02" integer="2" desc="Shader location: vertex attribute: texcoord02" />
@ -537,8 +537,9 @@
<Value name="SHADER_LOC_VERTEX_BONEIDS" integer="26" desc="Shader location: vertex attribute: boneIds" />
<Value name="SHADER_LOC_VERTEX_BONEWEIGHTS" integer="27" desc="Shader location: vertex attribute: boneWeights" />
<Value name="SHADER_LOC_BONE_MATRICES" integer="28" desc="Shader location: array of matrices uniform: boneMatrices" />
<Value name="SHADER_LOC_VERTEX_INSTANCE_TX" integer="29" desc="Shader location: vertex attribute: instanceTransform" />
</Enum>
<Enum name="ShaderUniformDataType" valueCount="9" desc="Shader uniform data type">
<Enum name="ShaderUniformDataType" valueCount="13" desc="Shader uniform data type">
<Value name="SHADER_UNIFORM_FLOAT" integer="0" desc="Shader uniform type: float" />
<Value name="SHADER_UNIFORM_VEC2" integer="1" desc="Shader uniform type: vec2 (2 float)" />
<Value name="SHADER_UNIFORM_VEC3" integer="2" desc="Shader uniform type: vec3 (3 float)" />
@ -547,7 +548,11 @@
<Value name="SHADER_UNIFORM_IVEC2" integer="5" desc="Shader uniform type: ivec2 (2 int)" />
<Value name="SHADER_UNIFORM_IVEC3" integer="6" desc="Shader uniform type: ivec3 (3 int)" />
<Value name="SHADER_UNIFORM_IVEC4" integer="7" desc="Shader uniform type: ivec4 (4 int)" />
<Value name="SHADER_UNIFORM_SAMPLER2D" integer="8" desc="Shader uniform type: sampler2d" />
<Value name="SHADER_UNIFORM_UINT" integer="8" desc="Shader uniform type: unsigned int" />
<Value name="SHADER_UNIFORM_UIVEC2" integer="9" desc="Shader uniform type: uivec2 (2 unsigned int)" />
<Value name="SHADER_UNIFORM_UIVEC3" integer="10" desc="Shader uniform type: uivec3 (3 unsigned int)" />
<Value name="SHADER_UNIFORM_UIVEC4" integer="11" desc="Shader uniform type: uivec4 (4 unsigned int)" />
<Value name="SHADER_UNIFORM_SAMPLER2D" integer="12" desc="Shader uniform type: sampler2d" />
</Enum>
<Enum name="ShaderAttributeDataType" valueCount="4" desc="Shader attribute data types">
<Value name="SHADER_ATTRIB_FLOAT" integer="0" desc="Shader attribute type: float" />
@ -674,7 +679,7 @@
<Param type="unsigned int" name="frames" desc="" />
</Callback>
</Callbacks>
<Functions count="581">
<Functions count="582">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" />
@ -1181,6 +1186,9 @@
</Function>
<Function name="GetCharPressed" retType="int" paramCount="0" desc="Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty">
</Function>
<Function name="GetKeyName" retType="const char *" paramCount="1" desc="Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)">
<Param type="int" name="key" desc="" />
</Function>
<Function name="SetExitKey" retType="void" paramCount="1" desc="Set a custom key to exit program (default is ESC)">
<Param type="int" name="key" desc="" />
</Function>
@ -2479,10 +2487,10 @@
<Function name="TextToCamel" retType="const char *" paramCount="1" desc="Get Camel case notation version of provided string">
<Param type="const char *" name="text" desc="" />
</Function>
<Function name="TextToInteger" retType="int" paramCount="1" desc="Get integer value from text (negative values not supported)">
<Function name="TextToInteger" retType="int" paramCount="1" desc="Get integer value from text">
<Param type="const char *" name="text" desc="" />
</Function>
<Function name="TextToFloat" retType="float" paramCount="1" desc="Get float value from text (negative values not supported)">
<Function name="TextToFloat" retType="float" paramCount="1" desc="Get float value from text">
<Param type="const char *" name="text" desc="" />
</Function>
<Function name="DrawLine3D" retType="void" paramCount="3" desc="Draw a line in 3D world space">

View File

@ -216,6 +216,7 @@ RLAPI bool IsKeyUp(int key); // Check if a key
RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
RLAPI const char *GetKeyName(int key); // Get name of a QWERTY key on the current keyboard layout (eg returns string "q" for KEY_A on an AZERTY keyboard)
// Input-related functions: gamepads
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available

View File

@ -693,16 +693,12 @@ Global
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug|x64.ActiveCfg = Debug|x64
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug|x64.Build.0 = Debug|x64
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug|x86.ActiveCfg = Debug|Win32
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Debug|x86.Build.0 = Debug|Win32
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release|x64.ActiveCfg = Release|x64
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release|x64.Build.0 = Release|x64
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release|x86.ActiveCfg = Release|Win32
{F026020F-7B00-40C8-91C3-5DE85EC45A95}.Release|x86.Build.0 = Release|Win32
{6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{6B8BAAF1-75C7-4C68-80B8-0E2A9EABBD9A}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32

View File

@ -23,6 +23,7 @@ endif()
# Used as public API to be included into other projects
set(raylib_public_headers
raylib.h
rcamera.h
rlgl.h
raymath.h
)
@ -90,16 +91,7 @@ if (BUILD_SHARED_LIBS)
set_property(TARGET raylib PROPERTY C_VISIBILITY_PRESET hidden)
endif ()
# If building as a static lib *AND* using internal GLFW we
# need to set it up as a PRIVATE import so cmake doesn't complain
# it isn't declared on an install rule
if (INTERNAL_GLFW AND BUILD_SHARED_LIBS)
target_link_libraries(raylib PRIVATE glfw)
endif()
target_link_libraries(raylib PUBLIC "${LIBS_PRIVATE}")
target_link_libraries(raylib "${LIBS_PRIVATE}")
# Sets some compile time definitions for the pre-processor
# If CUSTOMIZE_BUILD option is on you will not use config.h by default

View File

@ -61,11 +61,10 @@
#------------------------------------------------------------------------------------------------
# Define target platform
PLATFORM ?= PLATFORM_DESKTOP
ifeq ($(PLATFORM), PLATFORM_DESKTOP)
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW
TARGET_PLATFORM = PLATFORM_DESKTOP_GLFW
else
TARGET_PLATFORM = $(PLATFORM)
TARGET_PLATFORM = $(PLATFORM)
endif
# Define required raylib variables
@ -122,7 +121,6 @@ SDL_INCLUDE_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/include
SDL_LIBRARY_PATH ?= $(RAYLIB_SRC_PATH)/external/SDL2/lib
SDL_LIBRARIES ?= -lSDL2 -lSDL2main
# Determine if the file has root access (only required to install raylib)
# "whoami" prints the name of the user that calls him (so, if it is the root user, "whoami" prints "root")
ROOT = $(shell whoami)
@ -664,8 +662,8 @@ raylib: $(OBJS)
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW))
# Compile raylib libray for web
#$(CC) $(OBJS) -r -o $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).bc
$(AR) rcs $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).a $(OBJS)
@echo "raylib library generated (lib$(RAYLIB_LIB_NAME).a)!"
$(AR) rcs $(RAYLIB_RELEASE_PATH)/lib$(RAYLIB_LIB_NAME).web.a $(OBJS)
@echo "raylib library generated (lib$(RAYLIB_LIB_NAME).web.a)!"
else
ifeq ($(RAYLIB_LIBTYPE),SHARED)
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW PLATFORM_DESKTOP_SDL PLATFORM_DESKTOP_RGFW))

View File

@ -151,6 +151,8 @@
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
#endif
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX 9
// Default shader vertex attribute names to set location points
// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience

661
src/external/RGFW.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -627,7 +627,7 @@ int SetGamepadMappings(const char *mappings)
// Set gamepad vibration
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
{
TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");
TRACELOG(LOG_WARNING, "SetGamepadVibration() not implemented on target platform");
}
// Set mouse position XY
@ -699,7 +699,7 @@ void PollInputEvents(void)
// Poll Events (registered events) until we reach TIMEOUT which indicates there are no events left to poll
// NOTE: Activity is paused if not enabled (platform.appEnabled)
while ((pollResult = ALooper_pollOnce(platform.appEnabled? 0 : -1, NULL, &pollEvents, (void**)&platform.source)) > ALOOPER_POLL_TIMEOUT)
while ((pollResult = ALooper_pollOnce(platform.appEnabled? 0 : -1, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT))
{
// Process this event
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
@ -786,7 +786,7 @@ int InitPlatform(void)
while (!CORE.Window.ready)
{
// Process events until we reach TIMEOUT, which indicates no more events queued.
while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, (void**)&platform.source)) > ALOOPER_POLL_TIMEOUT)
while ((pollResult = ALooper_pollOnce(0, NULL, &pollEvents, ((void **)&platform.source)) > ALOOPER_POLL_TIMEOUT))
{
// Process this event
if (platform.source != NULL) platform.source->process(platform.app, platform.source);
@ -1226,7 +1226,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
return 1; // Handled gamepad button
}
KeyboardKey key = (keycode > 0 && keycode < KEYCODE_MAP_SIZE)? mapKeycode[keycode] : KEY_NULL;
KeyboardKey key = ((keycode > 0) && (keycode < KEYCODE_MAP_SIZE))? mapKeycode[keycode] : KEY_NULL;
if (key != KEY_NULL)
{
// Save current key and its state

View File

@ -322,7 +322,7 @@ void SetWindowState(unsigned int flags)
}
// State change: FLAG_FULLSCREEN_MODE
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) != (flags & FLAG_FULLSCREEN_MODE))
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) != (flags & FLAG_FULLSCREEN_MODE) && ((flags & FLAG_FULLSCREEN_MODE) > 0))
{
ToggleFullscreen(); // NOTE: Window state flag updated inside function
}
@ -1088,7 +1088,7 @@ int SetGamepadMappings(const char *mappings)
// Set gamepad vibration
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
{
TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform");
TRACELOG(LOG_WARNING, "SetGamepadVibration() not available on target platform");
}
// Set mouse position XY

View File

@ -129,6 +129,7 @@ static bool RGFW_disableCursor = false;
static const unsigned short keyMappingRGFW[] = {
[RGFW_KEY_NULL] = KEY_NULL,
[RGFW_Return] = KEY_ENTER,
[RGFW_Return] = KEY_ENTER,
[RGFW_Apostrophe] = KEY_APOSTROPHE,
[RGFW_Comma] = KEY_COMMA,
[RGFW_Minus] = KEY_MINUS,
@ -168,7 +169,6 @@ static const unsigned short keyMappingRGFW[] = {
[RGFW_SuperL] = KEY_LEFT_SUPER,
#ifndef RGFW_MACOS
[RGFW_ShiftR] = KEY_RIGHT_SHIFT,
[RGFW_AltR] = KEY_RIGHT_ALT,
#endif
[RGFW_Space] = KEY_SPACE,
@ -496,7 +496,7 @@ void SetWindowIcons(Image *images, int count)
// Set title for window
void SetWindowTitle(const char *title)
{
RGFW_window_setName(platform.window, (char*)title);
RGFW_window_setName(platform.window, (char *)title);
CORE.Window.title = title;
}
@ -553,9 +553,9 @@ void SetWindowFocused(void)
void *GetWindowHandle(void)
{
#ifdef RGFW_WEBASM
return (void*)platform.window->src.ctx;
return (void *)platform.window->src.ctx;
#else
return (void*)platform.window->src.window;
return (void *)platform.window->src.window;
#endif
}
@ -598,7 +598,7 @@ Vector2 GetMonitorPosition(int monitor)
{
RGFW_monitor *mons = RGFW_getMonitors();
return (Vector2){(float)mons[monitor].rect.x, (float)mons[monitor].rect.y};
return (Vector2){ (float)mons[monitor].rect.x, (float)mons[monitor].rect.y };
}
// Get selected monitor width (currently used by monitor)
@ -620,7 +620,7 @@ int GetMonitorHeight(int monitor)
// Get selected monitor physical width in millimetres
int GetMonitorPhysicalWidth(int monitor)
{
RGFW_monitor* mons = RGFW_getMonitors();
RGFW_monitor *mons = RGFW_getMonitors();
return mons[monitor].physW;
}
@ -665,7 +665,7 @@ Vector2 GetWindowScaleDPI(void)
// Set clipboard text content
void SetClipboardText(const char *text)
{
RGFW_writeClipboard(text, (u32)strlen(text));
RGFW_writeClipboard(text, strlen(text));
}
// Get clipboard text content
@ -685,19 +685,25 @@ const char *GetClipboardText(void)
# define WINGDI_ALREADY_INCLUDED
# include "../external/win32_clipboard.h"
#endif
#endif
// Get clipboard image
Image GetClipboardImage(void)
{
Image image = {0};
Image image = { 0 };
unsigned long long int dataSize = 0;
void* fileData = NULL;
void *fileData = NULL;
#ifdef _WIN32
int width, height;
fileData = (void*)Win32GetClipboardImageData(&width, &height, &dataSize);
#if defined(SUPPORT_CLIPBOARD_IMAGE)
#if defined(_WIN32)
int width = 0;
int height = 0;
fileData = (void *)Win32GetClipboardImageData(&width, &height, &dataSize);
if (fileData == NULL) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data");
else image = LoadImageFromMemory(".bmp", fileData, dataSize);
#else
TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement `GetClipboardImage` for this OS");
TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement GetClipboardImage() for this OS");
#endif
if (fileData == NULL)
@ -742,9 +748,7 @@ void EnableCursor(void)
void DisableCursor(void)
{
RGFW_disableCursor = true;
RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0));
HideCursor();
}
@ -794,6 +798,12 @@ int SetGamepadMappings(const char *mappings)
return 0;
}
// Set gamepad vibration
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
{
TRACELOG(LOG_WARNING, "SetGamepadVibration() not available on target platform");
}
// Set mouse position XY
void SetMousePosition(int x, int y)
{
@ -857,7 +867,6 @@ void PollInputEvents(void)
// Register previous mouse position
// Reset last gamepad button/axis registered state
for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++)
{
// Check if gamepad is available
@ -1164,35 +1173,20 @@ int InitPlatform(void)
if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) flags |= RGFW_NO_BORDER;
if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) flags |= RGFW_NO_RESIZE;
if ((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) flags |= RGFW_TRANSPARENT_WINDOW;
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) flags |= RGFW_FULLSCREEN;
// NOTE: Some OpenGL context attributes must be set before window creation
// Check selection OpenGL version
if (rlGetVersion() == RL_OPENGL_21)
{
RGFW_setGLVersion(RGFW_GL_CORE, 2, 1);
}
else if (rlGetVersion() == RL_OPENGL_33)
{
RGFW_setGLVersion(RGFW_GL_CORE, 3, 3);
}
else if (rlGetVersion() == RL_OPENGL_43)
{
RGFW_setGLVersion(RGFW_GL_CORE, 4, 1);
}
if (rlGetVersion() == RL_OPENGL_21) RGFW_setGLVersion(RGFW_GL_CORE, 2, 1);
else if (rlGetVersion() == RL_OPENGL_33) RGFW_setGLVersion(RGFW_GL_CORE, 3, 3);
else if (rlGetVersion() == RL_OPENGL_43) RGFW_setGLVersion(RGFW_GL_CORE, 4, 1);
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
{
RGFW_setGLSamples(4);
}
if (CORE.Window.flags & FLAG_MSAA_4X_HINT) RGFW_setGLSamples(4);
platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags);
#ifndef PLATFORM_WEB_RGFW
RGFW_area screenSize = RGFW_getScreenSize();
CORE.Window.display.width = screenSize.w;
@ -1201,10 +1195,8 @@ int InitPlatform(void)
CORE.Window.display.width = CORE.Window.screen.width;
CORE.Window.display.height = CORE.Window.screen.height;
#endif
/*
I think this is needed by Raylib now ?
If so, rcore_destkop_sdl should be updated too
*/
// TODO: Is this needed by raylib now?
// If so, rcore_desktop_sdl should be updated too
//SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1);
@ -1244,7 +1236,7 @@ int InitPlatform(void)
// Load OpenGL extensions
// NOTE: GL procedures address loader is required to load extensions
//----------------------------------------------------------------------------
rlLoadExtensions((void*)RGFW_getProcAddress);
rlLoadExtensions((void *)RGFW_getProcAddress);
//----------------------------------------------------------------------------
// TODO: Initialize input events system

View File

@ -23,7 +23,7 @@
* Custom flag for rcore on target platform -not used-
*
* DEPENDENCIES:
* - SDL 2 or SLD 3 (main library): Windowing and inputs management
* - SDL 2 or SDL 3 (main library): Windowing and inputs management
* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs)
*
*
@ -68,7 +68,7 @@
#define MAX_CLIPBOARD_BUFFER_LENGTH 1024 // Size of the clipboard buffer used on GetClipboardText()
#endif
#if ((defined(SDL_MAJOR_VERSION) && SDL_MAJOR_VERSION == 3) && (defined(SDL_MINOR_VERSION) && SDL_MINOR_VERSION >= 1))
#if ((defined(SDL_MAJOR_VERSION) && (SDL_MAJOR_VERSION == 3)) && (defined(SDL_MINOR_VERSION) && (SDL_MINOR_VERSION >= 1)))
#ifndef PLATFORM_DESKTOP_SDL3
#define PLATFORM_DESKTOP_SDL3
#endif
@ -405,7 +405,7 @@ int SDL_GetNumTouchFingers(SDL_TouchID touchID)
// Since SDL2 doesn't have this function we leave a stub
// SDL_GetClipboardData function is available since SDL 3.1.3. (e.g. SDL3)
void* SDL_GetClipboardData(const char *mime_type, size_t *size)
void *SDL_GetClipboardData(const char *mime_type, size_t *size)
{
TRACELOG(LOG_WARNING, "Getting clipboard data that is not text is only available in SDL3");
@ -497,20 +497,21 @@ void ToggleBorderlessWindowed(void)
void MaximizeWindow(void)
{
SDL_MaximizeWindow(platform.window);
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED;
if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED;
}
// Set window state: minimized
void MinimizeWindow(void)
{
SDL_MinimizeWindow(platform.window);
CORE.Window.flags |= FLAG_WINDOW_MINIMIZED;
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED;
}
// Set window state: not minimized/maximized
void RestoreWindow(void)
{
SDL_ShowWindow(platform.window);
SDL_RestoreWindow(platform.window);
// CORE.Window.flags will be removed on PollInputEvents()
}
// Set window configuration state using flags
@ -1426,7 +1427,7 @@ void PollInputEvents(void)
// Window events are also polled (Minimized, maximized, close...)
#ifndef PLATFORM_DESKTOP_SDL3
#ifndef PLATFORM_DESKTOP_SDL3
// SDL3 states:
// The SDL_WINDOWEVENT_* events have been moved to top level events,
// and SDL_WINDOWEVENT has been removed.
@ -1436,7 +1437,7 @@ void PollInputEvents(void)
{
switch (event.window.event)
{
#endif
#endif
case SDL_WINDOWEVENT_RESIZED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
{
@ -1448,7 +1449,24 @@ void PollInputEvents(void)
CORE.Window.currentFbo.width = width;
CORE.Window.currentFbo.height = height;
CORE.Window.resizedLastFrame = true;
#ifndef PLATFORM_DESKTOP_SDL3
// Manually detect if the window was maximized (due to SDL2 restore being unreliable on some platforms) to remove the FLAG_WINDOW_MAXIMIZED accordingly
if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) > 0)
{
int borderTop = 0;
int borderLeft = 0;
int borderBottom = 0;
int borderRight = 0;
SDL_GetWindowBordersSize(platform.window, &borderTop, &borderLeft, &borderBottom, &borderRight);
SDL_Rect usableBounds;
SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(platform.window), &usableBounds);
if ((width + borderLeft + borderRight != usableBounds.w) && (height + borderTop + borderBottom != usableBounds.h)) CORE.Window.flags &= ~FLAG_WINDOW_MAXIMIZED;
}
#endif
} break;
case SDL_WINDOWEVENT_ENTER:
{
CORE.Input.Mouse.cursorOnScreen = true;
@ -1457,16 +1475,49 @@ void PollInputEvents(void)
{
CORE.Input.Mouse.cursorOnScreen = false;
} break;
case SDL_WINDOWEVENT_HIDDEN:
case SDL_WINDOWEVENT_MINIMIZED:
case SDL_WINDOWEVENT_FOCUS_LOST:
case SDL_WINDOWEVENT_SHOWN:
case SDL_WINDOWEVENT_FOCUS_GAINED:
{
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MINIMIZED;
} break;
case SDL_WINDOWEVENT_MAXIMIZED:
{
if ((CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) == 0) CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED;
} break;
case SDL_WINDOWEVENT_RESTORED:
#if defined(PLATFORM_DESKTOP_SDL3)
break;
#else
{
if ((SDL_GetWindowFlags(platform.window) & SDL_WINDOW_MINIMIZED) == 0)
{
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED;
}
#ifdef PLATFORM_DESKTOP_SDL3
if ((SDL_GetWindowFlags(platform.window) & SDL_WINDOW_MAXIMIZED) == 0)
{
if ((CORE.Window.flags & SDL_WINDOW_MAXIMIZED) > 0) CORE.Window.flags &= ~SDL_WINDOW_MAXIMIZED;
}
#endif
} break;
case SDL_WINDOWEVENT_HIDDEN:
{
if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) == 0) CORE.Window.flags |= FLAG_WINDOW_HIDDEN;
} break;
case SDL_WINDOWEVENT_SHOWN:
{
if ((CORE.Window.flags & FLAG_WINDOW_HIDDEN) > 0) CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN;
} break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
{
if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) > 0) CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED;
} break;
case SDL_WINDOWEVENT_FOCUS_LOST:
{
if ((CORE.Window.flags & FLAG_WINDOW_UNFOCUSED) == 0) CORE.Window.flags |= FLAG_WINDOW_UNFOCUSED;
} break;
#ifndef PLATFORM_DESKTOP_SDL3
default: break;
}
} break;
@ -1971,7 +2022,7 @@ void ClosePlatform(void)
// Scancode to keycode mapping
static KeyboardKey ConvertScancodeToKey(SDL_Scancode sdlScancode)
{
if (sdlScancode >= 0 && sdlScancode < SCANCODE_MAPPED_NUM)
if ((sdlScancode >= 0) && (sdlScancode < SCANCODE_MAPPED_NUM))
{
return mapScancodeToKey[sdlScancode];
}

View File

@ -622,7 +622,7 @@ int SetGamepadMappings(const char *mappings)
// Set gamepad vibration
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
{
TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform");
TRACELOG(LOG_WARNING, "SetGamepadVibration() not implemented on target platform");
}
// Set mouse position XY
@ -1529,7 +1529,7 @@ static void ConfigureEvdevDevice(char *device)
platform.absRange.height = absinfo[ABS_Y].info.maximum - absinfo[ABS_Y].info.minimum;
}
}
else if (isGamepad && !isMouse && !isKeyboard && platform.gamepadCount < MAX_GAMEPADS)
else if (isGamepad && !isMouse && !isKeyboard && (platform.gamepadCount < MAX_GAMEPADS))
{
deviceKindStr = "gamepad";
int index = platform.gamepadCount++;
@ -1893,7 +1893,7 @@ static int FindExactConnectorMode(const drmModeConnector *connector, uint width,
TRACELOG(LOG_TRACE, "DISPLAY: DRM Mode %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive");
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && (!allowInterlaced)) continue;
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !allowInterlaced) continue;
if ((mode->hdisplay == width) && (mode->vdisplay == height) && (mode->vrefresh == fps)) return i;
}
@ -1923,7 +1923,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
continue;
}
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && (!allowInterlaced))
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !allowInterlaced)
{
TRACELOG(LOG_TRACE, "DISPLAY: DRM shouldn't choose an interlaced mode");
continue;

View File

@ -381,6 +381,12 @@ int SetGamepadMappings(const char *mappings)
return 0;
}
// Set gamepad vibration
void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration)
{
TRACELOG(LOG_WARNING, "SetGamepadVibration() not implemented on target platform");
}
// Set mouse position XY
void SetMousePosition(int x, int y)
{

View File

@ -319,7 +319,7 @@ void ToggleBorderlessWindowed(void)
// Set window state: maximized, if resizable
void MaximizeWindow(void)
{
if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE && !(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED))
if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && !(CORE.Window.flags & FLAG_WINDOW_MAXIMIZED))
{
platform.unmaximizedWidth = CORE.Window.screen.width;
platform.unmaximizedHeight = CORE.Window.screen.height;
@ -342,7 +342,7 @@ void MinimizeWindow(void)
// Set window state: not minimized/maximized
void RestoreWindow(void)
{
if (glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE && (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED))
if ((glfwGetWindowAttrib(platform.handle, GLFW_RESIZABLE) == GLFW_TRUE) && (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED))
{
if (platform.unmaximizedWidth && platform.unmaximizedHeight) glfwSetWindowSize(platform.handle, platform.unmaximizedWidth, platform.unmaximizedHeight);
@ -1664,10 +1664,10 @@ static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *
int height = EM_ASM_INT( return window.innerHeight; );
if (width < (int)CORE.Window.screenMin.width) width = CORE.Window.screenMin.width;
else if (width > (int)CORE.Window.screenMax.width && CORE.Window.screenMax.width > 0) width = CORE.Window.screenMax.width;
else if ((width > (int)CORE.Window.screenMax.width) && (CORE.Window.screenMax.width > 0)) width = CORE.Window.screenMax.width;
if (height < (int)CORE.Window.screenMin.height) height = CORE.Window.screenMin.height;
else if (height > (int)CORE.Window.screenMax.height && CORE.Window.screenMax.height > 0) height = CORE.Window.screenMax.height;
else if ((height > (int)CORE.Window.screenMax.height) && (CORE.Window.screenMax.height > 0)) height = CORE.Window.screenMax.height;
emscripten_set_canvas_element_size("#canvas", width, height);
@ -1722,7 +1722,7 @@ static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadE
for (int i = 0; i < gamepadEvent->numButtons; ++i) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
*/
if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS))
if (gamepadEvent->connected && (gamepadEvent->index < MAX_GAMEPADS))
{
CORE.Input.Gamepad.ready[gamepadEvent->index] = true;
sprintf(CORE.Input.Gamepad.name[gamepadEvent->index], "%s", gamepadEvent->id);

View File

@ -801,10 +801,10 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
wave.sampleRate = wav.sampleRate;
wave.sampleSize = 16;
wave.channels = wav.channels;
wave.data = (short *)RL_MALLOC(wave.frameCount*wave.channels*sizeof(short));
wave.data = (short *)RL_MALLOC((size_t)wave.frameCount*wave.channels*sizeof(short));
// NOTE: We are forcing conversion to 16bit sample size on reading
drwav_read_pcm_frames_s16(&wav, wav.totalPCMFrameCount, wave.data);
drwav_read_pcm_frames_s16(&wav, wave.frameCount, wave.data);
}
else TRACELOG(LOG_WARNING, "WAVE: Failed to load WAV data");
@ -1550,7 +1550,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
else if ((strcmp(fileType, ".ogg") == 0) || (strcmp(fileType, ".OGG") == 0))
{
// Open ogg audio stream
stb_vorbis* ctxOgg = stb_vorbis_open_memory((const unsigned char *)data, dataSize, NULL, NULL);
stb_vorbis *ctxOgg = stb_vorbis_open_memory((const unsigned char *)data, dataSize, NULL, NULL);
if (ctxOgg != NULL)
{
@ -2461,23 +2461,18 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.channelsOut);
/* At this point we can convert the data to our mixing format. */
ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); /* Safe cast. */
// At this point we can convert the data to our mixing format
ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration);
ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration;
ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration);
totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; /* Safe cast. */
totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; // Safe cast
if (inputFramesProcessedThisIteration < inputFramesToProcessThisIteration)
{
break; /* Ran out of input data. */
}
if (inputFramesProcessedThisIteration < inputFramesToProcessThisIteration) break; // Ran out of input data
/* This should never be hit, but will add it here for safety. Ensures we get out of the loop when no input nor output frames are processed. */
if (inputFramesProcessedThisIteration == 0 && outputFramesProcessedThisIteration == 0)
{
break;
}
// This should never be hit, but added here for safety
// Ensures we get out of the loop when no input nor output frames are processed
if ((inputFramesProcessedThisIteration == 0) && (outputFramesProcessedThisIteration == 0)) break;
}
return totalOutputFramesProcessed;

View File

@ -801,7 +801,8 @@ typedef enum {
SHADER_LOC_MAP_BRDF, // Shader location: sampler2d texture: brdf
SHADER_LOC_VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds
SHADER_LOC_VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights
SHADER_LOC_BONE_MATRICES // Shader location: array of matrices uniform: boneMatrices
SHADER_LOC_BONE_MATRICES, // Shader location: array of matrices uniform: boneMatrices
SHADER_LOC_VERTEX_INSTANCE_TX // Shader location: vertex attribute: instanceTransform
} ShaderLocationIndex;
#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
@ -817,6 +818,10 @@ typedef enum {
SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int)
SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int)
SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int)
SHADER_UNIFORM_UINT, // Shader uniform type: unsigned int
SHADER_UNIFORM_UIVEC2, // Shader uniform type: uivec2 (2 unsigned int)
SHADER_UNIFORM_UIVEC3, // Shader uniform type: uivec3 (3 unsigned int)
SHADER_UNIFORM_UIVEC4, // Shader uniform type: uivec4 (4 unsigned int)
SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d
} ShaderUniformDataType;
@ -1150,20 +1155,19 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
// Automation events functionality
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 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 SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set)
RLAPI void StopAutomationEventRecording(void); // Stop recording automation events
RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event
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 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 SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
RLAPI void StartAutomationEventRecording(void); // Start recording automation events (AutomationEventList must be set)
RLAPI void StopAutomationEventRecording(void); // Stop recording automation events
RLAPI void PlayAutomationEvent(AutomationEvent event); // Play a recorded automation event
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
@ -1177,19 +1181,20 @@ RLAPI bool IsKeyReleased(int key); // Check if a key
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
RLAPI const char *GetKeyName(int key); // Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard)
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
// Input-related functions: gamepads
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id
RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once
RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed
RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once
RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed
RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed
RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds)
// Input-related functions: mouse
@ -1218,19 +1223,19 @@ RLAPI int GetTouchPointCount(void); // Get number of t
//------------------------------------------------------------------------------------
// Gestures and Touch Handling Functions (Module: rgestures)
//------------------------------------------------------------------------------------
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
RLAPI int GetGestureDetected(void); // Get latest detected gesture
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
RLAPI int GetGestureDetected(void); // Get latest detected gesture
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
RLAPI float GetGesturePinchAngle(void); // Get gesture pinch angle
//------------------------------------------------------------------------------------
// Camera System Functions (Module: rcamera)
//------------------------------------------------------------------------------------
RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode
RLAPI void UpdateCamera(Camera *camera, int mode); // Update camera position for selected mode
RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom); // Update camera movement/rotation
//------------------------------------------------------------------------------------
@ -1239,9 +1244,9 @@ RLAPI void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, f
// Set texture and rectangle to be used on shapes drawing
// NOTE: It can be useful when using basic shapes and one single font,
// defining a font char white rectangle would allow drawing everything in a single draw call
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing
RLAPI Texture2D GetShapesTexture(void); // Get texture that is used for shapes drawing
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
// Basic shapes drawing functions
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel using geometry [Can be slow, use with care]
@ -1283,11 +1288,11 @@ RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation
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
RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, 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(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(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 DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, 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(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(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 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
@ -1486,15 +1491,15 @@ RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint);
RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
// Text codepoints management functions (unicode characters)
RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array
RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array
RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
// Text strings management functions (no UTF-8 strings, only byte chars)
// NOTE: Some strings allocate memory internally for returned strings, just be careful!
@ -1509,14 +1514,14 @@ RLAPI const char *TextJoin(const char **textList, int count, const char *delimit
RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor!
RLAPI int TextFindIndex(const char *text, const char *find); // Find first text occurrence within a string
RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string
RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string
RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
RLAPI const char *TextToSnake(const char *text); // Get Snake case notation version of provided string
RLAPI const char *TextToCamel(const char *text); // Get Camel case notation version of provided string
RLAPI const char *TextToUpper(const char *text); // Get upper case version of provided string
RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string
RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
RLAPI const char *TextToSnake(const char *text); // Get Snake case notation version of provided string
RLAPI const char *TextToCamel(const char *text); // Get Camel case notation version of provided string
RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported)
RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported)
RLAPI int TextToInteger(const char *text); // Get integer value from text
RLAPI float TextToFloat(const char *text); // Get float value from text
//------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models)
@ -1609,14 +1614,14 @@ RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount);
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
// Collision detection functions
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere
RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere
RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)

View File

@ -328,8 +328,9 @@ RMAPI float Vector2DistanceSqr(Vector2 v1, Vector2 v2)
return result;
}
// Calculate angle between two vectors
// NOTE: Angle is calculated from origin point (0, 0)
// Calculate the signed angle from v1 to v2, relative to the origin (0, 0)
// NOTE: Coordinate system convention: positive X right, positive Y down,
// positive angles appear clockwise, and negative angles appear counterclockwise
RMAPI float Vector2Angle(Vector2 v1, Vector2 v2)
{
float result = 0.0f;
@ -2664,12 +2665,12 @@ inline const Vector2& operator *= (Vector2& lhs, const Matrix& rhs)
inline Vector2 operator / (const Vector2& lhs, const float& rhs)
{
return Vector2Scale(lhs, 1.0f / rhs);
return Vector2Scale(lhs, 1.0f/rhs);
}
inline const Vector2& operator /= (Vector2& lhs, const float& rhs)
{
lhs = Vector2Scale(lhs, 1.0f / rhs);
lhs = Vector2Scale(lhs, 1.0f/rhs);
return lhs;
}
@ -2758,12 +2759,12 @@ inline const Vector3& operator *= (Vector3& lhs, const Matrix& rhs)
inline Vector3 operator / (const Vector3& lhs, const float& rhs)
{
return Vector3Scale(lhs, 1.0f / rhs);
return Vector3Scale(lhs, 1.0f/rhs);
}
inline const Vector3& operator /= (Vector3& lhs, const float& rhs)
{
lhs = Vector3Scale(lhs, 1.0f / rhs);
lhs = Vector3Scale(lhs, 1.0f/rhs);
return lhs;
}
@ -2842,12 +2843,12 @@ inline const Vector4& operator *= (Vector4& lhs, const Vector4& rhs)
inline Vector4 operator / (const Vector4& lhs, const float& rhs)
{
return Vector4Scale(lhs, 1.0f / rhs);
return Vector4Scale(lhs, 1.0f/rhs);
}
inline const Vector4& operator /= (Vector4& lhs, const float& rhs)
{
lhs = Vector4Scale(lhs, 1.0f / rhs);
lhs = Vector4Scale(lhs, 1.0f/rhs);
return lhs;
}

View File

@ -154,7 +154,7 @@ RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAr
RLAPI void CameraRoll(Camera *camera, float angle);
RLAPI Matrix GetCameraViewMatrix(Camera *camera);
RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
RLAPI Matrix GetCameraProjectionMatrix(Camera *camera, float aspect);
#if defined(__cplusplus)
}

View File

@ -1355,6 +1355,7 @@ Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
shader.locs[SHADER_LOC_VERTEX_COLOR] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
shader.locs[SHADER_LOC_VERTEX_BONEIDS] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);
shader.locs[SHADER_LOC_VERTEX_BONEWEIGHTS] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS);
shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX);
// Get handles to GLSL uniform locations (vertex shader)
shader.locs[SHADER_LOC_MATRIX_MVP] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP);
@ -2071,7 +2072,7 @@ const char *GetDirectoryPath(const char *filePath)
// In case provided path does not contain a root drive letter (C:\, D:\) nor leading path separator (\, /),
// we add the current directory path to dirPath
if (filePath[1] != ':' && filePath[0] != '\\' && filePath[0] != '/')
if ((filePath[1] != ':') && (filePath[0] != '\\') && (filePath[0] != '/'))
{
// For security, we set starting path to current directory,
// obtained path will be concatenated to this
@ -2774,7 +2775,8 @@ unsigned int *ComputeMD5(unsigned char *data, int dataSize)
// Compute SHA-1 hash code
// NOTE: Returns a static int[5] array (20 bytes)
unsigned int *ComputeSHA1(unsigned char *data, int dataSize) {
unsigned int *ComputeSHA1(unsigned char *data, int dataSize)
{
#define ROTATE_LEFT(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
static unsigned int hash[5] = { 0 }; // Hash to be returned
@ -2809,17 +2811,16 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize) {
{
// Break chunk into sixteen 32-bit words w[j], 0 <= j <= 15
unsigned int w[80] = {0};
for (int i = 0; i < 16; i++) {
w[i] = (msg[offset + (i * 4) + 0] << 24) |
(msg[offset + (i * 4) + 1] << 16) |
(msg[offset + (i * 4) + 2] << 8) |
(msg[offset + (i * 4) + 3]);
for (int i = 0; i < 16; i++)
{
w[i] = (msg[offset + (i*4) + 0] << 24) |
(msg[offset + (i*4) + 1] << 16) |
(msg[offset + (i*4) + 2] << 8) |
(msg[offset + (i*4) + 3]);
}
// Message schedule: extend the sixteen 32-bit words into eighty 32-bit words:
for (int i = 16; i < 80; ++i) {
w[i] = ROTATE_LEFT(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16], 1);
}
for (int i = 16; i < 80; i++) w[i] = ROTATE_LEFT(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16], 1);
// Initialize hash value for this chunk
unsigned int a = hash[0];
@ -2833,16 +2834,23 @@ unsigned int *ComputeSHA1(unsigned char *data, int dataSize) {
unsigned int f = 0;
unsigned int k = 0;
if (i < 20) {
if (i < 20)
{
f = (b & c) | ((~b) & d);
k = 0x5A827999;
} else if (i < 40) {
}
else if (i < 40)
{
f = b ^ c ^ d;
k = 0x6ED9EBA1;
} else if (i < 60) {
}
else if (i < 60)
{
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
} else {
}
else
{
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
@ -3324,7 +3332,8 @@ float GetGamepadAxisMovement(int gamepad, int axis)
{
float value = (axis == GAMEPAD_AXIS_LEFT_TRIGGER || axis == GAMEPAD_AXIS_RIGHT_TRIGGER)? -1.0f : 0.0f;
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS)) {
if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (axis < MAX_GAMEPAD_AXIS))
{
float movement = value < 0.0f ? CORE.Input.Gamepad.axisState[gamepad][axis] : fabsf(CORE.Input.Gamepad.axisState[gamepad][axis]);
if (movement > value) value = CORE.Input.Gamepad.axisState[gamepad][axis];

View File

@ -355,6 +355,9 @@
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
#endif
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX 9
#endif
//----------------------------------------------------------------------------------
// Types and Structures Definition
@ -998,6 +1001,9 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX
#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX
#endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
@ -1884,16 +1890,6 @@ void rlActiveDrawBuffers(int count)
else
{
unsigned int buffers[8] = {
#if defined(GRAPHICS_API_OPENGL_ES3)
GL_COLOR_ATTACHMENT0_EXT,
GL_COLOR_ATTACHMENT1_EXT,
GL_COLOR_ATTACHMENT2_EXT,
GL_COLOR_ATTACHMENT3_EXT,
GL_COLOR_ATTACHMENT4_EXT,
GL_COLOR_ATTACHMENT5_EXT,
GL_COLOR_ATTACHMENT6_EXT,
GL_COLOR_ATTACHMENT7_EXT,
#else
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
@ -1902,14 +1898,9 @@ void rlActiveDrawBuffers(int count)
GL_COLOR_ATTACHMENT5,
GL_COLOR_ATTACHMENT6,
GL_COLOR_ATTACHMENT7,
#endif
};
#if defined(GRAPHICS_API_OPENGL_ES3)
glDrawBuffersEXT(count, buffers);
#else
glDrawBuffers(count, buffers);
#endif
}
}
else TRACELOG(LOG_WARNING, "GL: One color buffer active by default");
@ -3310,6 +3301,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
// Activate Trilinear filtering if mipmaps are available
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapCount); // user defined mip count would break without this.
}
#endif
@ -3959,7 +3951,7 @@ void rlDrawVertexArrayElements(int offset, int count, const void *buffer)
void rlDrawVertexArrayInstanced(int offset, int count, int instances)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glDrawArraysInstanced(GL_TRIANGLES, 0, count, instances);
glDrawArraysInstanced(GL_TRIANGLES, offset, count, instances);
#endif
}
@ -4216,6 +4208,7 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCE_TX, RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCE_TX);
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);

View File

@ -96,9 +96,9 @@
#endif
#if defined(SUPPORT_MESH_GENERATION)
#define PAR_MALLOC(T, N) ((T*)RL_MALLOC(N*sizeof(T)))
#define PAR_CALLOC(T, N) ((T*)RL_CALLOC(N*sizeof(T), 1))
#define PAR_REALLOC(T, BUF, N) ((T*)RL_REALLOC(BUF, sizeof(T)*(N)))
#define PAR_MALLOC(T, N) ((T *)RL_MALLOC(N*sizeof(T)))
#define PAR_CALLOC(T, N) ((T *)RL_CALLOC(N*sizeof(T), 1))
#define PAR_REALLOC(T, BUF, N) ((T *)RL_REALLOC(BUF, sizeof(T)*(N)))
#define PAR_FREE RL_FREE
#if defined(_MSC_VER) // Disable some MSVC warning
@ -1734,12 +1734,12 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
// no faster, since we're transferring all the transform matrices anyway
instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false);
// Instances transformation matrices are send to shader attribute location: SHADER_LOC_MATRIX_MODEL
// Instances transformation matrices are sent to shader attribute location: SHADER_LOC_VERTEX_INSTANCE_TX
for (unsigned int i = 0; i < 4; i++)
{
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), i*sizeof(Vector4));
rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 1);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 4, RL_FLOAT, 0, sizeof(Matrix), i*sizeof(Vector4));
rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_VERTEX_INSTANCE_TX] + i, 1);
}
rlDisableVertexBuffer();
@ -2270,50 +2270,73 @@ void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame)
{
if (frame >= anim.frameCount) frame = frame%anim.frameCount;
// Get first mesh which have bones
int firstMeshWithBones = -1;
for (int i = 0; i < model.meshCount; i++)
{
if (model.meshes[i].boneMatrices)
{
assert(model.meshes[i].boneCount == anim.boneCount);
for (int boneId = 0; boneId < model.meshes[i].boneCount; boneId++)
if (firstMeshWithBones == -1)
{
Vector3 inTranslation = model.bindPose[boneId].translation;
Quaternion inRotation = model.bindPose[boneId].rotation;
Vector3 inScale = model.bindPose[boneId].scale;
firstMeshWithBones = i;
break;
}
}
}
Vector3 outTranslation = anim.framePoses[frame][boneId].translation;
Quaternion outRotation = anim.framePoses[frame][boneId].rotation;
Vector3 outScale = anim.framePoses[frame][boneId].scale;
// Update all bones and boneMatrices of first mesh with bones.
for (int boneId = 0; boneId < anim.boneCount; boneId++)
{
Vector3 inTranslation = model.bindPose[boneId].translation;
Quaternion inRotation = model.bindPose[boneId].rotation;
Vector3 inScale = model.bindPose[boneId].scale;
Vector3 invTranslation = Vector3RotateByQuaternion(Vector3Negate(inTranslation), QuaternionInvert(inRotation));
Quaternion invRotation = QuaternionInvert(inRotation);
Vector3 invScale = Vector3Divide((Vector3){ 1.0f, 1.0f, 1.0f }, inScale);
Vector3 outTranslation = anim.framePoses[frame][boneId].translation;
Quaternion outRotation = anim.framePoses[frame][boneId].rotation;
Vector3 outScale = anim.framePoses[frame][boneId].scale;
Vector3 boneTranslation = Vector3Add(
Vector3RotateByQuaternion(Vector3Multiply(outScale, invTranslation),
outRotation), outTranslation);
Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation);
Vector3 boneScale = Vector3Multiply(outScale, invScale);
Quaternion invRotation = QuaternionInvert(inRotation);
Vector3 invTranslation = Vector3RotateByQuaternion(Vector3Negate(inTranslation), invRotation);
Vector3 invScale = Vector3Divide((Vector3){ 1.0f, 1.0f, 1.0f }, inScale);
Matrix boneMatrix = MatrixMultiply(MatrixMultiply(
QuaternionToMatrix(boneRotation),
MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)),
MatrixScale(boneScale.x, boneScale.y, boneScale.z));
Vector3 boneTranslation = Vector3Add(Vector3RotateByQuaternion(
Vector3Multiply(outScale, invTranslation), outRotation), outTranslation);
Quaternion boneRotation = QuaternionMultiply(outRotation, invRotation);
Vector3 boneScale = Vector3Multiply(outScale, invScale);
model.meshes[i].boneMatrices[boneId] = boneMatrix;
Matrix boneMatrix = MatrixMultiply(MatrixMultiply(
QuaternionToMatrix(boneRotation),
MatrixTranslate(boneTranslation.x, boneTranslation.y, boneTranslation.z)),
MatrixScale(boneScale.x, boneScale.y, boneScale.z));
model.meshes[firstMeshWithBones].boneMatrices[boneId] = boneMatrix;
}
// Update remaining meshes with bones
// NOTE: Using deep copy because shallow copy results in double free with 'UnloadModel()'
if (firstMeshWithBones != -1)
{
for (int i = firstMeshWithBones + 1; i < model.meshCount; i++)
{
if (model.meshes[i].boneMatrices)
{
memcpy(model.meshes[i].boneMatrices,
model.meshes[firstMeshWithBones].boneMatrices,
model.meshes[i].boneCount*sizeof(model.meshes[i].boneMatrices[0]));
}
}
}
}
}
// at least 2x speed up vs the old method
// at least 2x speed up vs the old method
// Update model animated vertex data (positions and normals) for a given frame
// NOTE: Updated data is uploaded to GPU
void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
{
UpdateModelAnimationBones(model,anim,frame);
for (int m = 0; m < model.meshCount; m++)
{
Mesh mesh = model.meshes[m];
@ -2322,8 +2345,12 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
int boneId = 0;
int boneCounter = 0;
float boneWeight = 0.0;
bool updated = false; // Flag to check when anim vertex information is updated
bool updated = false; // Flag to check when anim vertex information is updated
const int vValues = mesh.vertexCount*3;
// Skip if missing bone data, causes segfault without on some models
if ((mesh.boneWeights == NULL) || (mesh.boneIds == NULL)) continue;
for (int vCounter = 0; vCounter < vValues; vCounter += 3)
{
mesh.animVertices[vCounter] = 0;
@ -2335,35 +2362,39 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
mesh.animNormals[vCounter + 1] = 0;
mesh.animNormals[vCounter + 2] = 0;
}
// Iterates over 4 bones per vertex
// Iterates over 4 bones per vertex
for (int j = 0; j < 4; j++, boneCounter++)
{
boneWeight = mesh.boneWeights[boneCounter];
boneId = mesh.boneIds[boneCounter];
// Early stop when no transformation will be applied
if (boneWeight == 0.0f) continue;
animVertex = (Vector3){ mesh.vertices[vCounter], mesh.vertices[vCounter + 1], mesh.vertices[vCounter + 2] };
animVertex = Vector3Transform(animVertex,model.meshes[m].boneMatrices[boneId]);
mesh.animVertices[vCounter] += animVertex.x * boneWeight;
mesh.animVertices[vCounter+1] += animVertex.y * boneWeight;
mesh.animVertices[vCounter+2] += animVertex.z * boneWeight;
mesh.animVertices[vCounter] += animVertex.x*boneWeight;
mesh.animVertices[vCounter+1] += animVertex.y*boneWeight;
mesh.animVertices[vCounter+2] += animVertex.z*boneWeight;
updated = true;
// Normals processing
// NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
if (mesh.normals != NULL)
if ((mesh.normals != NULL) && (mesh.animNormals != NULL ))
{
animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] };
animNormal = Vector3Transform(animNormal,model.meshes[m].boneMatrices[boneId]);
animNormal = Vector3Transform(animNormal, MatrixTranspose(MatrixInvert(model.meshes[m].boneMatrices[boneId])));
mesh.animNormals[vCounter] += animNormal.x*boneWeight;
mesh.animNormals[vCounter + 1] += animNormal.y*boneWeight;
mesh.animNormals[vCounter + 2] += animNormal.z*boneWeight;
}
}
}
if (updated)
{
rlUpdateVertexBuffer(mesh.vboId[0], mesh.animVertices, mesh.vertexCount*3*sizeof(float), 0); // Update vertex position
rlUpdateVertexBuffer(mesh.vboId[2], mesh.animNormals, mesh.vertexCount*3*sizeof(float), 0); // Update vertex normals
if (mesh.normals != NULL) rlUpdateVertexBuffer(mesh.vboId[2], mesh.animNormals, mesh.vertexCount*3*sizeof(float), 0); // Update vertex normals
}
}
}
@ -2725,11 +2756,11 @@ Mesh GenMeshCube(float width, float height, float length)
#else // Use par_shapes library to generate cube mesh
/*
// Platonic solids:
par_shapes_mesh* par_shapes_create_tetrahedron(); // 4 sides polyhedron (pyramid)
par_shapes_mesh* par_shapes_create_cube(); // 6 sides polyhedron (cube)
par_shapes_mesh* par_shapes_create_octahedron(); // 8 sides polyhedron (diamond)
par_shapes_mesh* par_shapes_create_dodecahedron(); // 12 sides polyhedron
par_shapes_mesh* par_shapes_create_icosahedron(); // 20 sides polyhedron
par_shapes_mesh *par_shapes_create_tetrahedron(); // 4 sides polyhedron (pyramid)
par_shapes_mesh *par_shapes_create_cube(); // 6 sides polyhedron (cube)
par_shapes_mesh *par_shapes_create_octahedron(); // 8 sides polyhedron (diamond)
par_shapes_mesh *par_shapes_create_dodecahedron(); // 12 sides polyhedron
par_shapes_mesh *par_shapes_create_icosahedron(); // 20 sides polyhedron
*/
// Platonic solid generation: cube (6 sides)
// NOTE: No normals/texcoords generated by default
@ -3840,7 +3871,7 @@ void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector
for (int i = 0; i < 4; i++)
{
points[i] = Vector3Subtract(points[i], origin3D);
if (rotation != 0.0) points[i] = Vector3RotateByAxisAngle(points[i], forward, rotation * DEG2RAD);
if (rotation != 0.0) points[i] = Vector3RotateByAxisAngle(points[i], forward, rotation*DEG2RAD);
points[i] = Vector3Add(points[i], position);
}
@ -4049,7 +4080,7 @@ RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform)
for (int i = 0; i < triangleCount; i++)
{
Vector3 a, b, c;
Vector3* vertdata = (Vector3*)mesh.vertices;
Vector3 *vertdata = (Vector3 *)mesh.vertices;
if (mesh.indices)
{
@ -4190,30 +4221,27 @@ static void BuildPoseFromParentJoints(BoneInfo *bones, int boneCount, Transform
static Model LoadOBJ(const char *fileName)
{
tinyobj_attrib_t objAttributes = { 0 };
tinyobj_shape_t* objShapes = NULL;
tinyobj_shape_t *objShapes = NULL;
unsigned int objShapeCount = 0;
tinyobj_material_t* objMaterials = NULL;
tinyobj_material_t *objMaterials = NULL;
unsigned int objMaterialCount = 0;
Model model = { 0 };
model.transform = MatrixIdentity();
char* fileText = LoadFileText(fileName);
char *fileText = LoadFileText(fileName);
if (fileText == NULL)
{
TRACELOG(LOG_ERROR, "MODEL Unable to read obj file %s", fileName);
TRACELOG(LOG_ERROR, "MODEL: [%s] Unable to read obj file", fileName);
return model;
}
char currentDir[1024] = { 0 };
strcpy(currentDir, GetWorkingDirectory()); // Save current working directory
const char* workingDir = GetDirectoryPath(fileName); // Switch to OBJ directory for material path correctness
if (CHDIR(workingDir) != 0)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir);
}
const char *workingDir = GetDirectoryPath(fileName); // Switch to OBJ directory for material path correctness
if (CHDIR(workingDir) != 0) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir);
unsigned int dataSize = (unsigned int)strlen(fileText);
@ -4222,7 +4250,7 @@ static Model LoadOBJ(const char *fileName)
if (ret != TINYOBJ_SUCCESS)
{
TRACELOG(LOG_ERROR, "MODEL Unable to read obj data %s", fileName);
TRACELOG(LOG_ERROR, "MODEL: Unable to read obj data %s", fileName);
return model;
}
@ -4233,52 +4261,51 @@ static Model LoadOBJ(const char *fileName)
int lastMaterial = -1;
unsigned int meshIndex = 0;
// count meshes
// Count meshes
unsigned int nextShapeEnd = objAttributes.num_face_num_verts;
// see how many verts till the next shape
// See how many verts till the next shape
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
// walk all the faces
// Walk all the faces
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
{
if (faceId >= nextShapeEnd)
{
// try to find the last vert in the next shape
// Try to find the last vert in the next shape
nextShape++;
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
else nextShapeEnd = objAttributes.num_face_num_verts; // This is actually the total number of face verts in the file, not faces
meshIndex++;
}
else if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial)
else if ((lastMaterial != -1) && (objAttributes.material_ids[faceId] != lastMaterial))
{
meshIndex++;// if this is a new material, we need to allocate a new mesh
meshIndex++; // If this is a new material, we need to allocate a new mesh
}
lastMaterial = objAttributes.material_ids[faceId];
faceVertIndex += objAttributes.face_num_verts[faceId];
}
// allocate the base meshes and materials
// Allocate the base meshes and materials
model.meshCount = meshIndex + 1;
model.meshes = (Mesh*)MemAlloc(sizeof(Mesh) * model.meshCount);
model.meshes = (Mesh *)MemAlloc(sizeof(Mesh)*model.meshCount);
if (objMaterialCount > 0)
{
model.materialCount = objMaterialCount;
model.materials = (Material*)MemAlloc(sizeof(Material) * objMaterialCount);
model.materials = (Material *)MemAlloc(sizeof(Material)*objMaterialCount);
}
else // we must allocate at least one material
else // We must allocate at least one material
{
model.materialCount = 1;
model.materials = (Material*)MemAlloc(sizeof(Material) * 1);
model.materials = (Material *)MemAlloc(sizeof(Material)*1);
}
model.meshMaterial = (int*)MemAlloc(sizeof(int) * model.meshCount);
model.meshMaterial = (int *)MemAlloc(sizeof(int)*model.meshCount);
// see how many verts are in each mesh
unsigned int* localMeshVertexCounts = (unsigned int*)MemAlloc(sizeof(unsigned int) * model.meshCount);
// See how many verts are in each mesh
unsigned int *localMeshVertexCounts = (unsigned int *)MemAlloc(sizeof(unsigned int)*model.meshCount);
faceVertIndex = 0;
nextShapeEnd = objAttributes.num_face_num_verts;
@ -4287,23 +4314,22 @@ static Model LoadOBJ(const char *fileName)
unsigned int localMeshVertexCount = 0;
nextShape = 1;
if (objShapeCount > 1)
nextShapeEnd = objShapes[nextShape].face_offset;
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
// walk all the faces
// Walk all the faces
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
{
bool newMesh = false; // do we need a new mesh?
bool newMesh = false; // Do we need a new mesh?
if (faceId >= nextShapeEnd)
{
// try to find the last vert in the next shape
// Try to find the last vert in the next shape
nextShape++;
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
newMesh = true;
}
else if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial)
else if ((lastMaterial != -1) && (objAttributes.material_ids[faceId] != lastMaterial))
{
newMesh = true;
}
@ -4321,50 +4347,52 @@ static Model LoadOBJ(const char *fileName)
faceVertIndex += objAttributes.face_num_verts[faceId];
localMeshVertexCount += objAttributes.face_num_verts[faceId];
}
localMeshVertexCounts[meshIndex] = localMeshVertexCount;
for (int i = 0; i < model.meshCount; i++)
{
// allocate the buffers for each mesh
// Allocate the buffers for each mesh
unsigned int vertexCount = localMeshVertexCounts[i];
model.meshes[i].vertexCount = vertexCount;
model.meshes[i].triangleCount = vertexCount / 3;
model.meshes[i].triangleCount = vertexCount/3;
model.meshes[i].vertices = (float*)MemAlloc(sizeof(float) * vertexCount * 3);
model.meshes[i].normals = (float*)MemAlloc(sizeof(float) * vertexCount * 3);
model.meshes[i].texcoords = (float*)MemAlloc(sizeof(float) * vertexCount * 2);
model.meshes[i].colors = (unsigned char*)MemAlloc(sizeof(unsigned char) * vertexCount * 4);
model.meshes[i].vertices = (float *)MemAlloc(sizeof(float)*vertexCount*3);
model.meshes[i].normals = (float *)MemAlloc(sizeof(float)*vertexCount*3);
model.meshes[i].texcoords = (float *)MemAlloc(sizeof(float)*vertexCount*2);
model.meshes[i].colors = (unsigned char *)MemAlloc(sizeof(unsigned char)*vertexCount*4);
}
MemFree(localMeshVertexCounts);
localMeshVertexCounts = NULL;
// fill meshes
// Fill meshes
faceVertIndex = 0;
nextShapeEnd = objAttributes.num_face_num_verts;
// see how many verts till the next shape
// See how many verts till the next shape
nextShape = 1;
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
lastMaterial = -1;
meshIndex = 0;
localMeshVertexCount = 0;
// walk all the faces
// Walk all the faces
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
{
bool newMesh = false; // do we need a new mesh?
bool newMesh = false; // Do we need a new mesh?
if (faceId >= nextShapeEnd)
{
// try to find the last vert in the next shape
// Try to find the last vert in the next shape
nextShape++;
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
else nextShapeEnd = objAttributes.num_face_num_verts; // This is actually the total number of face verts in the file, not faces
newMesh = true;
}
// if this is a new material, we need to allocate a new mesh
// If this is a new material, we need to allocate a new mesh
if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial) newMesh = true;
lastMaterial = objAttributes.material_ids[faceId];
@ -4375,8 +4403,7 @@ static Model LoadOBJ(const char *fileName)
}
int matId = 0;
if (lastMaterial >= 0 && lastMaterial < (int)objMaterialCount)
matId = lastMaterial;
if ((lastMaterial >= 0) && (lastMaterial < (int)objMaterialCount)) matId = lastMaterial;
model.meshMaterial[meshIndex] = matId;
@ -4386,19 +4413,15 @@ static Model LoadOBJ(const char *fileName)
int normalIndex = objAttributes.faces[faceVertIndex].vn_idx;
int texcordIndex = objAttributes.faces[faceVertIndex].vt_idx;
for (int i = 0; i < 3; i++)
model.meshes[meshIndex].vertices[localMeshVertexCount * 3 + i] = objAttributes.vertices[vertIndex * 3 + i];
for (int i = 0; i < 3; i++) model.meshes[meshIndex].vertices[localMeshVertexCount*3 + i] = objAttributes.vertices[vertIndex*3 + i];
for (int i = 0; i < 3; i++)
model.meshes[meshIndex].normals[localMeshVertexCount * 3 + i] = objAttributes.normals[normalIndex * 3 + i];
for (int i = 0; i < 3; i++) model.meshes[meshIndex].normals[localMeshVertexCount*3 + i] = objAttributes.normals[normalIndex*3 + i];
for (int i = 0; i < 2; i++)
model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + i] = objAttributes.texcoords[texcordIndex * 2 + i];
for (int i = 0; i < 2; i++) model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + i] = objAttributes.texcoords[texcordIndex*2 + i];
model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + 1] = 1.0f - model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + 1];
model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1] = 1.0f - model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1];
for (int i = 0; i < 4; i++)
model.meshes[meshIndex].colors[localMeshVertexCount * 4 + i] = 255;
for (int i = 0; i < 4; i++) model.meshes[meshIndex].colors[localMeshVertexCount*4 + i] = 255;
faceVertIndex++;
localMeshVertexCount++;
@ -4412,8 +4435,7 @@ static Model LoadOBJ(const char *fileName)
tinyobj_shapes_free(objShapes, objShapeCount);
tinyobj_materials_free(objMaterials, objMaterialCount);
for (int i = 0; i < model.meshCount; i++)
UploadMesh(model.meshes + i, true);
for (int i = 0; i < model.meshCount; i++) UploadMesh(model.meshes + i, true);
// Restore current working directory
if (CHDIR(currentDir) != 0)
@ -5069,6 +5091,8 @@ static Image LoadImageFromCgltfImage(cgltf_image *cgltfImage, const char *texPat
{
Image image = { 0 };
if (cgltfImage == NULL) return image;
if (cgltfImage->uri != NULL) // Check if image data is provided as an uri (base64 or path)
{
if ((strlen(cgltfImage->uri) > 5) &&
@ -5110,7 +5134,7 @@ static Image LoadImageFromCgltfImage(cgltf_image *cgltfImage, const char *texPat
image = LoadImage(TextFormat("%s/%s", texPath, cgltfImage->uri));
}
}
else if (cgltfImage->buffer_view->buffer->data != NULL) // Check if image is provided as data buffer
else if (cgltfImage->buffer_view != NULL && cgltfImage->buffer_view->buffer->data != NULL) // Check if image is provided as data buffer
{
unsigned char *data = RL_MALLOC(cgltfImage->buffer_view->size);
int offset = (int)cgltfImage->buffer_view->offset;
@ -5664,7 +5688,7 @@ static Model LoadGLTF(const char *fileName)
}
// Load primitive indices data (if provided)
if (mesh->primitives[p].indices != NULL)
if ((mesh->primitives[p].indices != NULL) && (mesh->primitives[p].indices->buffer_view != NULL))
{
cgltf_accessor *attribute = mesh->primitives[p].indices;
@ -5681,7 +5705,7 @@ static Model LoadGLTF(const char *fileName)
else if (attribute->component_type == cgltf_component_type_r_8u)
{
// Init raylib mesh indices to copy glTF attribute data
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count * sizeof(unsigned short));
model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short));
LOAD_ATTRIBUTE_CAST(attribute, 1, unsigned char, model.meshes[meshIndex].indices, unsigned short)
}
@ -5736,7 +5760,7 @@ static Model LoadGLTF(const char *fileName)
for (int i = 0; i < model.boneCount; i++)
{
cgltf_node* node = skin.joints[i];
cgltf_node *node = skin.joints[i];
cgltf_float worldTransform[16];
cgltf_node_transform_world(node, worldTransform);
Matrix worldMatrix = {

View File

@ -247,7 +247,11 @@ extern void LoadFontDefault(void)
// we must consider data as little-endian order (alpha + gray)
((unsigned short *)imFont.data)[i + j] = 0xffff;
}
else ((unsigned short *)imFont.data)[i + j] = 0x00ff;
else
{
((unsigned char *)imFont.data)[(i + j)*sizeof(short)] = 0xFF;
((unsigned char *)imFont.data)[(i + j)*sizeof(short) + 1] = 0x00;
}
}
counter++;
@ -1282,7 +1286,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
{
Vector2 textSize = { 0 };
if ((isGpuReady && (font.texture.id == 0)) ||
if ((isGpuReady && (font.texture.id == 0)) ||
(text == NULL) || (text[0] == '\0')) return textSize; // Security check
int size = TextLength(text); // Get size in bytes of text
@ -2325,9 +2329,9 @@ static Font LoadBMFont(const char *fileName)
// Convert hexadecimal to decimal (single digit)
static unsigned char HexToInt(char hex)
{
if (hex >= '0' && hex <= '9') return hex - '0';
else if (hex >= 'a' && hex <= 'f') return hex - 'a' + 10;
else if (hex >= 'A' && hex <= 'F') return hex - 'A' + 10;
if ((hex >= '0') && (hex <= '9')) return hex - '0';
else if ((hex >= 'a') && (hex <= 'f')) return hex - 'a' + 10;
else if ((hex >= 'A') && (hex <= 'F')) return hex - 'A' + 10;
else return 0;
}

View File

@ -829,25 +829,22 @@ Image GenImageGradientLinear(int width, int height, int direction, Color start,
// Calculate how far the top-left pixel is along the gradient direction from the center of said gradient
float startingPos = 0.5f - (cosDir*width/2) - (sinDir*height/2);
// With directions that lie in the first or third quadrant (i.e. from top-left to
// With directions that lie in the first or third quadrant (i.e. from top-left to
// bottom-right or vice-versa), pixel (0, 0) is the farthest point on the gradient
// (i.e. the pixel which should become one of the gradient's ends color); while for
// directions that lie in the second or fourth quadrant, that point is pixel (width, 0).
float maxPosValue =
((signbit(sinDir) != 0) == (signbit(cosDir) != 0))
? fabsf(startingPos)
: fabsf(startingPos+width*cosDir);
float maxPosValue = ((signbit(sinDir) != 0) == (signbit(cosDir) != 0))? fabsf(startingPos) : fabsf(startingPos + width*cosDir);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
// Calculate the relative position of the pixel along the gradient direction
float pos = (startingPos + (i*cosDir + j*sinDir)) / maxPosValue;
float pos = (startingPos + (i*cosDir + j*sinDir))/maxPosValue;
float factor = pos;
factor = (factor > 1.0f)? 1.0f : factor; // Clamp to [-1,1]
factor = (factor < -1.0f)? -1.0f : factor; // Clamp to [-1,1]
factor = factor / 2 + 0.5f;
factor = factor/2.0f + 0.5f;
// Generate the color for this pixel
pixels[j*width + i].r = (int)((float)end.r*factor + (float)start.r*(1.0f - factor));
@ -1007,7 +1004,8 @@ Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float
{
Color *pixels = (Color *)RL_MALLOC(width*height*sizeof(Color));
float aspectRatio = (float)width / (float)height;
float aspectRatio = (float)width/(float)height;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
@ -3567,7 +3565,7 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co
ImageDrawLine(dst, x1, y1, x2, y2, color);
// Determine if the line is more horizontal or vertical
if (dx != 0 && abs(dy/dx) < 1)
if ((dx != 0) && (abs(dy/dx) < 1))
{
// Line is more horizontal
// Calculate half the width of the line
@ -4206,8 +4204,10 @@ TextureCubemap LoadTextureCubemap(Image image, int layout)
ImageFormat(&faces, image.format);
Image mipmapped = ImageCopy(image);
#if defined(SUPPORT_IMAGE_MANIPULATION)
ImageMipmaps(&mipmapped);
ImageMipmaps(&faces);
#endif
// NOTE: Image formatting does not work with compressed textures
@ -5387,7 +5387,7 @@ static float HalfToFloat(unsigned short x)
const unsigned int e = (x & 0x7C00) >> 10; // Exponent
const unsigned int m = (x & 0x03FF) << 13; // Mantissa
const float fm = (float)m;
const unsigned int v = (*(unsigned int*)&fm) >> 23; // Evil log2 bit hack to count leading zeros in denormalized format
const unsigned int v = (*(unsigned int *)&fm) >> 23; // Evil log2 bit hack to count leading zeros in denormalized format
const unsigned int r = (x & 0x8000) << 16 | (e != 0)*((e + 112) << 23 | m) | ((e == 0)&(m != 0))*((v - 37) << 23 | ((m << (150 - v)) & 0x007FE000)); // sign : normalized : denormalized
result = *(float *)&r;
@ -5400,7 +5400,7 @@ static unsigned short FloatToHalf(float x)
{
unsigned short result = 0;
const unsigned int b = (*(unsigned int*) & x) + 0x00001000; // Round-to-nearest-even: add last bit after truncated mantissa
const unsigned int b = (*(unsigned int *) & x) + 0x00001000; // Round-to-nearest-even: add last bit after truncated mantissa
const unsigned int e = (b & 0x7F800000) >> 23; // Exponent
const unsigned int m = b & 0x007FFFFF; // Mantissa; in line below: 0x007FF000 = 0x00800000-0x00001000 = decimal indicator flag - initial rounding