Merge branch 'raysan5:master' into master

This commit is contained in:
Colleague Riley 2024-06-26 15:59:49 -04:00 committed by GitHub
commit 642222cdc8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
56 changed files with 2467 additions and 1423 deletions

View File

@ -1,6 +1,6 @@
# raylib bindings and wrappers # raylib bindings and wrappers
Some people ported raylib to other languages in form of bindings or wrappers to the library. Here is a list with all the ports available. Feel free to send a PR if you know of any binding/wrapper not in this list. Some people ported raylib to other languages in the form of bindings or wrappers to the library. Here is a list with all the ports available. Feel free to send a PR if you know of any binding/wrapper not in this list.
### Language Bindings ### Language Bindings
@ -12,8 +12,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib | | [Raylib-cs](https://github.com/ChrisDill/Raylib-cs) | **5.0** | [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-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-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.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT | | [Raylib-CSharp](https://github.com/MrScautHD/Raylib-CSharp) | **5.1-dev** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
| [Raylib.NET](https://github.com/Odex64/Raylib.NET) | **5.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MIT |
| [cl-raylib](https://github.com/longlene/cl-raylib) | 4.0 | [Common Lisp](https://common-lisp.net) | MIT | | [cl-raylib](https://github.com/longlene/cl-raylib) | 4.0 | [Common Lisp](https://common-lisp.net) | MIT |
| [claylib/wrap](https://github.com/defun-games/claylib) | 4.5 | [Common Lisp](https://common-lisp.net) | Zlib | | [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 | | [claw-raylib](https://github.com/bohonghuang/claw-raylib) | **auto** | [Common Lisp](https://common-lisp.net) | Apache-2.0 |
@ -37,7 +36,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT | | [jaylib](https://github.com/janet-lang/jaylib) | **5.0** | [Janet](https://janet-lang.org) | MIT |
| [jaylib](https://github.com/electronstudio/jaylib/) | 4.5 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | | [jaylib](https://github.com/electronstudio/jaylib/) | 4.5 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE |
| [raylib-j](https://github.com/CreedVI/Raylib-J) | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | | [raylib-j](https://github.com/CreedVI/Raylib-J) | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib |
| [raylib.jl](https://github.com/irishgreencitrus/raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib | | [Raylib.jl](https://github.com/chengchingwen/Raylib.jl) | 4.2 | [Julia](https://julialang.org) | Zlib |
| [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** | | [kaylib](https://github.com/electronstudio/kaylib) | 3.7 | [Kotlin/native](https://kotlinlang.org) | **???** |
| [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib | | [KaylibKit](https://codeberg.org/Kenta/KaylibKit) | 4.5 | [Kotlin/native](https://kotlinlang.org) | Zlib |
| [raylib-lua](https://github.com/TSnake41/raylib-lua) | 4.5 | [Lua](http://www.lua.org) | ISC | | [raylib-lua](https://github.com/TSnake41/raylib-lua) | 4.5 | [Lua](http://www.lua.org) | ISC |
@ -75,6 +74,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| [raylib-wren](https://github.com/TSnake41/raylib-wren) | 4.0 | [Wren](http://wren.io) | ISC | | [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-zig](https://github.com/Not-Nik/raylib-zig) | **5.0** | [Zig](https://ziglang.org) | MIT |
| [raylib.zig](https://github.com/ryupold/raylib.zig) | **5.1-dev** | [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 | | [hare-raylib](https://git.sr.ht/~evantj/hare-raylib) | **auto** | [Hare](https://harelang.org) | Zlib |
| [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD | | [raylib-sunder](https://github.com/ashn-dot-dev/raylib-sunder) | **auto** | [Sunder](https://github.com/ashn-dot-dev/sunder) | 0BSD |
| [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **auto** | [BQN](https://mlochbaum.github.io/BQN) | MIT | | [rayed-bqn](https://github.com/Brian-ED/rayed-bqn) | **auto** | [BQN](https://mlochbaum.github.io/BQN) | MIT |

View File

@ -642,7 +642,7 @@ Release: raylib 4.0 - 8th Anniversary Edition (05 November 2021)
KEY CHANGES: KEY CHANGES:
- Naming consistency and coherency: Complete review of the library: syntax, naming, comments, decriptions, logs... - Naming consistency and coherency: Complete review of the library: syntax, naming, comments, decriptions, logs...
- Event Automation System: Support for input events recording and automatic re-playing, useful for automated testing and more! - Event Automation System: Support for input events recording and automatic re-playing, useful for automated testing and more!
- Custom game-loop control: Intended for advance users that want to control the events polling and the timming mechanisms - Custom game-loop control: Intended for advanced users that want to control the events polling and the timming mechanisms
- rlgl 4.0: Completely decoupling from platform layer and raylib, intended for standalone usage as single-file header-only - rlgl 4.0: Completely decoupling from platform layer and raylib, intended for standalone usage as single-file header-only
- raymath 1.5: Complete review following new conventions, to make it more portable and self-contained - raymath 1.5: Complete review following new conventions, to make it more portable and self-contained
- raygui 3.0: Complete review and official new release, more portable and self-contained, intended for tools development - raygui 3.0: Complete review and official new release, more portable and self-contained, intended for tools development

View File

@ -20,7 +20,7 @@ cmake_policy(SET CMP0063 NEW)
# Directory for easier includes # Directory for easier includes
# Anywhere you see include(...) you can check <root>/cmake for that file # Anywhere you see include(...) you can check <root>/cmake for that file
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# RAYLIB_IS_MAIN determines whether the project is being used from root # RAYLIB_IS_MAIN determines whether the project is being used from root
# or if it is added as a dependency (through add_subdirectory for example). # or if it is added as a dependency (through add_subdirectory for example).
@ -51,7 +51,7 @@ add_subdirectory(src raylib)
# Uninstall target # Uninstall target
if(NOT TARGET uninstall) if(NOT TARGET uninstall)
configure_file( configure_file(
"${CMAKE_MODULE_PATH}/Uninstall.cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Uninstall.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY) IMMEDIATE @ONLY)

View File

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

View File

@ -11,7 +11,7 @@ Do you enjoy raylib and want to contribute? Nice! You can help with the followin
- `Testing` - Can you find some bugs in raylib? - `Testing` - Can you find some bugs in raylib?
This document contains a set of guidelines to contribute to the project. These are mostly guidelines, not rules. This document contains a set of guidelines to contribute to the project. These are mostly guidelines, not rules.
Use your best judgement, and feel free to propose changes to this document in a pull request. Use your best judgment, and feel free to propose changes to this document in a pull request.
### raylib philosophy ### raylib philosophy
@ -28,14 +28,14 @@ Use your best judgement, and feel free to propose changes to this document in a
- [raylib license](LICENSE) - [raylib license](LICENSE)
- [raylib roadmap](ROADMAP.md) - [raylib roadmap](ROADMAP.md)
[raylib Wiki](https://github.com/raysan5/raylib/wiki) contains some information about the library and is open to anyone for edit. [raylib Wiki](https://github.com/raysan5/raylib/wiki) contains some information about the library and is open to anyone to edit.
Feel free to review it if required, just take care not to break something. Feel free to review it if required, just take care not to break something.
### raylib C coding conventions ### raylib C coding conventions
Despite being written in C, raylib does not follow the standard Hungarian notation for C, Despite being written in C, raylib does not follow the standard Hungarian notation for C,
it [follows Pascal-case/camel-case notation](https://github.com/raysan5/raylib/wiki/raylib-coding-conventions), it [follows Pascal-case/camel-case notation](https://github.com/raysan5/raylib/wiki/raylib-coding-conventions),
more common on C# language. All code formatting decisions have been carefully taken more common in C# language. All code formatting decisions have been carefully taken
to make it easier for students/users to read, write and understand code. to make it easier for students/users to read, write and understand code.
Source code is extensively commented for that purpose, raylib primary learning method is: Source code is extensively commented for that purpose, raylib primary learning method is:
@ -46,12 +46,12 @@ For detailed information on building raylib and examples, please check [raylib W
### Opening new Issues ### Opening new Issues
To open new issue for raylib (bug, enhancement, discussion...), just try to follow these rules: To open new issues for raylib (bug, enhancement, discussion...), just try to follow these rules:
- Make sure the issue has not already been reported before by searching on GitHub under Issues. - Make sure the issue has not already been reported before by searching on GitHub under Issues.
- If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a - If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a
title and clear description, as much relevant information as possible, and a code sample demonstrating the unexpected behavior. title and clear description, as much relevant information as possible, and a code sample demonstrating the unexpected behavior.
- If applies, attach some screenshot of the issue and a .zip file with the code sample and required resources. - 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. - 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. 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 is being done!
@ -60,7 +60,7 @@ To open new issue for raylib (bug, enhancement, discussion...), just try to foll
- Make sure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. - Make sure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
- Don't send big pull requests (lots of changelists), they are difficult to review. It's better to send small pull requests, one at a time. - Don't send big pull requests (lots of changelists), they are difficult to review. It's better to send small pull requests, one at a time.
- Verify that changes don't break the build (at least on Windows platform). As many platforms where you can test it, the better, but don't worry - Verify that changes don't break the build (at least on Windows platform). The more platforms where you can test it, the better, but don't worry
if you cannot test all the platforms. if you cannot test all the platforms.
### Contact information ### Contact information

View File

@ -1,6 +1,6 @@
## C Coding Style Conventions ## C Coding Style Conventions
Here it is a list with some of the code conventions used by raylib: Here is a list with some of the code conventions used by raylib:
Code element | Convention | Example Code element | Convention | Example
--- | :---: | --- --- | :---: | ---
@ -79,7 +79,7 @@ _NOTE: Avoid any space or special character in the files/dir naming!_
- Data files should be organized by context and usage in the game, think about the loading requirements for data and put all the resources that need to be loaded at the same time together. - Data files should be organized by context and usage in the game, think about the loading requirements for data and put all the resources that need to be loaded at the same time together.
- Use descriptive names for the files, it would be perfect if just reading the name of the file, it was possible to know what is that file and where fits in the game. - Use descriptive names for the files, it would be perfect if just reading the name of the file, it was possible to know what is that file and where fits in the game.
- Here it is an example, note that some resources require to be loaded all at once while other require to be loaded only at initialization (gui, font). - Here is an example, note that some resources require to be loaded all at once while other require to be loaded only at initialization (gui, font).
``` ```
resources/audio/fx/long_jump.wav resources/audio/fx/long_jump.wav

20
FAQ.md
View File

@ -40,13 +40,13 @@ Yes, raylib can be used to create any kind of application, not just videogames.
### How can I learn to use raylib? Is there some official documentation or tutorials? ### How can I learn to use raylib? Is there some official documentation or tutorials?
raylib does not provide a "standard" API reference documentation like other libraries, all of the raylib functionality is exposed in a simple [cheatsheet](https://www.raylib.com/cheatsheet/cheatsheet.html). Most of the functions are self-explanatory and the required parameters are very intuitive. It's also highly recommended to take a look to [`raylib.h`](https://github.com/raysan5/raylib/blob/master/src/raylib.h) header file or even the source code, that is very clean and organized, intended for teaching. raylib does not provide a "standard" API reference documentation like other libraries, all of the raylib functionality is exposed in a simple [cheatsheet](https://www.raylib.com/cheatsheet/cheatsheet.html). Most of the functions are self-explanatory and the required parameters are very intuitive. It's also highly recommended to take a look at [`raylib.h`](https://github.com/raysan5/raylib/blob/master/src/raylib.h) header file or even the source code, that is very clean and organized, intended for teaching.
raylib also provides a big [collection of examples](https://www.raylib.com/examples.html), to showcase the multiple functionality usage (+120 examples). Examples are categorized by the internal module functionality and also define an estimated level of difficulty to guide the users checking them. raylib also provides a big [collection of examples](https://www.raylib.com/examples.html), to showcase the multiple functionality usage (+120 examples). Examples are categorized by the internal module functionality and also define an estimated level of difficulty to guide the users checking them.
There is also a [FAQ on the raylib Wiki](https://github.com/raysan5/raylib/wiki/Frequently-Asked-Questions) with common technical questions. There is also a [FAQ on the raylib Wiki](https://github.com/raysan5/raylib/wiki/Frequently-Asked-Questions) with common technical questions.
There are also many tutorials on the internet and YouTube created by the growing raylib community along the years. There are also many tutorials on the internet and YouTube created by the growing raylib community over the years.
[raylib Discord Community](https://discord.gg/raylib) is also a great place to join and ask questions, the community is very friendly and always ready to help. [raylib Discord Community](https://discord.gg/raylib) is also a great place to join and ask questions, the community is very friendly and always ready to help.
@ -56,7 +56,7 @@ raylib is [free and open source](https://github.com/raysan5/raylib). Anyone can
### What is the raylib license? ### What is the raylib license?
raylib source code is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software. Check [LICENSE](https://github.com/raysan5/raylib/blob/master/LICENSE) for further details. raylib source code is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed-source software. Check [LICENSE](https://github.com/raysan5/raylib/blob/master/LICENSE) for further details.
### What platforms are supported by raylib? ### What platforms are supported by raylib?
@ -90,25 +90,25 @@ I personally consider raylib a graphics library with some high-level features ra
### What does raylib provide that other engines or libraries don't? ### 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 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? ### How does raylib compare to Unity/Unreal/Godot?
Those engines are usually big and complex to use, providing lot of functionality. They require some time to learn and test, they usually abstract many parts of the game development process and they usually provide a set of tools to assist users on their creations (like a GUI editor). Those engines are usually big and complex to use, providing lot of functionality. They require some time to learn and test, they usually abstract many parts of the game development process and they usually provide a set of tools to assist users on their creations (like a GUI editor).
raylib is a simple programming library, with no integrated tools or editors. It gives full control to users at a very low-level to create graphics applications in a more handmade way. raylib is a simple programming library, with no integrated tools or editors. It gives full control to users at a very low level to create graphics applications in a more handmade way.
### What development tools are required for raylib? ### What development tools are required for raylib?
To develop raylib programs you only need a text editor (with recommended code syntax highlighting) and a compiler. To develop raylib programs you only need a text editor (with recommended code syntax highlighting) and a compiler.
A [raylib Windows Installer](https://raysan5.itch.io/raylib) package is distributed including the Notepad++ editor and MinGW (GCC) compiler pre-configured for Windows for new users as an starter-pack but for more advance configurations with other editors/compilers, [raylib Wiki](https://github.com/raysan5/raylib/wiki) provides plenty of configuration tutorials. A [raylib Windows Installer](https://raysan5.itch.io/raylib) package is distributed including the Notepad++ editor and MinGW (GCC) compiler pre-configured for Windows for new users as an starter-pack but for more advanced configurations with other editors/compilers, [raylib Wiki](https://github.com/raysan5/raylib/wiki) provides plenty of configuration tutorials.
### What are raylib's external dependencies? ### What are raylib's external dependencies?
raylib is self-contained, it has no external dependencies to build it. But internally raylib uses several libraries from other developers, mostly used to load specific file-formats. raylib is self-contained, it has no external dependencies to build it. But internally raylib uses several libraries from other developers, mostly used to load specific file formats.
A detailed list of raylib dependencies could be found on the [raylib Wiki](https://github.com/raysan5/raylib/wiki/raylib-dependencies). A detailed list of raylib dependencies can be found on the [raylib Wiki](https://github.com/raysan5/raylib/wiki/raylib-dependencies).
### Can I use raylib with other technologies or libraries? ### Can I use raylib with other technologies or libraries?
@ -129,10 +129,10 @@ No, raylib is built on top of OpenGL API, and there are currently no plans to su
### What could I expect to see in raylib in the future? ### What could I expect to see in raylib in the future?
The main focus of the library is simplicity. Most of the efforts are invested in maintainability and bug-fixing. Despite new small features are regularly added, it's not the objective for raylib to become a full-featured engine. Personally I prefer to keep it small and enjoyable. The main focus of the library is simplicity. Most of the efforts are invested in maintainability and bug-fixing. Despite new small features being regularly added, it's not the objective for raylib to become a full-featured engine. Personally I prefer to keep it small and enjoyable.
### Who are the raylib developers? ### Who are the raylib developers?
The main raylib developer and maintainer is [Ramon Santamaria](https://www.linkedin.com/in/raysan/) but there's 360+ contributors that have helped by adding new features, testing the library and solving issues in the 9+ years life of raylib. The main raylib developer and maintainer is [Ramon Santamaria](https://www.linkedin.com/in/raysan/) but there are 360+ contributors that have helped by adding new features, testing the library and solving issues in the 9+ years life of raylib.
The full list of raylib contributors can be seen [on GitHub](https://github.com/raysan5/raylib/graphs/contributors). The full list of raylib contributors can be seen [on GitHub](https://github.com/raysan5/raylib/graphs/contributors).

View File

@ -3,13 +3,13 @@
introduction introduction
------------ ------------
I started developing videogames in 2006 and some years later I started teaching videogames development to young people with artistic profile, most of students had never written a single line of code. I started developing videogames in 2006 and some years later I started teaching videogames development to young people with artistic profiles, most of students had never written a single line of code.
I decided to start with C language basis and, after searching for the most simple and easy-to-use library to teach videogames programming, I found [WinBGI](https://winbgim.codecutter.org/); it was great and it worked very well with students, in just a couple of weeks, those students that had never written a single line of code were able to program (and understand) a simple PONG game, some of them even a BREAKOUT! I decided to start with C language basis and, after searching for the most simple and easy-to-use library to teach videogames programming, I found [WinBGI](https://winbgim.codecutter.org/); it was great and it worked very well with students, in just a couple of weeks, those students that had never written a single line of code were able to program (and understand) a simple PONG game, some of them even a BREAKOUT!
But WinBGI was not the clearer and most organized library for my taste. There were lots of things I found confusing and some function names were not clear enough for most of the students; not to mention the lack of transparencies support and no hardware acceleration. But WinBGI was not the clearest and most organized library for my taste. There were lots of things I found confusing and some function names were not clear enough for most of the students; not to mention the lack of transparencies support and no hardware acceleration.
So, I decided to create my own library, hardware accelerated, clear function names, quite organized, well structured, plain C coding and, the most important, primarily intended to learn videogames programming. So, I decided to create my own library, hardware accelerated, clear function names, quite organized, well structured, plain C coding and, most importantly, primarily intended to learn videogames programming.
My previous videogames development experience was mostly in C# and [XNA](https://en.wikipedia.org/wiki/Microsoft_XNA) and I really loved it, so, I decided to use C# language style notation and XNA naming conventions. That way, students were able to move from raylib to XNA, MonoGame or similar libs extremely easily. My previous videogames development experience was mostly in C# and [XNA](https://en.wikipedia.org/wiki/Microsoft_XNA) and I really loved it, so, I decided to use C# language style notation and XNA naming conventions. That way, students were able to move from raylib to XNA, MonoGame or similar libs extremely easily.
@ -20,28 +20,28 @@ Enjoy it.
notes on raylib 1.1 notes on raylib 1.1
------------------- -------------------
On April 2014, after 6 month of first raylib release, raylib 1.1 has been released. This new version presents a complete internal redesign of the library to support OpenGL 1.1, OpenGL 3.3+ and OpenGL ES 2.0. On April 2014, after 6 months of first raylib release, raylib 1.1 was released. This new version presents a complete internal redesign of the library to support OpenGL 1.1, OpenGL 3.3+ and OpenGL ES 2.0.
- A new module named [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been added to the library. This new module translates raylib-OpenGL-style immediate mode functions (i.e. rlVertex3f(), rlBegin(), ...) to different versions of OpenGL (1.1, 3.3+, ES2), selectable by one define. - A new module named [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been added to the library. This new module translates raylib-OpenGL-style immediate mode functions (i.e. rlVertex3f(), rlBegin(), ...) to different versions of OpenGL (1.1, 3.3+, ES2), selectable by one define.
- [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) also comes with a second new module named [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h), which includes a bunch of useful functions for 3d-math with vectors, matrices and quaternions. - [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) also comes with a second new module named [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h), which includes a bunch of useful functions for 3d-math with vectors, matrices and quaternions.
Some other big changes of this new version have been the support for OGG files loading and stream playing, and the support of DDS texture files (compressed and uncompressed) along with mipmaps support. Some other big changes of this new version have been the support for OGG file loading and stream playing, and the support of DDS texture files (compressed and uncompressed) along with mipmaps support.
Lots of code changes and lot of testing have concluded in this amazing new raylib 1.1. Lots of code changes and a lot of testing have concluded in this amazing new raylib 1.1.
notes on raylib 1.2 notes on raylib 1.2
------------------- -------------------
On September 2014, after 5 month of raylib 1.1 release, it comes raylib 1.2. Again, this version presents a complete internal redesign of [core](https://github.com/raysan5/raylib/blob/master/src/rcore.c) module to support two new platforms: [Android](http://www.android.com/) and [Raspberry Pi](http://www.raspberrypi.org/). On September 2014, after 5 months of raylib 1.1 release, it comes raylib 1.2. Again, this version presents a complete internal redesign of [core](https://github.com/raysan5/raylib/blob/master/src/rcore.c) module to support two new platforms: [Android](http://www.android.com/) and [Raspberry Pi](http://www.raspberrypi.org/).
It's been some month of really hard work to accomodate raylib to those new platforms while keeping it easy for the users. On Android, raylib manages internally the activity cicle, as well as the inputs; on Raspberry Pi, a complete raw input system has been written from scratch. It's been some months of really hard work to accommodate raylib to those new platforms while keeping it easy for the users. On Android, raylib manages internally the activity cycle, as well as the inputs; on Raspberry Pi, a complete raw input system has been written from scratch.
- A new display initialization system has been created to support multiple resolutions, adding black bars if required; user only defines desired screen size and it gets properly displayed. - A new display initialization system has been created to support multiple resolutions, adding black bars if required; the user only defines the desired screen size and it gets properly displayed.
- Now raylib can easily deploy games to Android devices and Raspberry Pi (console mode). - Now raylib can easily deploy games to Android devices and Raspberry Pi (console mode).
Lots of code changes and lot of testing have concluded in this amazing new raylib 1.2. Lots of code changes and a lot of testing have concluded in this amazing new raylib 1.2.
In December 2014, new raylib 1.2.2 was published with support to compile directly for web (html5) using [emscripten](http://kripken.github.io/emscripten-site/) and [asm.js](http://asmjs.org/). In December 2014, new raylib 1.2.2 was published with support to compile directly for web (html5) using [emscripten](http://kripken.github.io/emscripten-site/) and [asm.js](http://asmjs.org/).
@ -50,26 +50,26 @@ notes on raylib 1.3
On September 2015, after 1 year of raylib 1.2 release, arrives raylib 1.3. This version adds shaders functionality, improves tremendously textures module and also provides some new modules (camera system, gestures system, immediate-mode gui). On September 2015, after 1 year of raylib 1.2 release, arrives raylib 1.3. This version adds shaders functionality, improves tremendously textures module and also provides some new modules (camera system, gestures system, immediate-mode gui).
- Shaders support is the biggest addition to raylib 1.3, with support for easy shaders loading and use. Loaded shaders can be attached to 3d models or used as fullscreen postrocessing effects. A bunch of postprocessing shaders are also included in this release, check raylib/shaders folder. - Shaders support is the biggest addition to raylib 1.3, with support for easy shaders loading and use. Loaded shaders can be attached to 3d models or used as fullscreen post-processing effects. A bunch of postprocessing shaders are also included in this release, check raylib/shaders folder.
- Textures module has grown to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT); raylib 1.3 can load .dds, .pkm, .ktx, .astc and .pvr files. - Textures module has grown to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT); raylib 1.3 can load .dds, .pkm, .ktx, .astc and .pvr files.
- A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/rcamera.c) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_first_person.c). - A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/rcamera.h) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core/core_3d_camera_first_person.c).
- New [gestures](https://github.com/raysan5/raylib/blob/master/src/rgestures.h) module simplifies gestures detection on Android and HTML5 programs. - New [gestures](https://github.com/raysan5/raylib/blob/master/src/rgestures.h) module simplifies gestures detection on Android and HTML5 programs.
- [raygui](https://github.com/raysan5/raylib/blob/master/src/raygui.h), the new immediate-mode GUI module offers a set of functions to create simple user interfaces, primary intended for tools development. It's still in experimental state but already fully functional. - [raygui](https://github.com/raysan5/raylib/blob/master/examples/shapes/raygui.h), the new immediate-mode GUI module offers a set of functions to create simple user interfaces, primarily intended for tools development. It's still in an experimental state but already fully functional.
Most of the examples have been completely rewritten and +10 new examples have been added to show the new raylib features. Most of the examples have been completely rewritten and +10 new examples have been added to show the new raylib features.
Lots of code changes and lot of testing have concluded in this amazing new raylib 1.3. Lots of code changes and a lot of testing have concluded in this amazing new raylib 1.3.
notes on raylib 1.4 notes on raylib 1.4
------------------- -------------------
On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version, lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added. On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version, lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added.
- First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now a basic image processing can be done before converting the image to texture for usage. - First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1331) that have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now basic image processing can be done before converting the image to texture for usage.
- SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file. - SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file.
@ -77,12 +77,12 @@ On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For
- [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline. - [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline.
- [gestures](https://github.com/raysan5/raylib/blob/master/src/rgestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code. - [gestures](https://github.com/raysan5/raylib/blob/master/src/rgestures.h) module has been redesigned and simplified, now it can process touch events from any source, including the mouse. This way, gestures system can be used on any platform providing a unified way to work with inputs and allowing the user to create multiplatform games with only one source code.
- Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental). - Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental).
Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions, Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions,
and the addition of two simple functions for persistent data storage. Now raylib user can save and load game data in a file (only some platforms supported). A simple [easings](https://github.com/raysan5/raylib/blob/master/src/easings.h) module has also been added for values animation. and the addition of two simple functions for persistent data storage. Now raylib users can save and load game data in a file (only some platforms are supported). A simple [easings](https://github.com/raysan5/raylib/blob/master/examples/shapes/reasings.h) module has also been added for values animation.
Up to 8 new code examples have been added to show the new raylib features and +10 complete game samples have been provided to learn Up to 8 new code examples have been added to show the new raylib features and +10 complete game samples have been provided to learn
how to create some classic games like Arkanoid, Asteroids, Missile Commander, Snake or Tetris. how to create some classic games like Arkanoid, Asteroids, Missile Commander, Snake or Tetris.
@ -94,36 +94,36 @@ notes on raylib 1.5
On July 2016, after 5 months of raylib 1.4 release, arrives raylib 1.5. This new version is the biggest boost of the library until now, lots of parts of the library have been redesigned, lots of bugs have been solved and some **AMAZING** new features have been added. On July 2016, after 5 months of raylib 1.4 release, arrives raylib 1.5. This new version is the biggest boost of the library until now, lots of parts of the library have been redesigned, lots of bugs have been solved and some **AMAZING** new features have been added.
- VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameteres, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c). - VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameters, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c).
- New materials system: now raylib supports standard material properties for 3D models, including diffuse-ambient-specular colors and diffuse-normal-specular textures. Just assign values to standard material and everything is processed internally. - New materials system: now raylib supports standard material properties for 3D models, including diffuse-ambient-specular colors and diffuse-normal-specular textures. Just assign values to standard material and everything is processed internally.
- New lighting system: added support for up to 8 configurable lights and 3 light types: **point**, **directional** and **spot** lights. Just create a light, configure its parameters and raylib manages render internally for every 3d object using standard material. - New lighting system: added support for up to 8 configurable lights and 3 light types: **point**, **directional** and **spot** lights. Just create a light, configure its parameters and raylib manages to render internally for every 3d object using standard material.
- Complete gamepad support on Raspberry Pi: Gamepad system has been completely redesigned. Now multiple gamepads can be easily configured and used; gamepad data is read and processed in raw mode in a second thread. - Complete gamepad support on Raspberry Pi: Gamepad system has been completely redesigned. Now multiple gamepads can be easily configured and used; gamepad data is read and processed in raw mode in a second thread.
- Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been singnificantly improved, now physic objects are managed internally in a second thread. - Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been significantly improved, now physic objects are managed internally in a second thread.
- Audio chiptunese support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All this features thanks to the amazing work of @kd7tck. - Audio chiptunes support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All these features thanks to the amazing work of @kd7tck.
Other additions include a [2D camera system](https://github.com/raysan5/raylib/blob/master/examples/core_2d_rcamera.c), render textures for offline render (and most comprehensive [postprocessing](https://github.com/raysan5/raylib/blob/master/examples/shaders_postprocessing.c)) or support for legacy OpenGL 2.1 on desktop platforms. Other additions include a [2D camera system](https://github.com/raysan5/raylib/blob/master/examples/core/core_2d_rcamera.c), render textures for offline render (and most comprehensive [postprocessing](https://github.com/raysan5/raylib/blob/master/examples/shaders/shaders_postprocessing.c)) or support for legacy OpenGL 2.1 on desktop platforms.
This new version is so massive that is difficult to list all the improvements, most of raylib modules have been reviewed and [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.c) module has been completely redesigned to accomodate to new material-lighting systems and stereo rendering. You can check [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) file for a more detailed list of changes. This new version is so massive that is difficult to list all the improvements, most of the raylib modules have been reviewed and [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely redesigned to accommodate to new material-lighting systems and stereo rendering. You can check [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) file for a more detailed list of changes.
Up to 8 new code examples have been added to show the new raylib features and also some samples to show the usage of [rlgl](https://github.com/raysan5/raylib/blob/master/examples/rlgl_standalone.c) and [audio](https://github.com/raysan5/raylib/blob/master/examples/audio_standalone.c) raylib modules as standalone libraries. Up to 8 new code examples have been added to show the new raylib features and also some samples to show the usage of [rlgl](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c) and [audio](https://github.com/raysan5/raylib/blob/master/examples/audio_standalone.c) raylib modules as standalone libraries.
Lots of code changes (+400 commits) and lots of hours of hard work have concluded in this amazing new raylib 1.5. Lots of code changes (+400 commits) and lots of hours of hard work have concluded in this amazing new raylib 1.5.
notes on raylib 1.6 notes on raylib 1.6
------------------- -------------------
On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version conmmemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features: On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version commemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features:
- Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality. - Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
- Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more! - Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completely self-contained, no external libraries are required anymore!
- [Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing! - [Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, the library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing!
- Camera and gestures modules have been reviewed, highly simplified and ported to single-file header-only libraries for easier portability and usage flexibility. Consequently, camera system usage has been simplified in all examples. - Camera and gestures modules have been reviewed, highly simplified and ported to single-file header-only libraries for easier portability and usage flexibility. Consequently, camera system usage has been simplified in all examples.
@ -131,41 +131,41 @@ On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new v
- Improved textures and text functionality, adding new functions for texture filtering control and better TTF/AngelCode fonts loading and generation support. - Improved textures and text functionality, adding new functions for texture filtering control and better TTF/AngelCode fonts loading and generation support.
Build system improvement. Added support for raylib dynamic library generation (raylib.dll) for users that prefer dynamic library linking. Also thinking on advance users, it has been added pre-configured [Visual Studio C++ 2015 solution](https://github.com/raysan5/raylib/tree/master/project/vs2015) with raylib project and C/C++ examples for users that prefer that professional IDE and compiler. Build system improvement. Added support for raylib dynamic library generation (raylib.dll) for users that prefer dynamic library linking. Also thinking on advanced users, it has been added pre-configured [Visual Studio C++ 2015 solution](https://github.com/raysan5/raylib/tree/master/projects/vs2015) with raylib project and C/C++ examples for users that prefer that professional IDE and compiler.
New examples, new functions, complete code-base review, multiple bugs corrected... this is raylib 1.6. Enjoy making games. New examples, new functions, complete code-base review, multiple bugs corrected... this is raylib 1.6. Enjoy making games.
notes on raylib 1.7 notes on raylib 1.7
------------------- -------------------
On May 2017, around 6 month after raylib 1.6, comes another raylib instalment, raylib 1.7. This time library has been improved a lot in terms of consistency and cleanness. As stated in [this patreon article](https://www.patreon.com/posts/raylib-future-7501034), this new raylib version has focused efforts in becoming more simple and easy-to-use to learn videogames programming. Some highlights of this new version are: On May 2017, around 6 months after raylib 1.6, comes another raylib installment, raylib 1.7. This time library has been improved a lot in terms of consistency and cleanness. As stated in [this patreon article](https://www.patreon.com/posts/raylib-future-7501034), this new raylib version has focused efforts in becoming more simple and easy-to-use to learn videogames programming. Some highlights of this new version are:
- More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, functions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions! - More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, functions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions!
- Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advance users can customize raylib just choosing desired features, defining some configuration flags on modules compilation. That way users can control library size and available functionality. - Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advanced users can customize raylib just by choosing desired features, and defining some configuration flags on modules compilation. That way users can control library size and available functionality.
- Improved [build system](https://github.com/raysan5/raylib/blob/master/src/Makefile) for all supported platforms (Windows, Linux, OSX, RPI, Android, HTML5) with a unique Makefile to compile sources. Added support for Android compilation with a custom standalone toolchain and also multiple build compliation flags. - Improved [build system](https://github.com/raysan5/raylib/blob/master/src/Makefile) for all supported platforms (Windows, Linux, OSX, RPI, Android, HTML5) with a unique Makefile to compile sources. Added support for Android compilation with a custom standalone toolchain and also multiple build compilation flags.
- New [examples](http://www.raylib.com/examples.html) and [sample games](http://www.raylib.com/games.html) added. All samples material has been reviewed, removing useless examples and adding more comprehensive ones; all material has been ported to latest raylib version and tested in multiple platforms. Examples folder structure has been improved and also build systems. - New [examples](http://www.raylib.com/examples.html) and [sample games](http://www.raylib.com/games.html) added. All sample material has been reviewed, removing useless examples and adding more comprehensive ones; all material has been ported to the latest raylib version and tested on multiple platforms. Examples folder structure has been improved and also build systems.
- Improved library consistency and organization in general. Functions and parameters have been renamed, some parts of the library have been cleaned and simplyfied, some functions has been moved to examples (lighting, Oculus Rift CV1 support) towards a more generic library implementation. Lots of hours have been invested in this process... - Improved library consistency and organization in general. Functions and parameters have been renamed, some parts of the library have been cleaned and simplified, some functions have been moved to examples (lighting, Oculus Rift CV1 support) towards a more generic library implementation. Lots of hours have been invested in this process...
Some other features: Gamepad support on HTML5, RPI touch screen support, 32bit audio support, frames timing improvements, public log system, rres file format support, automatic GIF recording... Some other features: Gamepad support on HTML5, RPI touch screen support, 32bit audio support, frames timing improvements, public log system, rres file format support, automatic GIF recording...
And here it is another version of **raylib, a simple and easy-to-use library to enjoy videogames programming**. Enjoy it. And here is another version of **raylib, a simple and easy-to-use library to enjoy videogames programming**. Enjoy it.
notes on raylib 1.8 notes on raylib 1.8
------------------- -------------------
October 2017, around 5 months after latest raylib version, another release is published: raylib 1.8. Again, several modules of the library have been reviewed and some new functionality added. Main changes of this new release are: October 2017, around 5 months after latest raylib version, another release is published: raylib 1.8. Again, several modules of the library have been reviewed and some new functionality added. Main changes of this new release are:
- [Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning pourpouses. - [Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning purposes.
- [Parametric mesh generation](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing. - [Parametric mesh generation](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing.
- PBR Materials support, a completely redesigned shaders and material system allows advance materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference. - PBR Materials support, a completely redesigned shaders and material system allows advanced materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference.
- Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts. - Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into the final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts.
- [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions. - [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions.
@ -178,37 +178,37 @@ New installer provided, web updated, examples re-builded, documentation reviewed
notes on raylib 2.0 notes on raylib 2.0
------------------- -------------------
It's been 9 month since last raylib version was published, a lots of things have changed since then... This new raylib version represents an inflexion point in the development of the library and so, we jump to a new major version... Here it is the result of almost **5 years and thousands of hours of hard work**... here it is... **raylib 2.0** It's been 9 months since last raylib version was published, a lot of things have changed since then... This new raylib version represents an inflection point in the development of the library and so, we jump to a new major version... Here is the result of almost **5 years and thousands of hours of hard work**... here is... **raylib 2.0**
In **raylib 2.0** the full API has been carefully reviewed for better consistency, some new functionality has been added and the overall raylib experience has been greatly improved... The key features of new version are: In **raylib 2.0** the full API has been carefully reviewed for better consistency, some new functionality has been added and the overall raylib experience has been greatly improved... The key features of new version are:
- **Complete removal of external dependencies.** Finally, raylib does not require external libraries to be installed and linked along with raylib, all required libraries are contained and compiled within raylib. Obviously some external libraries are required but only the strictly platform-dependant ones, the ones that come installed with the OS. So, raylib becomes a self-contained platform-independent games development library. - **Complete removal of external dependencies.** Finally, raylib does not require external libraries to be installed and linked along with raylib, all required libraries are contained and compiled within raylib. Obviously some external libraries are required but only the strictly platform-dependent ones, the ones that come installed with the OS. So, raylib becomes a self-contained platform-independent games development library.
- **Full redesign of audio module to use the amazing miniaudio library**, along with external dependencies removal, OpenAL library has been replaced by [miniaudio](https://github.com/dr-soft/miniaudio), this brand new library offers automatic dynamic linking with default OS audio systems. Undoubtedly, the perfect low-level companion for raylib audio module! - **Full redesign of audio module to use the amazing miniaudio library**, along with external dependencies removal, OpenAL library has been replaced by [miniaudio](https://github.com/dr-soft/miniaudio), this brand new library offers automatic dynamic linking with default OS audio systems. Undoubtedly, the perfect low-level companion for raylib audio module!
- **Support for continuous integration building*** through AppVeyor and Travis CI. Consequently, raylib GitHub develop branch has been removed, simplyfing the code-base to a single master branch, always stable. Every time a new commit is deployed, library is compiled for **up-to 12 different configurations**, including multiple platforms, 32bit/64bit and multiple compiler options! All those binaries are automatically attached to any new release! - **Support for continuous integration building*** through AppVeyor and Travis CI. Consequently, raylib GitHub develop branch has been removed, simplifying the code-base to a single master branch, always stable. Every time a new commit is deployed, library is compiled for **up-to 12 different configurations**, including multiple platforms, 32bit/64bit and multiple compiler options! All those binaries are automatically attached to any new release!
- **More platforms supported and tested**, including BSD family (FreeBSD, openBSD, NetBSD, DragonFly) and Linux-based family platforms (openSUSE, Debian, Ubuntu, Arch, NixOS...). raylib has already been added to some package managers! Oh, and last but not less important, **Android 64bit** is already supported by raylib! - **More platforms supported and tested**, including BSD family (FreeBSD, openBSD, NetBSD, DragonFly) and Linux-based family platforms (openSUSE, Debian, Ubuntu, Arch, NixOS...). raylib has already been added to some package managers! Oh, and last but not less important, **Android 64bit** is already supported by raylib!
- **Support for TCC compiler!** Thanks to the lack of external dependencies, raylib can now be easily compiled with a **minimal toolchain**, like the one provide by Tiny C Compiler. It opens the door to an amazing future, allowing, for example, static linkage of libtcc for **runtime compilation of raylib-based code**... and the library itself if required! Moreover, TCC is blazing fast, it can compile all raylib in a couple of seconds! - **Support for TCC compiler!** Thanks to the lack of external dependencies, raylib can now be easily compiled with a **minimal toolchain**, like the one provided by Tiny C Compiler. It opens the door to an amazing future, allowing, for example, static linkage of libtcc for **runtime compilation of raylib-based code**... and the library itself if required! Moreover, TCC is blazing fast, it can compile all raylib in a couple of seconds!
- Refactored all raylib configuration #defines into a **centralized `config.h` header**, with more than **40 possible configuration options** to compile a totally customizable raylib version including only desired options like supported file-formats or specific functionality support. It allows generating a trully ligth-weight version of the library if desired! - Refactored all raylib configuration #defines into a **centralized `config.h` header**, with more than **40 possible configuration options** to compile a totally customizable raylib version including only desired options like supported file formats or specific functionality support. It allows generating a trully ligth-weight version of the library if desired!
A part of that, lots of new features, like a brand **new font rendering and packaging system** for TTF fonts with **SDF support** (thanks to the amazing STB headers), new functions for **CPU image data manipulation**, new orthographic 3d camera mode, a complete review of `raymath.h` single-file header-only library for better consistency and performance, new examples and way, [way more](https://github.com/raysan5/raylib/blob/master/CHANGELOG). A part of that, lots of new features, like a brand **new font rendering and packaging system** for TTF fonts with **SDF support** (thanks to the amazing STB headers), new functions for **CPU image data manipulation**, new orthographic 3d camera mode, a complete review of `raymath.h` single-file header-only library for better consistency and performance, new examples and way, [way more](https://github.com/raysan5/raylib/blob/master/CHANGELOG).
Probably by now, **raylib 2.0 is the simplest and easiest-to-use library to enjoy (and learn) videogames programming**... but, undoubtedly its development has exceeded any initial objective; raylib has become a simple and easy-to-use trully multiplatform portable standalone media library with thousands of possibilities... and that's just the beginning! Probably by now, **raylib 2.0 is the simplest and easiest-to-use library to enjoy (and learn) videogames programming**... but, undoubtedly its development has exceeded any initial objective; raylib has become a simple and easy-to-use truly multiplatform portable standalone media library with thousands of possibilities... and that's just the beginning!
notes on raylib 2.5 notes on raylib 2.5
------------------- -------------------
After almost one years since latest raylib installment, here it is **raylib 2.5**. A lot of work has been put on this new version and consequently I decided to bump versioning several digits. The complete list of changes and additions is humungous, details can be found in the [CHANGELOG](CHANGELOG), and here it is a short recap with the highlight improvements. After almost one years since latest raylib installment, here is **raylib 2.5**. A lot of work has been put on this new version and consequently I decided to bump versioning several digits. The complete list of changes and additions is humungous, details can be found in the [CHANGELOG](CHANGELOG), and here is a short recap with the highlight improvements.
- New **window management and file system functions** to query monitor information, deal with clipboard, check directory files info and even launch a URL with default system web browser. Experimental **High-DPI monitor support** has also been added through a compile flag. - New **window management and file system functions** to query monitor information, deal with clipboard, check directory files info and even launch a URL with default system web browser. Experimental **High-DPI monitor support** has also been added through a compile flag.
- **Redesigned Gamepad mechanism**, now generic for all platforms and gamepads, no more specific gamepad configurations. - **Redesigned Gamepad mechanism**, now generic for all platforms and gamepads, no more specific gamepad configurations.
**Redesigned UWP input system**, now raylib supports UWP seamlessly, previous implementation required a custom input system implemented in user code. **Redesigned UWP input system**, now raylib supports UWP seamlessly, previous implementation required a custom input system implemented in user code.
- `rlgl` module has been redesigned to **support a unique buffer for shapes drawing batching**, including LINES, TRIANGLES, QUADS in the same indexed buffer, also added support for multi-buffering if required. Additionally, `rlPushMatrix()`/`rlPopMatrix()` functionality has been reviewed to behave exactly like OpenGL 1.1, `models_rlgl_solar_system` example has been added to illustrate this behaviour. - `rlgl` module has been redesigned to **support a unique buffer for shapes drawing batching**, including LINES, TRIANGLES, QUADS in the same indexed buffer, also added support for multi-buffering if required. Additionally, `rlPushMatrix()`/`rlPopMatrix()` functionality has been reviewed to behave exactly like OpenGL 1.1, `models_rlgl_solar_system` example has been added to illustrate this behavior.
- **VR simulator** has been reviewed to **allow custom configuration of Head-Mounted-Device parameters and distortion shader**, `core_vr_simulator` has been properly adapted to showcase this new functionality, now the VR simulator is a generic configurable stereo rendering system that allows any VR device simulation with just a few lines of code or even dynamic tweaking of HMD parameters. - **VR simulator** has been reviewed to **allow custom configuration of Head-Mounted-Device parameters and distortion shader**, `core_vr_simulator` has been properly adapted to showcase this new functionality, now the VR simulator is a generic configurable stereo rendering system that allows any VR device simulation with just a few lines of code or even dynamic tweaking of HMD parameters.
@ -220,30 +220,30 @@ After almost one years since latest raylib installment, here it is **raylib 2.5*
- Experimental **cubemap support**, to automatically load multiple cubemap layouts (`LoadTextureCubemap()`). It required some internal `rlgl` redesign to allow cubemap textures. - Experimental **cubemap support**, to automatically load multiple cubemap layouts (`LoadTextureCubemap()`). It required some internal `rlgl` redesign to allow cubemap textures.
- **Skeletal animation support for 3d models**, this addition implied a redesign of `Model` data structure to accomodate multiple mesh/multiple materials support and bones information. Multiple models functions have been reviewed and added on this process, also **glTF models loading support** has been added. - **Skeletal animation support for 3d models**, this addition implied a redesign of `Model` data structure to accommodate multiple mesh/multiple materials support and bones information. Multiple models functions have been reviewed and added on this process, also **glTF models loading support** has been added.
This is a just a brief list with some of the changes of the new **raylib 2.5** but there is way more, about **70 new functions** have been added and several subsystems have been redesigned. More than **30 new examples** have been created to show the new functionalities and better illustrate already available ones. This is just a brief list with some of the changes of the new **raylib 2.5** but there is way more, about **70 new functions** have been added and several subsystems have been redesigned. More than **30 new examples** have been created to show the new functionalities and better illustrate already available ones.
It has been a long year of hard work to make raylib a solid technology to develop new products over it. It has been a long year of hard work to make raylib a solid technology to develop new products over it.
notes on raylib 3.0 notes on raylib 3.0
------------------- -------------------
After **10 months of intense development**, new raylib version is ready. Despite primary intended as a minor release, the [CHANGELIST](CHANGELOG) has grown so big and the library has changed so much internally that it finally became a major release. Library **internal ABI** has reveived a big redesign and review, targeting portability, integration with other platforms and making it a perfect option for other progamming [language bindings](BINDINGS.md). After **10 months of intense development**, new raylib version is ready. Despite primary intended as a minor release, the [CHANGELIST](CHANGELOG) has grown so big and the library has changed so much internally that it finally became a major release. Library **internal ABI** has received a big redesign and review, targeting portability, integration with other platforms and making it a perfect option for other programming [language bindings](BINDINGS.md).
- All **global variables** from the multiple raylib modules have been moved to a **global context state**, it has several benefits, first, better code readability with more comprehensive variables naming and categorization (organized by types, i.e. `CORE.Window.display.width`, `CORE.Input.Keyboard.currentKeyState` or `RLGL.State.modelview`). Second, it allows better memory management to load global context state dynamically when required (not at the moment), making it easy to implement a **hot-reloading mechanism** if desired. - All **global variables** from the multiple raylib modules have been moved to a **global context state**, it has several benefits, first, better code readability with more comprehensive variable naming and categorization (organized by types, i.e. `CORE.Window.display.width`, `CORE.Input.Keyboard.currentKeyState` or `RLGL.State.modelview`). Second, it allows better memory management to load global context state dynamically when required (not at the moment), making it easy to implement a **hot-reloading mechanism** if desired.
- All **memory allocations** on raylib and its dependencies now use `RL_MALLOC`, `RL_FREE` and similar macros. Now users can easely hook their own memory allocations mechanism if desired, having more control over memory allocated internally by the library. Additionally, it makes it easier to port the library to embedded devices where memory control is critical. For more info check raylib issue #1074. - All **memory allocations** on raylib and its dependencies now use `RL_MALLOC`, `RL_FREE` and similar macros. Now users can easily hook their own memory allocation mechanism if desired, having more control over memory allocated internally by the library. Additionally, it makes it easier to port the library to embedded devices where memory control is critical. For more info check raylib issue #1074.
- All **I/O file accesses** from raylib are being moved to **memory data access**, now all I/O file access is centralized into just four functions: `LoadFileData()`, `SaveFileData()`, `LoadFileText()`, `SaveFileText()`. Users can just update those functions to any I/O file system. This change makes it easier to integrate raylib with **Virtual File Systems** or custom I/O file implementations. - All **I/O file accesses** from raylib are being moved to **memory data access**, now all I/O file access is centralized into just four functions: `LoadFileData()`, `SaveFileData()`, `LoadFileText()`, `SaveFileText()`. Users can just update those functions to any I/O file system. This change makes it easier to integrate raylib with **Virtual File Systems** or custom I/O file implementations.
- All **raylib data structures** have been reviewed and optimized for pass-by-value usage. One of raylib distinctive design decisions is that most of its functions receive and return data by value. This design makes raylib really simple for newcomers, avoiding pointers and allowing complete access to all structures data in a simple way. The downside is that data is copied on stack every function call and that copy could be costly so, all raylib data structures have been optimized to **stay under 64 bytes** for fast copy and retrieve. - All **raylib data structures** have been reviewed and optimized for pass-by-value usage. One of raylib distinctive design decisions is that most of its functions receive and return data by value. This design makes raylib really simple for newcomers, avoiding pointers and allowing complete access to all structures data in a simple way. The downside is that data is copied on stack every function call and that copy could be costly so, all raylib data structures have been optimized to **stay under 64 bytes** for fast copy and retrieve.
- All **raylib tracelog messages** have been reviewd and categorized for a more comprehensive output information when developing raylib applications, now all display, input, timer, platform, auxiliar libraries, file-accesses, data loading/unloading issues are properly reported with more detailed and visual messages. - All **raylib tracelog messages** have been reviewed and categorized for a more comprehensive output information when developing raylib applications, now all display, input, timer, platform, auxiliar libraries, file-accesses, data loading/unloading issues are properly reported with more detailed and visual messages.
- `raudio` module has been internally reviewed to accomodate the new `Music` structure (converted from previous pointer format) and the module has been adapted to the **highly improved** [`miniaudio v0.10`](https://github.com/dr-soft/miniaudio). - `raudio` module has been internally reviewed to accommodate the new `Music` structure (converted from previous pointer format) and the module has been adapted to the **highly improved** [`miniaudio v0.10`](https://github.com/dr-soft/miniaudio).
- `text` module reviewed to **improve fonts generation** and text management functions, `Font` structure has been redesigned to better accomodate characters data, decoupling individual characters as `Image` glyphs from the font atlas parameters. Several improvements have been made to better support Unicode strings with UTF-8 encoding. - `text` module reviewed to **improve fonts generation** and text management functions, `Font` structure has been redesigned to better accommodate characters data, decoupling individual characters as `Image` glyphs from the font atlas parameters. Several improvements have been made to better support Unicode strings with UTF-8 encoding.
- **Multiple new examples added** (most of them contributed by raylib users) and all examples reviewed for correct execution on most of the supported platforms, specially Web and Raspberry Pi. A detailed categorized table has been created on github for easy examples navigation and code access. - **Multiple new examples added** (most of them contributed by raylib users) and all examples reviewed for correct execution on most of the supported platforms, specially Web and Raspberry Pi. A detailed categorized table has been created on github for easy examples navigation and code access.
@ -274,19 +274,19 @@ Here the list with some highlights for `raylib 3.5`.
- NEW **configuration options** exposed: For custom raylib builds, `config.h` now exposes **more than 150 flags and defines** to build raylib with only the desired features, for example, it allows to build a minimal raylib library in just some KB removing all external data filetypes supported, very useful to generate **small executables or embedded devices**. - NEW **configuration options** exposed: For custom raylib builds, `config.h` now exposes **more than 150 flags and defines** to build raylib with only the desired features, for example, it allows to build a minimal raylib library in just some KB removing all external data filetypes supported, very useful to generate **small executables or embedded devices**.
- NEW **automatic GIF recording** feature: Actually, automatic GIF recording (**CTRL+F12**) for any raylib application has been available for some versions but this feature was really slow and low-performant using an old gif library with many file-accesses. It has been replaced by a **high-performant alternative** (`msf_gif.h`) that operates directly on memory... and actually works very well! Try it out! - NEW **automatic GIF recording** feature: Actually, automatic GIF recording (**CTRL+F12**) for any raylib application has been available for some versions but this feature was really slow and low-performant using an old gif library with many file accesses. It has been replaced by a **high-performant alternative** (`msf_gif.h`) that operates directly on memory... and actually works very well! Try it out!
- NEW **RenderBatch** system: `rlgl` module has been redesigned to support custom **render batches** to allow grouping draw calls as desired, previous implementation just had one default render batch. This feature has not been exposed to raylib API yet but it can be used by advance users dealing with `rlgl` directly. For example, multiple `RenderBatch` can be created for 2D sprites and 3D geometry independently. - NEW **RenderBatch** system: `rlgl` module has been redesigned to support custom **render batches** to allow grouping draw calls as desired, previous implementation just had one default render batch. This feature has not been exposed to raylib API yet but it can be used by advanced users dealing with `rlgl` directly. For example, multiple `RenderBatch` can be created for 2D sprites and 3D geometry independently.
- NEW **Framebuffer** system: `rlgl` module now exposes an API for custom **Framebuffer attachments** (including cubemaps!). raylib `RenderTexture` is a basic use-case, just allowing color and depth textures, but this new API allows the creation of more advance Framebuffers with multiple attachments, like the **G-Buffers**. `GenTexture*()` functions have been redesigned to use this new API. - NEW **Framebuffer** system: `rlgl` module now exposes an API for custom **Framebuffer attachments** (including cubemaps!). raylib `RenderTexture` is a basic use-case, just allowing color and depth textures, but this new API allows the creation of more advanced Framebuffers with multiple attachments, like the **G-Buffers**. `GenTexture*()` functions have been redesigned to use this new API.
- Improved **software rendering**: raylib `Image*()` API is intended for software rendering, for those cases when **no GPU or no Window is available**. Those functions operate directly with **multi-format** pixel data on RAM and they have been completely redesigned to be way faster, specially for small resolutions and retro-gaming. Low-end embedded devices like **microcontrollers with custom displays** could benefit of this raylib functionality! - Improved **software rendering**: raylib `Image*()` API is intended for software rendering, for those cases when **no GPU or no Window is available**. Those functions operate directly with **multi-format** pixel data on RAM and they have been completely redesigned to be way faster, specially for small resolutions and retro-gaming. Low-end embedded devices like **microcontrollers with custom displays** could benefit of this raylib functionality!
- File **loading from memory**: Multiple functions have been redesigned to load data from memory buffers **instead of directly accessing the files**, now all raylib file loading/saving goes through a couple of functions that load data into memory. This feature allows **custom virtual-file-systems** and it gives more control to the user to access data already loaded in memory (i.e. images, fonts, sounds...). - File **loading from memory**: Multiple functions have been redesigned to load data from memory buffers **instead of directly accessing the files**, now all raylib file loading/saving goes through a couple of functions that load data into memory. This feature allows **custom virtual-file-systems** and it gives more control to the user to access data already loaded in memory (i.e. images, fonts, sounds...).
- NEW **Window states** management system: raylib `core` module has been redesigned to support Window **state check and setup more easily** and also **before/after Window initialization**, `SetConfigFlags()` has been reviewed and `SetWindowState()` has been added to control Window minification, maximization, hidding, focusing, topmost and more. - NEW **Window states** management system: raylib `core` module has been redesigned to support Window **state check and setup more easily** and also **before/after Window initialization**, `SetConfigFlags()` has been reviewed and `SetWindowState()` has been added to control Window minification, maximization, hiding, focusing, topmost and more.
- NEW **GitHub Actions** CI/CD system: Previous CI implementation has been reviewed and improved a lot to support **multiple build configurations** (platforms, compilers, static/shared build) and also an **automatic deploy system** has been implemented to automatically attach the diferent generated artifacts to every new release. As the system seems to work very good, previous CI platforms (AppVeyor/TravisCI) have been removed. - NEW **GitHub Actions** CI/CD system: Previous CI implementation has been reviewed and improved a lot to support **multiple build configurations** (platforms, compilers, static/shared build) and also an **automatic deploy system** has been implemented to automatically attach the different generated artifacts to every new release. As the system seems to work very good, previous CI platforms (AppVeyor/TravisCI) have been removed.
A part of those changes, many new functions have been added, some redundant functions removed and many functions have been reviewed for consistency with the full API (function name, parameters name and order, code formatting...). Again, this release represents is a **great improvement for raylib and marks the way forward** for the library. Make sure to check [CHANGELOG](CHANGELOG) for details! Hope you enjoy it! A part of those changes, many new functions have been added, some redundant functions removed and many functions have been reviewed for consistency with the full API (function name, parameters name and order, code formatting...). Again, this release represents is a **great improvement for raylib and marks the way forward** for the library. Make sure to check [CHANGELOG](CHANGELOG) for details! Hope you enjoy it!
@ -295,7 +295,7 @@ Happy holidays! :)
notes on raylib 3.7 notes on raylib 3.7
------------------- -------------------
April 2021, it's been about 4 months since last raylib release and here it is already a new one, this time with a bunch of internal redesigns and improvements. Surprisingly, on April the 8th I was awarded for a second time with the [Google Open Source Peer Bonus Award](https://opensource.googleblog.com/2021/04/announcing-first-group-of-google-open-source-peer-bonus-winners.html) for my contribution to open source world with raylib and it seems the library is getting some traction, what a better moment for a new release? Let's see what can be found in this new version: April 2021, it's been about 4 months since the last raylib release and here is already a new one, this time with a bunch of internal redesigns and improvements. Surprisingly, on April 8th I was awarded for a second time with the [Google Open Source Peer Bonus Award](https://opensource.googleblog.com/2021/04/announcing-first-group-of-google-open-source-peer-bonus-winners.html) for my contribution to open source world with raylib and it seems the library is getting some traction, what a better moment for a new release? Let's see what can be found in this new version:
Let's start with some numbers: Let's start with some numbers:
@ -315,18 +315,18 @@ Highlights for `raylib 3.7`:
- **ADDED: glTF animations support**. glTF is the preferred models file format to be used with raylib and along the addition of a models animation API on latest raylib versions, now animations support for glTF format has come to raylib, thanks for this great contribution to [Hristo Stamenov](@object71) - **ADDED: glTF animations support**. glTF is the preferred models file format to be used with raylib and along the addition of a models animation API on latest raylib versions, now animations support for glTF format has come to raylib, thanks for this great contribution to [Hristo Stamenov](@object71)
- **ADDED: Music streaming support from memory**. raylib has been adding the `Load*FromMemory()` option to all its supported file formats but **music streaming** was not supported yet... until now. Thanks to this great contribution by [Agnis "NeZvērs" Aldiņš](@nezvers), now raylib supports music streamming from memory data for all supported file formats: WAV, OGG, MP3, FLAC, XM and MOD. - **ADDED: Music streaming support from memory**. raylib has been adding the `Load*FromMemory()` option to all its supported file formats but **music streaming** was not supported yet... until now. Thanks to this great contribution by [Agnis "NeZvērs" Aldiņš](@nezvers), now raylib supports music streaming from memory data for all supported file formats: WAV, OGG, MP3, FLAC, XM and MOD.
- **RENAMED: enums values for consistency**. Most raylib enums names and values names have been renamed for consistency, now all value names start with the type of data they represent. It increases clarity and readability when using those values and also **improves overall library consistency**. - **RENAMED: enums values for consistency**. Most raylib enums names and values names have been renamed for consistency, now all value names start with the type of data they represent. It increases clarity and readability when using those values and also **improves overall library consistency**.
Beside those key changes, many functions have been reviewed with improvements and bug fixes, many of them contributed by the community! Thanks! And again, this release sets a **new milestone for raylib library**. Make sure to check [CHANGELOG](CHANGELOG) for detailed list of changes! Hope you enjoy this new raylib installment! Besides those key changes, many functions have been reviewed with improvements and bug fixes, many of them contributed by the community! Thanks! And again, this release sets a **new milestone for raylib library**. Make sure to check [CHANGELOG](CHANGELOG) for detailed list of changes! Hope you enjoy this new raylib installment!
Happy **gamedev/tools/graphics** programming! :) Happy **gamedev/tools/graphics** programming! :)
notes on raylib 4.0 - 8th Anniversary Edition notes on raylib 4.0 - 8th Anniversary Edition
--------------------------------------------- ---------------------------------------------
It's been about 6 months since last raylib release and it's been **8 years since I started with this project**, what an adventure! It's time for a new release: `raylib 4.0`, **the biggest release ever** and an inflexion point for the library. Many hours have been put in this release to make it special, **many library details have been polished**: syntax, naming conventions, code comments, functions descriptions, log outputs... Almost all the issues have been closed (only 3 remain open at the moment of this writing) and some amazing new features have been added. I expect this **`raylib 4.0`** to be a long term version (LTS), stable and complete enough for any new graphic/game/tool application development. It's been about 6 months since last raylib release and it's been **8 years since I started with this project**, what an adventure! It's time for a new release: `raylib 4.0`, **the biggest release ever** and an inflection point for the library. Many hours have been put in this release to make it special, **many library details have been polished**: syntax, naming conventions, code comments, functions descriptions, log outputs... Almost all the issues have been closed (only 3 remain open at the moment of this writing) and some amazing new features have been added. I expect this **`raylib 4.0`** to be a long-term version (LTS), stable and complete enough for any new graphic/game/tool application development.
Let's start with some numbers: Let's start with some numbers:
@ -339,11 +339,11 @@ Let's start with some numbers:
Highlights for `raylib 4.0`: Highlights for `raylib 4.0`:
- **Naming consistency and coherency**: `raylib` API has been completely reviewed to be consistent on naming conventions for data structures and functions, comments and descriptions have been reviewed, also the syntax of many symbols for consistency; some functions and structs have been renamed (i.e. `struct CharInfo` to `struct GlyphInfo`). Output log messages have been also improved to show more info to the users. Several articles have been writen in this process: [raylib_syntax analysis](https://github.com/raysan5/raylib/wiki/raylib-syntax-analysis) and [raylib API usage analysis](https://gist.github.com/raysan5/7c0c9fff1b6c19af24bb4a51b7383f1e). In general, a big polishment of the library to make it more consistent and coherent. - **Naming consistency and coherency**: `raylib` API has been completely reviewed to be consistent on naming conventions for data structures and functions, comments and descriptions have been reviewed, also the syntax of many symbols for consistency; some functions and structs have been renamed (i.e. `struct CharInfo` to `struct GlyphInfo`). Output log messages have been also improved to show more info to the users. Several articles have been written in this process: [raylib_syntax analysis](https://github.com/raysan5/raylib/wiki/raylib-syntax-analysis) and [raylib API usage analysis](https://gist.github.com/raysan5/7c0c9fff1b6c19af24bb4a51b7383f1e). In general, a big polishment of the library to make it more consistent and coherent.
- **Event Automation System**: This new _experimental_ feature has been added for future usage, it allows to **record input events and re-play them automatically**. This feature could be very useful to automatize examples testing but also for tutorials with assited game playing, in-game cinematics, speedruns, AI playing and more! Note this feature is still experimental. - **Event Automation System**: This new _experimental_ feature has been added for future usage, it allows to **record input events and re-play them automatically**. This feature could be very useful to automatize examples testing but also for tutorials with assisted game playing, in-game cinematics, speedruns, AI playing and more! Note this feature is still experimental.
- **Custom game-loop control**: As requested by some advance users, **the game-loop control can be exposed** compiling raylib with the config flag: `SUPPORT_CUSTOM_FRAME_CONTROL`. It's intended for advance users that want to control the events polling and also the timming mechanisms of their games. - **Custom game-loop control**: As requested by some advanced users, **the game-loop control can be exposed** compiling raylib with the config flag: `SUPPORT_CUSTOM_FRAME_CONTROL`. It's intended for advanced users that want to control the events polling and also the timing mechanisms of their games.
- [**`rlgl 4.0`**](https://github.com/raysan5/raylib/blob/master/src/rlgl.h): This module has been completely **decoupled from platform layer** and raylib, now `rlgl` single-file header-only library only depends on the multiple OpenGL backends supported, even the dependency on `raymath` has been removed. Additionally, **support for OpenGL 4.3** has been added, supporting compute shaders and Shader Storage Buffer Objects (SSBO). Now `rlgl` can be used as a complete standalone portable library to wrap several OpenGL version and providing **a simple and easy-to-use pseudo-OpenGL immediate-mode API**. - [**`rlgl 4.0`**](https://github.com/raysan5/raylib/blob/master/src/rlgl.h): This module has been completely **decoupled from platform layer** and raylib, now `rlgl` single-file header-only library only depends on the multiple OpenGL backends supported, even the dependency on `raymath` has been removed. Additionally, **support for OpenGL 4.3** has been added, supporting compute shaders and Shader Storage Buffer Objects (SSBO). Now `rlgl` can be used as a complete standalone portable library to wrap several OpenGL version and providing **a simple and easy-to-use pseudo-OpenGL immediate-mode API**.
@ -361,12 +361,12 @@ Highlights for `raylib 4.0`:
Those are some of the key features for this new release but actually there is way more! **Support for `VOX` ([MagikaVoxel](https://ephtracy.github.io/)) 3d model format** has been added, **new [raylib_game_template](https://github.com/raysan5/raylib-game-template)** repo shared, **new `EncodeDataBase64()` and `DecodeDataBase64()` functions** added, **improved HiDPI support**, new `DrawTextPro()` with support for text rotations, completely **reviewed `glTF` models loading**, added **`SeekMusicStream()` for music seeking**, many new examples and +20 examples reviewed... **hundreds of improvements and bug fixes**! Make sure to check [CHANGELOG](CHANGELOG) for a detailed list of changes! Those are some of the key features for this new release but actually there is way more! **Support for `VOX` ([MagikaVoxel](https://ephtracy.github.io/)) 3d model format** has been added, **new [raylib_game_template](https://github.com/raysan5/raylib-game-template)** repo shared, **new `EncodeDataBase64()` and `DecodeDataBase64()` functions** added, **improved HiDPI support**, new `DrawTextPro()` with support for text rotations, completely **reviewed `glTF` models loading**, added **`SeekMusicStream()` for music seeking**, many new examples and +20 examples reviewed... **hundreds of improvements and bug fixes**! Make sure to check [CHANGELOG](CHANGELOG) for a detailed list of changes!
Undoubtely, **this is the best raylib ever**. Enjoy gamedev/tools/graphics programming! :) Undoubtedly, **this is the best raylib ever**. Enjoy gamedev/tools/graphics programming! :)
notes on raylib 4.2 notes on raylib 4.2
------------------- -------------------
**New raylib release!** Nine months after latest raylib, here it is a new version. It was supposed to be just a small update but, actually, it's a huge update with lots of changes a improvements. It has been possible thanks to the many contributors that has helped with issues and improvements, it's the **update with more contributors to date** and that's amazing! **New raylib release!** Nine months after latest raylib, here is a new version. It was supposed to be just a small update but, actually, it's a huge update with lots of changes a improvements. It has been possible thanks to the many contributors that has helped with issues and improvements, it's the **update with more contributors to date** and that's amazing!
Some numbers to start with: Some numbers to start with:
@ -390,7 +390,7 @@ Highlights for `raylib 4.2`:
- **New file system API**: Current API has been redesigned to be more comprehensive and better aligned with raylib naming conventions, two new functions are provided `LoadDirectoryFiles()`/`LoadDirectoryFilesEx()` to load a `FilePathList` for provided path, supporting extension filtering and recursive directory scan. `LoadDroppedFiles()` has been renamed to better reflect its internal functionality. Now, all raylib functions that start with `Load*()` allocate memory internally and a equivalent `Unload*()` function is defined to take care of that memory internally when not required any more! - **New file system API**: Current API has been redesigned to be more comprehensive and better aligned with raylib naming conventions, two new functions are provided `LoadDirectoryFiles()`/`LoadDirectoryFilesEx()` to load a `FilePathList` for provided path, supporting extension filtering and recursive directory scan. `LoadDroppedFiles()` has been renamed to better reflect its internal functionality. Now, all raylib functions that start with `Load*()` allocate memory internally and a equivalent `Unload*()` function is defined to take care of that memory internally when not required any more!
- **New audio stream processors API** (_experimental_): Now real-time audio stream data processors can be added using callbacks to played Music. It allows users to create custom effects for audio like delays of low-pass-filtering (example provided). The new API uses a callback system and it's still _ highly experimental_, it differs from the usual level of complexity that provides raylib and it is intended for advance users. It could change in the future but, actually, `raudio` module is in the spotlight for future updates; [miniaudio](https://github.com/mackron/miniaudio) implements a new higher-level API that can be useful in the future for raylib. - **New audio stream processors API** (_experimental_): Now real-time audio stream data processors can be added using callbacks to played Music. It allows users to create custom effects for audio like delays of low-pass-filtering (example provided). The new API uses a callback system and it's still _ highly experimental_, it differs from the usual level of complexity that provides raylib and it is intended for advanced users. It could change in the future but, actually, `raudio` module is in the spotlight for future updates; [miniaudio](https://github.com/mackron/miniaudio) implements a new higher-level API that can be useful in the future for raylib.
As always, there are more improvements than the key features listed, make sure to check raylib [CHANGELOG](CHANGELOG) for the detailed list of changes; for this release a `WARNING` flag has been added to all the changes that could affect bindings or productivity code. **raylib keeps improving one more version** and a special focus on maintainability has been put on the library for the future. Specific/advance functionality will be provided through **raylib-extras** repos and raylib main repo devlelopment will be focused on what made raylib popular: being a simple and easy-to-use library to **enjoy videogames programming**. As always, there are more improvements than the key features listed, make sure to check raylib [CHANGELOG](CHANGELOG) for the detailed list of changes; for this release a `WARNING` flag has been added to all the changes that could affect bindings or productivity code. **raylib keeps improving one more version** and a special focus on maintainability has been put on the library for the future. Specific/advance functionality will be provided through **raylib-extras** repos and raylib main repo devlelopment will be focused on what made raylib popular: being a simple and easy-to-use library to **enjoy videogames programming**.
@ -399,7 +399,7 @@ As always, there are more improvements than the key features listed, make sure t
notes on raylib 4.5 notes on raylib 4.5
------------------- -------------------
It's been **7 months** since latest raylib release. As usual, **many parts of the library have been reviewed and improved** along those months. Many issues have been closed, staying under 10 open issues at the moment of this writting and also many PRs from contributors have been received, reviewed and merged into raylib library. Some new functions have been added and some others have been removed to improve library coherence and avoid moving too high level, giving the users the tools to implement advance functionality themselfs over raylib. Again, this is a big release with a considerable amount of changes and improvements. Here it is a small summary highlighting this new **rayib 4.5**. It's been **7 months** since latest raylib release. As usual, **many parts of the library have been reviewed and improved** along those months. Many issues have been closed, staying under 10 open issues at the moment of this writting and also many PRs from contributors have been received, reviewed and merged into raylib library. Some new functions have been added and some others have been removed to improve library coherence and avoid moving too high level, giving the users the tools to implement advance functionality themselfs over raylib. Again, this is a big release with a considerable amount of changes and improvements. Here is a small summary highlighting this new **rayib 4.5**.
Some numbers for this release: Some numbers for this release:
@ -413,7 +413,7 @@ Highlights for `raylib 4.5`:
- **`NEW` Improved ANGLE support on Desktop platforms**: Support for OpenGL ES 2.0 on Desktop platforms (Windows, Linux, macOS) has been reviewed by @wtnbgo GitHub user. Now raylib can be compiled on desktop for OpenGL ES 2.0 and linked against [`ANGLE`](https://github.com/google/angle). This _small_ addition open the door to building raylib for all **ANGLE supported backends: Direct3D 11, Vulkan and Metal**. Please note that this new feature is still experimental and requires further testing! - **`NEW` Improved ANGLE support on Desktop platforms**: Support for OpenGL ES 2.0 on Desktop platforms (Windows, Linux, macOS) has been reviewed by @wtnbgo GitHub user. Now raylib can be compiled on desktop for OpenGL ES 2.0 and linked against [`ANGLE`](https://github.com/google/angle). This _small_ addition open the door to building raylib for all **ANGLE supported backends: Direct3D 11, Vulkan and Metal**. Please note that this new feature is still experimental and requires further testing!
- **`NEW` Camera module**: A brand new implementation from scratch for `rcamera` module, contributed by @Crydsch GitHub user! **New camera system is simpler, more flexible, more granular and more extendable**. Specific camera math transformations (movement/rotation) have been moved to individual functions, exposing them to users if required. Global state has been removed from the module and standalone usage has been greatly improved; now `rcamera.h` single-file header-only library can be used externally, independently of raylib. A new `UpdateCameraPro()` function has been added to address input-dependency of `UpdateCamera()`, now advance users have **full control over camera inputs and movement/rotation speeds**! - **`NEW` Camera module**: A brand new implementation from scratch for `rcamera` module, contributed by @Crydsch GitHub user! **New camera system is simpler, more flexible, more granular and more extendable**. Specific camera math transformations (movement/rotation) have been moved to individual functions, exposing them to users if required. Global state has been removed from the module and standalone usage has been greatly improved; now `rcamera.h` single-file header-only library can be used externally, independently of raylib. A new `UpdateCameraPro()` function has been added to address input-dependency of `UpdateCamera()`, now advanced users have **full control over camera inputs and movement/rotation speeds**!
- **`NEW` Support for M3D models and M3D/GLTF animations**: 3d models animations support has been a limited aspect of raylib for long time, some versions ago IQM animations were supported but raylib 4.5 also adds support for the brand new [M3D file format](https://bztsrc.gitlab.io/model3d/), including animations and the long expected support for **GLTF animations**! The new M3D file format is **simple, portable, feature complete, extensible and open source**. It also provides a complete set of tools to export/visualize M3D models from/to Blender! Now raylib supports up to **3 model file-formats with animations**: `IQM`, `GLTF` and `M3D`. - **`NEW` Support for M3D models and M3D/GLTF animations**: 3d models animations support has been a limited aspect of raylib for long time, some versions ago IQM animations were supported but raylib 4.5 also adds support for the brand new [M3D file format](https://bztsrc.gitlab.io/model3d/), including animations and the long expected support for **GLTF animations**! The new M3D file format is **simple, portable, feature complete, extensible and open source**. It also provides a complete set of tools to export/visualize M3D models from/to Blender! Now raylib supports up to **3 model file-formats with animations**: `IQM`, `GLTF` and `M3D`.
@ -425,7 +425,7 @@ Highlights for `raylib 4.5`:
- **Reviewed `rshapes` module to minimize the rlgl dependency**: Now `rshapes` 2d shapes drawing functions **only depend on 6 low-level functions**: `rlBegin()`, `rlEnd()`, `rlVertex3f()`, `rlTexCoord2f()`, `rlNormal3f()`, `rlSetTexture()`. With only those pseudo-OpenGl 1.1 minimal functionality, everything can be drawn! This improvement converts `rshapes` module in a **self-contained, portable shapes-drawing library that can be used independently of raylib**, as far as entry points for those 6 functions are provided by the user. It even allows to be used for software rendering, with the proper backend! - **Reviewed `rshapes` module to minimize the rlgl dependency**: Now `rshapes` 2d shapes drawing functions **only depend on 6 low-level functions**: `rlBegin()`, `rlEnd()`, `rlVertex3f()`, `rlTexCoord2f()`, `rlNormal3f()`, `rlSetTexture()`. With only those pseudo-OpenGl 1.1 minimal functionality, everything can be drawn! This improvement converts `rshapes` module in a **self-contained, portable shapes-drawing library that can be used independently of raylib**, as far as entry points for those 6 functions are provided by the user. It even allows to be used for software rendering, with the proper backend!
- **Added data structures validation functions**: Multiple functions have been added by @RobLoach GitHub user to ease the validation of raylib data structures: `IsImageReady()`, `IsTextureReady()`, `IsSoundReady()`... Now users have a simple mechanism to **make sure data has been correctly loaded**, instead of checking internal structure values by themselfs. - **Added data structures validation functions**: Multiple functions have been added by @RobLoach GitHub user to ease the validation of raylib data structures: `IsImageReady()`, `IsTextureReady()`, `IsSoundReady()`... Now users have a simple mechanism to **make sure data has been correctly loaded**, instead of checking internal structure values by themselves.
As usual, those are only some highlights but there is much more! New image generators, new color transformation functionality, improved blending support for color/alpha, etc... Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes! Please, note that all breaking changes have been flagged with a `WARNING` in the CHANGELOG, specially useful for binding creators! As usual, those are only some highlights but there is much more! New image generators, new color transformation functionality, improved blending support for color/alpha, etc... Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes! Please, note that all breaking changes have been flagged with a `WARNING` in the CHANGELOG, specially useful for binding creators!
@ -436,7 +436,7 @@ Let's keep **enjoying games/tools/graphics programming!** :)
notes on raylib 5.0 notes on raylib 5.0
------------------- -------------------
It's been **7 months** since latest raylib release and **10 years** since raylib 1.0 was officially released... what an adventure! In the last 10 years raylib has improved a lot, new functions have been added, many new features and improvements implemented, up to **500 contributors** have helped to shape the library as it is today. `raylib 5.0` is the final result of all this incredible amount of work and dedication. Here it is the summary with the key features and additions of this NEW major version of raylib. It's been **7 months** since latest raylib release and **10 years** since raylib 1.0 was officially released... what an adventure! In the last 10 years raylib has improved a lot, new functions have been added, many new features and improvements implemented, up to **500 contributors** have helped to shape the library as it is today. `raylib 5.0` is the final result of all this incredible amount of work and dedication. Here is the summary with the key features and additions of this NEW major version of raylib.
Some numbers for this release: Some numbers for this release:
@ -448,9 +448,9 @@ Some numbers for this release:
Highlights for `raylib 5.0`: Highlights for `raylib 5.0`:
- **`rcore` module platform-split**: Probably the biggest raylib redesign in the last 10 years. raylib started as a library targeting 3 desktop platforms: `Windows`, `Linux` and `macOS` (thanks to `GLFW` underlying library) but with the years support for several new platforms has been added (`Android`, `Web`, `Rapsberry Pi`, `RPI native`...); lot of the platform code was shared so the logic was all together on `rcore.c` module, separated by compilation flags. This approach was very handy but also made it very difficult to support new platforms and specially painful for contributors not familiar with the module, navigating +8000 lines of code in a single file. A big redesign was really needed but the amount of work required was humungus and quite scary for a solo-developer like me, moreover considering that everything was working and the chances to break things were really high. Fortunately, some contributors were ready for the task (@ubkp, @michaelfiber, @Bigfoot71) and thanks to their initiative and super-hard work, the `rcore` [platform split](https://github.com/raysan5/raylib/blob/master/src/platforms) has been possible! This new raylib architecture greatly improves the platforms maintenance but also greatly simplifies the addition of new platforms. A [`platforms/rcore_template.c`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_template.c) file is provided with the required structure and functions to be filled for the addition of new platforms, actually it has been simplified to mostly filling some pre-defined functions: `InitPlatform()`, `ClosePlatform`, `PollInputEvents`... Undoubtely, **this redesign opens the doors to a new era for raylib**, letting the users to plug new platforms as desired. - **`rcore` module platform-split**: Probably the biggest raylib redesign in the last 10 years. raylib started as a library targeting 3 desktop platforms: `Windows`, `Linux` and `macOS` (thanks to `GLFW` underlying library) but with the years support for several new platforms has been added (`Android`, `Web`, `Rapsberry Pi`, `RPI native`...); lot of the platform code was shared so the logic was all together on `rcore.c` module, separated by compilation flags. This approach was very handy but also made it very difficult to support new platforms and specially painful for contributors not familiar with the module, navigating +8000 lines of code in a single file. A big redesign was really needed but the amount of work required was humungous and quite scary for a solo-developer like me, moreover considering that everything was working and the chances to break things were really high. Fortunately, some contributors were ready for the task (@ubkp, @michaelfiber, @Bigfoot71) and thanks to their initiative and super-hard work, the `rcore` [platform split](https://github.com/raysan5/raylib/blob/master/src/platforms) has been possible! This new raylib architecture greatly improves the platforms maintenance but also greatly simplifies the addition of new platforms. A [`platforms/rcore_template.c`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_template.c) file is provided with the required structure and functions to be filled for the addition of new platforms, actually it has been simplified to mostly filling some pre-defined functions: `InitPlatform()`, `ClosePlatform`, `PollInputEvents`... Undoubtedly, **this redesign opens the doors to a new era for raylib**, letting the users to plug new platforms as desired.
- **`NEW` Platform backend supported: SDL**: Thanks to the new `rcore` platform-split, the addition of new platforms/backends to raylib has been greatly simplified. As a proof of concept, [`SDL2`](https://libsdl.org/) platform backend has been added to raylib as an aternative for `GLFW` library for desktop builds: [`platforms/rcore_desktop_sdl`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_sdl.c). Lot of work has been put to provide exactly the same features as the other platforms and carefully test the new implementation. Now `SDL2` fans can use this new backend, just providing the required include libraries on compilation and linkage (not included in raylib, like `GLFW`). `SDL` backend support also **eases the process of supporting a wider range of platforms** that already support `SDL`. - **`NEW` Platform backend supported: SDL**: Thanks to the new `rcore` platform-split, the addition of new platforms/backends to raylib has been greatly simplified. As a proof of concept, [`SDL2`](https://libsdl.org/) platform backend has been added to raylib as an alternative for `GLFW` library for desktop builds: [`platforms/rcore_desktop_sdl`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_sdl.c). Lot of work has been put to provide exactly the same features as the other platforms and carefully test the new implementation. Now `SDL2` fans can use this new backend, just providing the required include libraries on compilation and linkage (not included in raylib, like `GLFW`). `SDL` backend support also **eases the process of supporting a wider range of platforms** that already support `SDL`.
- **`NEW` Platform backend supported: Nintendo Switch (closed source)**: The addition of the `SDL` backend was quite a challenge but to really verify the robustness and ease of the new platform plugin system, adding support for a console was a more demanding adventure. Surprisingly, only two days of work were required to add support for `Nintendo Switch` to raylib! Implementation result showed an outstanding level of simplicity, with a **self-contained module** (`rcore_swith.cpp`) supporting graphics and inputs. Unfortunately this module can not be open-sourced due to licensing restrictions. - **`NEW` Platform backend supported: Nintendo Switch (closed source)**: The addition of the `SDL` backend was quite a challenge but to really verify the robustness and ease of the new platform plugin system, adding support for a console was a more demanding adventure. Surprisingly, only two days of work were required to add support for `Nintendo Switch` to raylib! Implementation result showed an outstanding level of simplicity, with a **self-contained module** (`rcore_swith.cpp`) supporting graphics and inputs. Unfortunately this module can not be open-sourced due to licensing restrictions.
@ -468,6 +468,6 @@ As always, those are only some highlights of the new `raylib 5.0` but there is m
Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes! Make sure to check raylib [CHANGELOG]([CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG)) for a detailed list of changes!
Undoubtely, this is the **biggest raylib update in 10 years**. Many new features and improvements with a special focus on maintainabiliy and long-term sustainability. **Undoubtely, this is the raylib of the future**. Undoubtedly, this is the **biggest raylib update in 10 years**. Many new features and improvements with a special focus on maintainability and long-term sustainability. **Undoubtedly, this is the raylib of the future**.
**Enjoy programming!** :) **Enjoy programming!** :)

View File

@ -1,6 +1,6 @@
# raylib roadmap # raylib roadmap
Here it is a wishlist with features and ideas to improve the library. Note that features listed here are usually long term improvements or just describe a route to follow for the library. There are also some additional places to look for raylib improvements and ideas: Here is a wishlist with features and ideas to improve the library. Note that features listed here are usually long term improvements or just describe a route to follow for the library. There are also some additional places to look for raylib improvements and ideas:
- [GitHub Issues](https://github.com/raysan5/raylib/issues) has several open issues for possible improvements or bugs to fix. - [GitHub Issues](https://github.com/raysan5/raylib/issues) has several open issues for possible improvements or bugs to fix.
- [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve. - [raylib source code](https://github.com/raysan5/raylib/tree/master/src) has multiple *TODO* comments around code with pending things to review or improve.
@ -73,7 +73,7 @@ _Current version of raylib is complete and functional but there is always room f
**raylib 1.5** **raylib 1.5**
- [x] Support Oculus Rift CV1 and VR stereo rendering (simulator) - [x] Support Oculus Rift CV1 and VR stereo rendering (simulator)
- [x] Redesign Shaders/Textures system -> New Materials system - [x] Redesign Shaders/Textures system -> New Materials system
- [x] Support lighting: Omni, Directional and Spot lights - [x] Support lighting: Omni, Directional and Spotlights
- [x] Redesign physics module (physac) - [x] Redesign physics module (physac)
- [x] Chiptunes audio modules support - [x] Chiptunes audio modules support

View File

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

View File

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

View File

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

View File

@ -96,10 +96,9 @@ if (${PLATFORM} MATCHES "Android")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c)
elseif (${PLATFORM} MATCHES "Web") elseif (${PLATFORM} MATCHES "Web")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os")
# Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads # Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s WASM=1 -s ASYNCIFY -s ALLOW_MEMORY_GROWTH=1 --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
set(CMAKE_EXECUTABLE_SUFFIX ".html") set(CMAKE_EXECUTABLE_SUFFIX ".html")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
@ -113,6 +112,13 @@ elseif ("${PLATFORM}" STREQUAL "DRM")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
elseif (NOT SUPPORT_GESTURES_SYSTEM)
# Items requiring gestures system
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_mouse_painting.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_basic_screen_manager.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_input_gestures_web.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/core/core_input_gestures.c)
endif () endif ()
# The rlgl_standalone example only targets desktop, without shared libraries. # The rlgl_standalone example only targets desktop, without shared libraries.

View File

@ -202,5 +202,5 @@ Examples showing raylib misc functionality that does not fit in other categories
| 125 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) | | 125 | [raylib_opengl_interop](others/raylib_opengl_interop.c) | <img src="others/raylib_opengl_interop.png" alt="raylib_opengl_interop" width="80"> | ⭐️⭐️⭐️⭐️ | **4.0** | **4.0** | [Stephan Soller](https://github.com/arkanis) |
| 126 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) | | 126 | [embedded_files_loading](others/embedded_files_loading.c) | <img src="others/embedded_files_loading.png" alt="embedded_files_loading" width="80"> | ⭐️⭐️☆☆ | 3.5 | 3.5 | [Kristian Holmgren](https://github.com/defutura) |
As always contributions are welcome, feel free to send new examples! Here it is an [examples template](examples_template.c) to start with! As always contributions are welcome, feel free to send new examples! Here is an [examples template](examples_template.c) to start with!

View File

@ -97,7 +97,7 @@ int main(void)
DrawRectangle(199, 199, 402, 34, LIGHTGRAY); DrawRectangle(199, 199, 402, 34, LIGHTGRAY);
for (int i = 0; i < 400; i++) for (int i = 0; i < 400; i++)
{ {
DrawLine(201 + i, 232 - averageVolume[i] * 32, 201 + i, 232, MAROON); DrawLine(201 + i, 232 - (int)averageVolume[i] * 32, 201 + i, 232, MAROON);
} }
DrawRectangleLines(199, 199, 402, 34, GRAY); DrawRectangleLines(199, 199, 402, 34, GRAY);

View File

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

View File

@ -133,10 +133,10 @@ int main(void)
for (int i = 0; i < envItemsLength; i++) DrawRectangleRec(envItems[i].rect, envItems[i].color); for (int i = 0; i < envItemsLength; i++) DrawRectangleRec(envItems[i].rect, envItems[i].color);
Rectangle playerRect = { player.position.x - 20, player.position.y - 40, 40, 40 }; Rectangle playerRect = { player.position.x - 20, player.position.y - 40, 40.0f, 40.0f };
DrawRectangleRec(playerRect, RED); DrawRectangleRec(playerRect, RED);
DrawCircle(player.position.x, player.position.y, 5, GOLD); DrawCircleV(player.position, 5.0f, GOLD);
EndMode2D(); EndMode2D();

View File

@ -2,7 +2,7 @@
* *
* raylib [core] example - custom frame control * raylib [core] example - custom frame control
* *
* NOTE: WARNING: This is an example for advance users willing to have full control over * NOTE: WARNING: This is an example for advanced users willing to have full control over
* the frame processes. By default, EndDrawing() calls the following processes: * the frame processes. By default, EndDrawing() calls the following processes:
* 1. Draw remaining batch data: rlDrawRenderBatchActive() * 1. Draw remaining batch data: rlDrawRenderBatchActive()
* 2. SwapScreenBuffer() * 2. SwapScreenBuffer()

View File

@ -22,7 +22,7 @@
// NOTE: Gamepad name ID depends on drivers and OS // NOTE: Gamepad name ID depends on drivers and OS
#define XBOX360_LEGACY_NAME_ID "Xbox Controller" #define XBOX360_LEGACY_NAME_ID "Xbox Controller"
#define XBOX360_NAME_ID "Xbox 360 Controller" #define XBOX360_NAME_ID "Xbox 360 Controller"
#define PS3_NAME_ID "PLAYSTATION(R)3 Controller" #define PS3_NAME_ID "Sony PLAYSTATION(R)3 Controller"
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
@ -67,7 +67,7 @@ int main(void)
{ {
DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK); DrawText(TextFormat("GP%d: %s", gamepad, GetGamepadName(gamepad)), 10, 10, 10, BLACK);
if (true) if (TextIsEqual(GetGamepadName(gamepad), XBOX360_LEGACY_NAME_ID) || TextIsEqual(GetGamepadName(gamepad), XBOX360_NAME_ID))
{ {
DrawTexture(texXboxPad, 0, 0, DARKGRAY); DrawTexture(texXboxPad, 0, 0, DARKGRAY);

View File

@ -36,7 +36,7 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
boxPositionY -= (GetMouseWheelMove()*scrollSpeed); boxPositionY -= (int)(GetMouseWheelMove()*scrollSpeed);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw

View File

@ -41,7 +41,7 @@ int main(void) {
int rectCount = 20; int rectCount = 20;
float rectSize = (float)screenWidth/rectCount; float rectSize = (float)screenWidth/rectCount;
ColorRect* rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight); ColorRect* rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
SetTargetFPS(60); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -62,7 +62,7 @@ int main(void) {
rectCount++; rectCount++;
rectSize = (float)screenWidth/rectCount; rectSize = (float)screenWidth/rectCount;
free(rectangles); free(rectangles);
rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight); rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
} }
if(IsKeyPressed(KEY_DOWN)) if(IsKeyPressed(KEY_DOWN))
@ -71,7 +71,7 @@ int main(void) {
rectCount--; rectCount--;
rectSize = (float)screenWidth/rectCount; rectSize = (float)screenWidth/rectCount;
free(rectangles); free(rectangles);
rectangles = GenerateRandomColorRectSequence(rectCount, rectSize, screenWidth, 0.75f * screenHeight); rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f * screenHeight);
} }
} }
@ -121,17 +121,17 @@ static Color GenerateRandomColor()
} }
static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight){ static ColorRect* GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight){
int *seq = LoadRandomSequence(rectCount, 0, rectCount-1); int *seq = LoadRandomSequence((unsigned int)rectCount, 0, (unsigned int)rectCount-1);
ColorRect* rectangles = (ColorRect *)malloc(rectCount*sizeof(ColorRect)); ColorRect* rectangles = (ColorRect *)malloc((int)rectCount*sizeof(ColorRect));
float rectSeqWidth = rectCount * rectWidth; float rectSeqWidth = rectCount * rectWidth;
int startX = (screenWidth - rectSeqWidth) * 0.5f; float startX = (screenWidth - rectSeqWidth) * 0.5f;
for(int x=0;x<rectCount;x++){ for(int x=0;x<rectCount;x++){
int rectHeight = Remap(seq[x], 0, rectCount-1, 0, screenHeight); int rectHeight = (int)Remap((float)seq[x], 0, rectCount-1, 0, screenHeight);
rectangles[x].c = GenerateRandomColor(); rectangles[x].c = GenerateRandomColor();
rectangles[x].r = CLITERAL(Rectangle){ rectangles[x].r = CLITERAL(Rectangle){
startX + x * rectWidth, screenHeight - rectHeight, rectWidth, rectHeight startX + x * rectWidth, screenHeight - rectHeight, rectWidth, (float)rectHeight
}; };
} }
UnloadRandomSequence(seq); UnloadRandomSequence(seq);

View File

@ -69,18 +69,18 @@ int main(void)
rotation += 60.0f*GetFrameTime(); // Rotate the rectangles, 60 degrees per second rotation += 60.0f*GetFrameTime(); // Rotate the rectangles, 60 degrees per second
// Make the camera move to demonstrate the effect // Make the camera move to demonstrate the effect
cameraX = (sinf(GetTime())*50.0f) - 10.0f; cameraX = (sinf((float)GetTime())*50.0f) - 10.0f;
cameraY = cosf(GetTime())*30.0f; cameraY = cosf((float)GetTime())*30.0f;
// Set the camera's target to the values computed above // Set the camera's target to the values computed above
screenSpaceCamera.target = (Vector2){ cameraX, cameraY }; screenSpaceCamera.target = (Vector2){ cameraX, cameraY };
// Round worldSpace coordinates, keep decimals into screenSpace coordinates // Round worldSpace coordinates, keep decimals into screenSpace coordinates
worldSpaceCamera.target.x = (int)screenSpaceCamera.target.x; worldSpaceCamera.target.x = truncf(screenSpaceCamera.target.x);
screenSpaceCamera.target.x -= worldSpaceCamera.target.x; screenSpaceCamera.target.x -= worldSpaceCamera.target.x;
screenSpaceCamera.target.x *= virtualRatio; screenSpaceCamera.target.x *= virtualRatio;
worldSpaceCamera.target.y = (int)screenSpaceCamera.target.y; worldSpaceCamera.target.y = truncf(screenSpaceCamera.target.y);
screenSpaceCamera.target.y -= worldSpaceCamera.target.y; screenSpaceCamera.target.y -= worldSpaceCamera.target.y;
screenSpaceCamera.target.y *= virtualRatio; screenSpaceCamera.target.y *= virtualRatio;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -177,7 +177,7 @@ int LoadStorageValue(unsigned int position)
if (fileData != NULL) if (fileData != NULL)
{ {
if (dataSize < (position*4)) TraceLog(LOG_WARNING, "FILEIO: [%s] Failed to find storage position: %i", STORAGE_DATA_FILE, position); if (dataSize < ((int)(position*4))) TraceLog(LOG_WARNING, "FILEIO: [%s] Failed to find storage position: %i", STORAGE_DATA_FILE, position);
else else
{ {
int *dataPtr = (int *)fileData; int *dataPtr = (int *)fileData;

View File

@ -67,7 +67,7 @@ int main(void)
DrawCubeTexture(texture, (Vector3){ -2.0f, 2.0f, 0.0f }, 2.0f, 4.0f, 2.0f, WHITE); DrawCubeTexture(texture, (Vector3){ -2.0f, 2.0f, 0.0f }, 2.0f, 4.0f, 2.0f, WHITE);
// Draw cube with an applied texture, but only a defined rectangle piece of the texture // Draw cube with an applied texture, but only a defined rectangle piece of the texture
DrawCubeTextureRec(texture, (Rectangle){ 0, texture.height/2, texture.width/2, texture.height/2 }, DrawCubeTextureRec(texture, (Rectangle){ 0.0f, texture.height/2.0f, texture.width/2.0f, texture.height/2.0f },
(Vector3){ 2.0f, 1.0f, 0.0f }, 2.0f, 2.0f, 2.0f, WHITE); (Vector3){ 2.0f, 1.0f, 0.0f }, 2.0f, 2.0f, 2.0f, WHITE);
DrawGrid(10, 1.0f); // Draw a grid DrawGrid(10, 1.0f); // Draw a grid

View File

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

View File

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

View File

@ -281,7 +281,7 @@ int main(void)
.id = gBuffer.positionTexture, .id = gBuffer.positionTexture,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
DrawText("POSITION TEXTURE", 10, screenHeight - 30, 20, DARKGREEN); DrawText("POSITION TEXTURE", 10, screenHeight - 30, 20, DARKGREEN);
} break; } break;
@ -291,7 +291,7 @@ int main(void)
.id = gBuffer.normalTexture, .id = gBuffer.normalTexture,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
DrawText("NORMAL TEXTURE", 10, screenHeight - 30, 20, DARKGREEN); DrawText("NORMAL TEXTURE", 10, screenHeight - 30, 20, DARKGREEN);
} break; } break;
@ -301,7 +301,7 @@ int main(void)
.id = gBuffer.albedoSpecTexture, .id = gBuffer.albedoSpecTexture,
.width = screenWidth, .width = screenWidth,
.height = screenHeight, .height = screenHeight,
}, (Rectangle) { 0, 0, screenWidth, -screenHeight }, Vector2Zero(), RAYWHITE); }, (Rectangle) { 0, 0, (float)screenWidth, (float)-screenHeight }, Vector2Zero(), RAYWHITE);
DrawText("ALBEDO TEXTURE", 10, screenHeight - 30, 20, DARKGREEN); DrawText("ALBEDO TEXTURE", 10, screenHeight - 30, 20, DARKGREEN);
} break; } break;

View File

@ -69,8 +69,8 @@ int main(void)
DrawLineBezier(startPoint, endPoint, 4.0f, BLUE); DrawLineBezier(startPoint, endPoint, 4.0f, BLUE);
// Draw start-end spline circles with some details // Draw start-end spline circles with some details
DrawCircleV(startPoint, CheckCollisionPointCircle(mouse, startPoint, 10.0f)? 14 : 8, moveStartPoint? RED : BLUE); DrawCircleV(startPoint, CheckCollisionPointCircle(mouse, startPoint, 10.0f)? 14.0f : 8.0f, moveStartPoint? RED : BLUE);
DrawCircleV(endPoint, CheckCollisionPointCircle(mouse, endPoint, 10.0f)? 14 : 8, moveEndPoint? RED : BLUE); DrawCircleV(endPoint, CheckCollisionPointCircle(mouse, endPoint, 10.0f)? 14.0f : 8.0f, moveEndPoint? RED : BLUE);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

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

View File

@ -4499,6 +4499,17 @@
} }
] ]
}, },
{
"name": "IsFileNameValid",
"description": "Check if fileName is valid for the platform/OS",
"returnType": "bool",
"params": [
{
"type": "const char *",
"name": "fileName"
}
]
},
{ {
"name": "LoadDirectoryFiles", "name": "LoadDirectoryFiles",
"description": "Load directory filepaths", "description": "Load directory filepaths",
@ -5334,7 +5345,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6011,7 +6022,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6030,7 +6041,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6134,7 +6145,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6157,7 +6168,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6180,7 +6191,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6203,7 +6214,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6226,7 +6237,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6633,7 +6644,7 @@
"name": "point" "name": "point"
}, },
{ {
"type": "Vector2 *", "type": "const Vector2 *",
"name": "points" "name": "points"
}, },
{ {
@ -6692,6 +6703,29 @@
} }
] ]
}, },
{
"name": "CheckCollisionCircleLine",
"description": "Check if circle collides with a line created betweeen two points [p1] and [p2]",
"returnType": "bool",
"params": [
{
"type": "Vector2",
"name": "center"
},
{
"type": "float",
"name": "radius"
},
{
"type": "Vector2",
"name": "p1"
},
{
"type": "Vector2",
"name": "p2"
}
]
},
{ {
"name": "GetCollisionRec", "name": "GetCollisionRec",
"description": "Get collision rectangle for two rectangles collision", "description": "Get collision rectangle for two rectangles collision",
@ -7317,7 +7351,7 @@
}, },
{ {
"name": "ImageKernelConvolution", "name": "ImageKernelConvolution",
"description": "Apply Custom Square image convolution kernel", "description": "Apply custom square convolution kernel to image",
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
@ -7325,7 +7359,7 @@
"name": "image" "name": "image"
}, },
{ {
"type": "float*", "type": "const float *",
"name": "kernel" "name": "kernel"
}, },
{ {
@ -7783,6 +7817,33 @@
} }
] ]
}, },
{
"name": "ImageDrawLineEx",
"description": "Draw a line defining thickness within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2",
"name": "start"
},
{
"type": "Vector2",
"name": "end"
},
{
"type": "int",
"name": "thick"
},
{
"type": "Color",
"name": "color"
}
]
},
{ {
"name": "ImageDrawCircle", "name": "ImageDrawCircle",
"description": "Draw a filled circle within an image", "description": "Draw a filled circle within an image",
@ -7979,6 +8040,141 @@
} }
] ]
}, },
{
"name": "ImageDrawTriangle",
"description": "Draw triangle within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2",
"name": "v1"
},
{
"type": "Vector2",
"name": "v2"
},
{
"type": "Vector2",
"name": "v3"
},
{
"type": "Color",
"name": "color"
}
]
},
{
"name": "ImageDrawTriangleEx",
"description": "Draw triangle with interpolated colors within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2",
"name": "v1"
},
{
"type": "Vector2",
"name": "v2"
},
{
"type": "Vector2",
"name": "v3"
},
{
"type": "Color",
"name": "c1"
},
{
"type": "Color",
"name": "c2"
},
{
"type": "Color",
"name": "c3"
}
]
},
{
"name": "ImageDrawTriangleLines",
"description": "Draw triangle outline within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2",
"name": "v1"
},
{
"type": "Vector2",
"name": "v2"
},
{
"type": "Vector2",
"name": "v3"
},
{
"type": "Color",
"name": "color"
}
]
},
{
"name": "ImageDrawTriangleFan",
"description": "Draw a triangle fan defined by points within an image (first vertex is the center)",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2 *",
"name": "points"
},
{
"type": "int",
"name": "pointCount"
},
{
"type": "Color",
"name": "color"
}
]
},
{
"name": "ImageDrawTriangleStrip",
"description": "Draw a triangle strip defined by points within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2 *",
"name": "points"
},
{
"type": "int",
"name": "pointCount"
},
{
"type": "Color",
"name": "color"
}
]
},
{ {
"name": "ImageDraw", "name": "ImageDraw",
"description": "Draw a source image within a destination image (tint applied to source)", "description": "Draw a source image within a destination image (tint applied to source)",
@ -9445,6 +9641,28 @@
} }
] ]
}, },
{
"name": "TextToSnake",
"description": "Get Snake case notation version of provided string",
"returnType": "const char *",
"params": [
{
"type": "const char *",
"name": "text"
}
]
},
{
"name": "TextToCamel",
"description": "Get Camel case notation version of provided string",
"returnType": "const char *",
"params": [
{
"type": "const char *",
"name": "text"
}
]
},
{ {
"name": "TextToInteger", "name": "TextToInteger",
"description": "Get integer value from text (negative values not supported)", "description": "Get integer value from text (negative values not supported)",
@ -9557,7 +9775,7 @@
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
"type": "Vector3 *", "type": "const Vector3 *",
"name": "points" "name": "points"
}, },
{ {

View File

@ -4058,6 +4058,14 @@ return {
{type = "const char *", name = "path"} {type = "const char *", name = "path"}
} }
}, },
{
name = "IsFileNameValid",
description = "Check if fileName is valid for the platform/OS",
returnType = "bool",
params = {
{type = "const char *", name = "fileName"}
}
},
{ {
name = "LoadDirectoryFiles", name = "LoadDirectoryFiles",
description = "Load directory filepaths", description = "Load directory filepaths",
@ -4628,7 +4636,7 @@ return {
description = "Draw lines sequence (using gl lines)", description = "Draw lines sequence (using gl lines)",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
@ -4939,7 +4947,7 @@ return {
description = "Draw a triangle fan defined by points (first vertex is the center)", description = "Draw a triangle fan defined by points (first vertex is the center)",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
@ -4949,7 +4957,7 @@ return {
description = "Draw a triangle strip defined by points", description = "Draw a triangle strip defined by points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
@ -4996,7 +5004,7 @@ return {
description = "Draw spline: Linear, minimum 2 points", description = "Draw spline: Linear, minimum 2 points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5007,7 +5015,7 @@ return {
description = "Draw spline: B-Spline, minimum 4 points", description = "Draw spline: B-Spline, minimum 4 points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5018,7 +5026,7 @@ return {
description = "Draw spline: Catmull-Rom, minimum 4 points", description = "Draw spline: Catmull-Rom, minimum 4 points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5029,7 +5037,7 @@ return {
description = "Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]", description = "Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5040,7 +5048,7 @@ return {
description = "Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]", description = "Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "float", name = "thick"}, {type = "float", name = "thick"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
@ -5231,7 +5239,7 @@ return {
returnType = "bool", returnType = "bool",
params = { params = {
{type = "Vector2", name = "point"}, {type = "Vector2", name = "point"},
{type = "Vector2 *", name = "points"}, {type = "const Vector2 *", name = "points"},
{type = "int", name = "pointCount"} {type = "int", name = "pointCount"}
} }
}, },
@ -5258,6 +5266,17 @@ return {
{type = "int", name = "threshold"} {type = "int", name = "threshold"}
} }
}, },
{
name = "CheckCollisionCircleLine",
description = "Check if circle collides with a line created betweeen two points [p1] and [p2]",
returnType = "bool",
params = {
{type = "Vector2", name = "center"},
{type = "float", name = "radius"},
{type = "Vector2", name = "p1"},
{type = "Vector2", name = "p2"}
}
},
{ {
name = "GetCollisionRec", name = "GetCollisionRec",
description = "Get collision rectangle for two rectangles collision", description = "Get collision rectangle for two rectangles collision",
@ -5598,11 +5617,11 @@ return {
}, },
{ {
name = "ImageKernelConvolution", name = "ImageKernelConvolution",
description = "Apply Custom Square image convolution kernel", description = "Apply custom square convolution kernel to image",
returnType = "void", returnType = "void",
params = { params = {
{type = "Image *", name = "image"}, {type = "Image *", name = "image"},
{type = "float*", name = "kernel"}, {type = "const float *", name = "kernel"},
{type = "int", name = "kernelSize"} {type = "int", name = "kernelSize"}
} }
}, },
@ -5860,6 +5879,18 @@ return {
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
}, },
{
name = "ImageDrawLineEx",
description = "Draw a line defining thickness within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2", name = "start"},
{type = "Vector2", name = "end"},
{type = "int", name = "thick"},
{type = "Color", name = "color"}
}
},
{ {
name = "ImageDrawCircle", name = "ImageDrawCircle",
description = "Draw a filled circle within an image", description = "Draw a filled circle within an image",
@ -5951,6 +5982,66 @@ return {
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }
}, },
{
name = "ImageDrawTriangle",
description = "Draw triangle within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2", name = "v1"},
{type = "Vector2", name = "v2"},
{type = "Vector2", name = "v3"},
{type = "Color", name = "color"}
}
},
{
name = "ImageDrawTriangleEx",
description = "Draw triangle with interpolated colors within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2", name = "v1"},
{type = "Vector2", name = "v2"},
{type = "Vector2", name = "v3"},
{type = "Color", name = "c1"},
{type = "Color", name = "c2"},
{type = "Color", name = "c3"}
}
},
{
name = "ImageDrawTriangleLines",
description = "Draw triangle outline within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2", name = "v1"},
{type = "Vector2", name = "v2"},
{type = "Vector2", name = "v3"},
{type = "Color", name = "color"}
}
},
{
name = "ImageDrawTriangleFan",
description = "Draw a triangle fan defined by points within an image (first vertex is the center)",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2 *", name = "points"},
{type = "int", name = "pointCount"},
{type = "Color", name = "color"}
}
},
{
name = "ImageDrawTriangleStrip",
description = "Draw a triangle strip defined by points within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2 *", name = "points"},
{type = "int", name = "pointCount"},
{type = "Color", name = "color"}
}
},
{ {
name = "ImageDraw", name = "ImageDraw",
description = "Draw a source image within a destination image (tint applied to source)", description = "Draw a source image within a destination image (tint applied to source)",
@ -6757,6 +6848,22 @@ return {
{type = "const char *", name = "text"} {type = "const char *", name = "text"}
} }
}, },
{
name = "TextToSnake",
description = "Get Snake case notation version of provided string",
returnType = "const char *",
params = {
{type = "const char *", name = "text"}
}
},
{
name = "TextToCamel",
description = "Get Camel case notation version of provided string",
returnType = "const char *",
params = {
{type = "const char *", name = "text"}
}
},
{ {
name = "TextToInteger", name = "TextToInteger",
description = "Get integer value from text (negative values not supported)", description = "Get integer value from text (negative values not supported)",
@ -6820,7 +6927,7 @@ return {
description = "Draw a triangle strip defined by points", description = "Draw a triangle strip defined by points",
returnType = "void", returnType = "void",
params = { params = {
{type = "Vector3 *", name = "points"}, {type = "const Vector3 *", name = "points"},
{type = "int", name = "pointCount"}, {type = "int", name = "pointCount"},
{type = "Color", name = "color"} {type = "Color", name = "color"}
} }

File diff suppressed because it is too large Load Diff

View File

@ -670,7 +670,7 @@
<Param type="unsigned int" name="frames" desc="" /> <Param type="unsigned int" name="frames" desc="" />
</Callback> </Callback>
</Callbacks> </Callbacks>
<Functions count="562"> <Functions count="572">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context"> <Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" /> <Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" /> <Param type="int" name="height" desc="" />
@ -1075,6 +1075,9 @@
<Function name="IsPathFile" retType="bool" paramCount="1" desc="Check if a given path is a file or a directory"> <Function name="IsPathFile" retType="bool" paramCount="1" desc="Check if a given path is a file or a directory">
<Param type="const char *" name="path" desc="" /> <Param type="const char *" name="path" desc="" />
</Function> </Function>
<Function name="IsFileNameValid" retType="bool" paramCount="1" desc="Check if fileName is valid for the platform/OS">
<Param type="const char *" name="fileName" desc="" />
</Function>
<Function name="LoadDirectoryFiles" retType="FilePathList" paramCount="1" desc="Load directory filepaths"> <Function name="LoadDirectoryFiles" retType="FilePathList" paramCount="1" desc="Load directory filepaths">
<Param type="const char *" name="dirPath" desc="" /> <Param type="const char *" name="dirPath" desc="" />
</Function> </Function>
@ -1314,7 +1317,7 @@
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawLineStrip" retType="void" paramCount="3" desc="Draw lines sequence (using gl lines)"> <Function name="DrawLineStrip" retType="void" paramCount="3" desc="Draw lines sequence (using gl lines)">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
@ -1490,12 +1493,12 @@
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawTriangleFan" retType="void" paramCount="3" desc="Draw a triangle fan defined by points (first vertex is the center)"> <Function name="DrawTriangleFan" retType="void" paramCount="3" desc="Draw a triangle fan defined by points (first vertex is the center)">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawTriangleStrip" retType="void" paramCount="3" desc="Draw a triangle strip defined by points"> <Function name="DrawTriangleStrip" retType="void" paramCount="3" desc="Draw a triangle strip defined by points">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
@ -1522,31 +1525,31 @@
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineLinear" retType="void" paramCount="4" desc="Draw spline: Linear, minimum 2 points"> <Function name="DrawSplineLinear" retType="void" paramCount="4" desc="Draw spline: Linear, minimum 2 points">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineBasis" retType="void" paramCount="4" desc="Draw spline: B-Spline, minimum 4 points"> <Function name="DrawSplineBasis" retType="void" paramCount="4" desc="Draw spline: B-Spline, minimum 4 points">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineCatmullRom" retType="void" paramCount="4" desc="Draw spline: Catmull-Rom, minimum 4 points"> <Function name="DrawSplineCatmullRom" retType="void" paramCount="4" desc="Draw spline: Catmull-Rom, minimum 4 points">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineBezierQuadratic" retType="void" paramCount="4" desc="Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]"> <Function name="DrawSplineBezierQuadratic" retType="void" paramCount="4" desc="Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawSplineBezierCubic" retType="void" paramCount="4" desc="Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]"> <Function name="DrawSplineBezierCubic" retType="void" paramCount="4" desc="Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]">
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="float" name="thick" desc="" /> <Param type="float" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
@ -1652,7 +1655,7 @@
</Function> </Function>
<Function name="CheckCollisionPointPoly" retType="bool" paramCount="3" desc="Check if point is within a polygon described by array of vertices"> <Function name="CheckCollisionPointPoly" retType="bool" paramCount="3" desc="Check if point is within a polygon described by array of vertices">
<Param type="Vector2" name="point" desc="" /> <Param type="Vector2" name="point" desc="" />
<Param type="Vector2 *" name="points" desc="" /> <Param type="const Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
</Function> </Function>
<Function name="CheckCollisionLines" retType="bool" paramCount="5" desc="Check the collision between two lines defined by two points each, returns collision point by reference"> <Function name="CheckCollisionLines" retType="bool" paramCount="5" desc="Check the collision between two lines defined by two points each, returns collision point by reference">
@ -1668,6 +1671,12 @@
<Param type="Vector2" name="p2" desc="" /> <Param type="Vector2" name="p2" desc="" />
<Param type="int" name="threshold" desc="" /> <Param type="int" name="threshold" desc="" />
</Function> </Function>
<Function name="CheckCollisionCircleLine" retType="bool" paramCount="4" desc="Check if circle collides with a line created betweeen two points [p1] and [p2]">
<Param type="Vector2" name="center" desc="" />
<Param type="float" name="radius" desc="" />
<Param type="Vector2" name="p1" desc="" />
<Param type="Vector2" name="p2" desc="" />
</Function>
<Function name="GetCollisionRec" retType="Rectangle" paramCount="2" desc="Get collision rectangle for two rectangles collision"> <Function name="GetCollisionRec" retType="Rectangle" paramCount="2" desc="Get collision rectangle for two rectangles collision">
<Param type="Rectangle" name="rec1" desc="" /> <Param type="Rectangle" name="rec1" desc="" />
<Param type="Rectangle" name="rec2" desc="" /> <Param type="Rectangle" name="rec2" desc="" />
@ -1833,9 +1842,9 @@
<Param type="Image *" name="image" desc="" /> <Param type="Image *" name="image" desc="" />
<Param type="int" name="blurSize" desc="" /> <Param type="int" name="blurSize" desc="" />
</Function> </Function>
<Function name="ImageKernelConvolution" retType="void" paramCount="3" desc="Apply Custom Square image convolution kernel"> <Function name="ImageKernelConvolution" retType="void" paramCount="3" desc="Apply custom square convolution kernel to image">
<Param type="Image *" name="image" desc="" /> <Param type="Image *" name="image" desc="" />
<Param type="float*" name="kernel" desc="" /> <Param type="const float *" name="kernel" desc="" />
<Param type="int" name="kernelSize" desc="" /> <Param type="int" name="kernelSize" desc="" />
</Function> </Function>
<Function name="ImageResize" retType="void" paramCount="3" desc="Resize image (Bicubic scaling algorithm)"> <Function name="ImageResize" retType="void" paramCount="3" desc="Resize image (Bicubic scaling algorithm)">
@ -1957,6 +1966,13 @@
<Param type="Vector2" name="end" desc="" /> <Param type="Vector2" name="end" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="ImageDrawLineEx" retType="void" paramCount="5" desc="Draw a line defining thickness within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="start" desc="" />
<Param type="Vector2" name="end" desc="" />
<Param type="int" name="thick" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawCircle" retType="void" paramCount="5" desc="Draw a filled circle within an image"> <Function name="ImageDrawCircle" retType="void" paramCount="5" desc="Draw a filled circle within an image">
<Param type="Image *" name="dst" desc="" /> <Param type="Image *" name="dst" desc="" />
<Param type="int" name="centerX" desc="" /> <Param type="int" name="centerX" desc="" />
@ -2008,6 +2024,41 @@
<Param type="int" name="thick" desc="" /> <Param type="int" name="thick" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="ImageDrawTriangle" retType="void" paramCount="5" desc="Draw triangle within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="v1" desc="" />
<Param type="Vector2" name="v2" desc="" />
<Param type="Vector2" name="v3" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawTriangleEx" retType="void" paramCount="7" desc="Draw triangle with interpolated colors within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="v1" desc="" />
<Param type="Vector2" name="v2" desc="" />
<Param type="Vector2" name="v3" desc="" />
<Param type="Color" name="c1" desc="" />
<Param type="Color" name="c2" desc="" />
<Param type="Color" name="c3" desc="" />
</Function>
<Function name="ImageDrawTriangleLines" retType="void" paramCount="5" desc="Draw triangle outline within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="v1" desc="" />
<Param type="Vector2" name="v2" desc="" />
<Param type="Vector2" name="v3" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawTriangleFan" retType="void" paramCount="4" desc="Draw a triangle fan defined by points within an image (first vertex is the center)">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawTriangleStrip" retType="void" paramCount="4" desc="Draw a triangle strip defined by points within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDraw" retType="void" paramCount="5" desc="Draw a source image within a destination image (tint applied to source)"> <Function name="ImageDraw" retType="void" paramCount="5" desc="Draw a source image within a destination image (tint applied to source)">
<Param type="Image *" name="dst" desc="" /> <Param type="Image *" name="dst" desc="" />
<Param type="Image" name="src" desc="" /> <Param type="Image" name="src" desc="" />
@ -2396,6 +2447,12 @@
<Function name="TextToPascal" retType="const char *" paramCount="1" desc="Get Pascal case notation version of provided string"> <Function name="TextToPascal" retType="const char *" paramCount="1" desc="Get Pascal case notation version of provided string">
<Param type="const char *" name="text" desc="" /> <Param type="const char *" name="text" desc="" />
</Function> </Function>
<Function name="TextToSnake" retType="const char *" paramCount="1" desc="Get Snake case notation version of provided string">
<Param type="const char *" name="text" desc="" />
</Function>
<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 (negative values not supported)">
<Param type="const char *" name="text" desc="" /> <Param type="const char *" name="text" desc="" />
</Function> </Function>
@ -2425,7 +2482,7 @@
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="DrawTriangleStrip3D" retType="void" paramCount="3" desc="Draw a triangle strip defined by points"> <Function name="DrawTriangleStrip3D" retType="void" paramCount="3" desc="Draw a triangle strip defined by points">
<Param type="Vector3 *" name="points" desc="" /> <Param type="const Vector3 *" name="points" desc="" />
<Param type="int" name="pointCount" desc="" /> <Param type="int" name="pointCount" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>

View File

@ -202,9 +202,12 @@ int main(int argc, char* argv[])
{ {
if (argc > 1) ProcessCommandLine(argc, argv); if (argc > 1) ProcessCommandLine(argc, argv);
if (inFileName[0] == '\0') MemoryCopy(inFileName, "../src/raylib.h\0", 16); const char *raylibhPath = "../src/raylib.h\0";
if (outFileName[0] == '\0') MemoryCopy(outFileName, "raylib_api.txt\0", 15); const char *raylibapiPath = "raylib_api.txt\0";
if (apiDefine[0] == '\0') MemoryCopy(apiDefine, "RLAPI\0", 6); const char *rlapiPath = "RLAPI\0";
if (inFileName[0] == '\0') MemoryCopy(inFileName, raylibhPath, TextLength(raylibhPath) + 1);
if (outFileName[0] == '\0') MemoryCopy(outFileName, raylibapiPath, TextLength(raylibapiPath) + 1);
if (apiDefine[0] == '\0') MemoryCopy(apiDefine, rlapiPath, TextLength(rlapiPath) + 1);
int length = 0; int length = 0;
char *buffer = LoadFileText(inFileName, &length); char *buffer = LoadFileText(inFileName, &length);
@ -1097,7 +1100,7 @@ static void ShowCommandLineInfo(void)
printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n"); printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n");
printf(" -f, --format <type> : Define output format for parser data.\n"); printf(" -f, --format <type> : Define output format for parser data.\n");
printf(" Supported types: DEFAULT, JSON, XML, LUA, CODE\n\n"); printf(" Supported types: DEFAULT, JSON, XML, LUA, CODE\n\n");
printf(" -d, --define <DEF> : Define functions specifiers (i.e. RLAPI for raylib.h, RMDEF for raymath.h, etc.)\n"); printf(" -d, --define <DEF> : Define functions specifiers (i.e. RLAPI for raylib.h, RMAPI for raymath.h, etc.)\n");
printf(" NOTE: If no specifier defined, defaults to: RLAPI\n\n"); printf(" NOTE: If no specifier defined, defaults to: RLAPI\n\n");
printf(" -t, --truncate <after> : Define string to truncate input after (i.e. \"RLGL IMPLEMENTATION\" for rlgl.h)\n"); printf(" -t, --truncate <after> : Define string to truncate input after (i.e. \"RLGL IMPLEMENTATION\" for rlgl.h)\n");
printf(" NOTE: If not specified, the full input file is parsed.\n\n"); printf(" NOTE: If not specified, the full input file is parsed.\n\n");
@ -1107,7 +1110,7 @@ static void ShowCommandLineInfo(void)
printf(" Process <raylib.h> to generate <api.json>\n\n"); printf(" Process <raylib.h> to generate <api.json>\n\n");
printf(" > raylib_parser --output raylib_data.info --format XML\n"); printf(" > raylib_parser --output raylib_data.info --format XML\n");
printf(" Process <raylib.h> to generate <raylib_data.info> as XML text data\n\n"); printf(" Process <raylib.h> to generate <raylib_data.info> as XML text data\n\n");
printf(" > raylib_parser --input raymath.h --output raymath_data.info --format XML\n"); printf(" > raylib_parser --input raymath.h --output raymath_data.info --format XML --define RMAPI\n");
printf(" Process <raymath.h> to generate <raymath_data.info> as XML text data\n\n"); printf(" Process <raymath.h> to generate <raymath_data.info> as XML text data\n\n");
} }
@ -1277,8 +1280,10 @@ static void GetDataTypeAndName(const char *typeName, int typeNameLen, char *type
} }
else if ((typeName[k] == '.') && (typeNameLen == 3)) // Handle varargs ...); else if ((typeName[k] == '.') && (typeNameLen == 3)) // Handle varargs ...);
{ {
MemoryCopy(type, "...", 3); const char *varargsDots = "...";
MemoryCopy(name, "args", 4); const char *varargsArg = "args";
MemoryCopy(type, varargsDots, TextLength(varargsDots));
MemoryCopy(name, varargsArg, TextLength(varargsArg));
break; break;
} }
} }

View File

@ -509,7 +509,7 @@
</KeyWord> </KeyWord>
<!-- Set custom callbacks --> <!-- Set custom callbacks -->
<!-- WARNING: Callbacks setup is intended for advance users --> <!-- WARNING: Callbacks setup is intended for advanced users -->
<KeyWord name="SetTraceLogCallback" func="yes"> <KeyWord name="SetTraceLogCallback" func="yes">
<Overload retVal="void" descr="Set custom trace log"> <Overload retVal="void" descr="Set custom trace log">
<Param name="TraceLogCallback callback" /> <Param name="TraceLogCallback callback" />
@ -2822,7 +2822,7 @@
<Param name="Vector2 size" /> <Param name="Vector2 size" />
<Param name="Vector2 origin" /> <Param name="Vector2 origin" />
<Param name="float rotation" /> <Param name="float rotation" />
<Param name="0ó¿8± " /> <Param name="0<EFBFBD>8<EFBFBD> " />
</Overload> </Overload>
</KeyWord> </KeyWord>

View File

@ -134,7 +134,7 @@ RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal me
RLAPI void MemFree(void *ptr); // Internal memory free RLAPI void MemFree(void *ptr); // Internal memory free
// Set custom callbacks // Set custom callbacks
// WARNING: Callbacks setup is intended for advance users // WARNING: Callbacks setup is intended for advanced users
RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log
RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader
RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver

View File

@ -202,7 +202,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -219,7 +219,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
@ -237,7 +237,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -258,7 +258,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
@ -281,7 +281,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -303,7 +303,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -325,7 +325,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
@ -353,7 +353,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>

View File

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

View File

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

View File

@ -22,6 +22,7 @@ pub fn addRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
.platform_drm = options.platform_drm, .platform_drm = options.platform_drm,
.shared = options.shared, .shared = options.shared,
.linux_display_backend = options.linux_display_backend, .linux_display_backend = options.linux_display_backend,
.opengl_version = options.opengl_version,
}); });
const raylib = raylib_dep.artifact("raylib"); const raylib = raylib_dep.artifact("raylib");
@ -201,16 +202,22 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
const cache_include = std.fs.path.join(b.allocator, &.{ b.sysroot.?, "cache", "sysroot", "include" }) catch @panic("Out of memory"); const cache_include = std.fs.path.join(b.allocator, &.{ b.sysroot.?, "cache", "sysroot", "include" }) catch @panic("Out of memory");
defer b.allocator.free(cache_include); defer b.allocator.free(cache_include);
var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!"); if (comptime builtin.zig_version.minor > 12) {
dir.close(); var dir = std.fs.cwd().openDir(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!");
dir.close();
raylib.addIncludePath(b.path(cache_include)); raylib.addIncludePath(b.path(cache_include));
} else {
var dir = std.fs.openDirAbsolute(cache_include, std.fs.Dir.OpenDirOptions{ .access_sub_paths = true, .no_follow = true }) catch @panic("No emscripten cache. Generate it!");
dir.close();
raylib.addIncludePath(.{ .path = cache_include });
}
}, },
else => { else => {
@panic("Unsupported OS"); @panic("Unsupported OS");
}, },
} }
raylib.addIncludePath(b.path("src"));
raylib.root_module.addCSourceFiles(.{ raylib.root_module.addCSourceFiles(.{
.root = b.path("src"), .root = b.path("src"),
.files = c_source_files.items, .files = c_source_files.items,

View File

@ -66,7 +66,7 @@
#define SUPPORT_COMPRESSION_API 1 #define SUPPORT_COMPRESSION_API 1
// Support automatic generated events, loading and recording of those events when required // Support automatic generated events, loading and recording of those events when required
#define SUPPORT_AUTOMATION_EVENTS 1 #define SUPPORT_AUTOMATION_EVENTS 1
// Support custom frame control, only for advance users // Support custom frame control, only for advanced users
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents()
// Enabling this flag allows manual control of the frame processes, use at your own risk // Enabling this flag allows manual control of the frame processes, use at your own risk
//#define SUPPORT_CUSTOM_FRAME_CONTROL 1 //#define SUPPORT_CUSTOM_FRAME_CONTROL 1

882
src/external/RGFW.h vendored

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -34,8 +34,12 @@
<link rel="shortcut icon" href="https://www.raylib.com/favicon.ico"> <link rel="shortcut icon" href="https://www.raylib.com/favicon.ico">
<style> <style>
body { margin: 0px; } body {
canvas.emscripten { border: 0px none; background-color: black; } margin: 0px;
overflow: hidden;
background-color: black;
}
canvas.emscripten { border: 0px none; background-color: black;}
</style> </style>
<script type='text/javascript' src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js/dist/FileSaver.min.js"> </script> <script type='text/javascript' src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js/dist/FileSaver.min.js"> </script>
<script type='text/javascript'> <script type='text/javascript'>

View File

@ -666,6 +666,9 @@ void SetWindowMaxSize(int width, int height)
// Set window dimensions // Set window dimensions
void SetWindowSize(int width, int height) void SetWindowSize(int width, int height)
{ {
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
glfwSetWindowSize(platform.handle, width, height); glfwSetWindowSize(platform.handle, width, height);
} }
@ -1443,15 +1446,12 @@ int InitPlatform(void)
else else
{ {
// No-fullscreen window creation // No-fullscreen window creation
bool wantWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0); bool requestWindowedFullscreen = (CORE.Window.screen.height == 0) && (CORE.Window.screen.width == 0);
// If we are windowed fullscreen, ensures that window does not minimize when focus is lost. // If we are windowed fullscreen, ensures that window does not minimize when focus is lost.
// This hinting code will not work if the user already specified the correct monitor dimensions; // This hinting code will not work if the user already specified the correct monitor dimensions;
// at this point we don't know the monitor's dimensions. (Though, how did the user then?) // at this point we don't know the monitor's dimensions. (Though, how did the user then?)
if (wantWindowedFullscreen) if (requestWindowedFullscreen) glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
{
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
}
// Default to at least one pixel in size, as creation with a zero dimension is not allowed. // Default to at least one pixel in size, as creation with a zero dimension is not allowed.
int creationWidth = CORE.Window.screen.width != 0 ? CORE.Window.screen.width : 1; int creationWidth = CORE.Window.screen.width != 0 ? CORE.Window.screen.width : 1;
@ -1471,11 +1471,7 @@ int InitPlatform(void)
monitor = monitors[monitorIndex]; monitor = monitors[monitorIndex];
SetDimensionsFromMonitor(monitor); SetDimensionsFromMonitor(monitor);
TRACELOG(LOG_INFO, "wantWindowed: %d, size: %dx%d", wantWindowedFullscreen, CORE.Window.screen.width, CORE.Window.screen.height); if (requestWindowedFullscreen) glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
if (wantWindowedFullscreen)
{
glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
}
} }
else else
{ {

View File

@ -431,7 +431,11 @@ void SetWindowFocused(void)
// Get native window handle // Get native window handle
void *GetWindowHandle(void) void *GetWindowHandle(void)
{ {
return platform.window->src.window; #ifndef RGFW_WINDOWS
return (void*)platform.window->src.window;
#else
return platform.window->src.hwnd;
#endif
} }
// Get number of monitors // Get number of monitors
@ -890,8 +894,6 @@ void PollInputEvents(void)
CORE.Input.Mouse.currentPosition.x = (event->point.x - (platform.window->r.w / 2)) * 2; CORE.Input.Mouse.currentPosition.x = (event->point.x - (platform.window->r.w / 2)) * 2;
CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h / 2)) * 2; CORE.Input.Mouse.currentPosition.y = (event->point.y - (platform.window->r.h / 2)) * 2;
RGFW_window_showMouse(platform.window, 1);
} }
else { else {
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;

View File

@ -1278,7 +1278,7 @@ Wave WaveCopy(Wave wave)
// NOTE: Security check in case of out-of-range // NOTE: Security check in case of out-of-range
void WaveCrop(Wave *wave, int initFrame, int finalFrame) void WaveCrop(Wave *wave, int initFrame, int finalFrame)
{ {
if ((initFrame >= 0) && (initFrame < finalFrame) && ((unsigned int)finalFrame < wave->frameCount)) if ((initFrame >= 0) && (initFrame < finalFrame) && ((unsigned int)finalFrame <= wave->frameCount))
{ {
int frameCount = finalFrame - initFrame; int frameCount = finalFrame - initFrame;
@ -1288,6 +1288,7 @@ void WaveCrop(Wave *wave, int initFrame, int finalFrame)
RL_FREE(wave->data); RL_FREE(wave->data);
wave->data = data; wave->data = data;
wave->frameCount = (unsigned int)frameCount;
} }
else TRACELOG(LOG_WARNING, "WAVE: Crop range out of bounds"); else TRACELOG(LOG_WARNING, "WAVE: Crop range out of bounds");
} }
@ -1303,8 +1304,8 @@ float *LoadWaveSamples(Wave wave)
for (unsigned int i = 0; i < wave.frameCount*wave.channels; i++) for (unsigned int i = 0; i < wave.frameCount*wave.channels; i++)
{ {
if (wave.sampleSize == 8) samples[i] = (float)(((unsigned char *)wave.data)[i] - 127)/256.0f; if (wave.sampleSize == 8) samples[i] = (float)(((unsigned char *)wave.data)[i] - 128)/128.0f;
else if (wave.sampleSize == 16) samples[i] = (float)(((short *)wave.data)[i])/32767.0f; else if (wave.sampleSize == 16) samples[i] = (float)(((short *)wave.data)[i])/32768.0f;
else if (wave.sampleSize == 32) samples[i] = ((float *)wave.data)[i]; else if (wave.sampleSize == 32) samples[i] = ((float *)wave.data)[i];
} }
@ -1427,7 +1428,9 @@ Music LoadMusicStream(const char *fileName)
{ {
music.ctxType = MUSIC_AUDIO_FLAC; music.ctxType = MUSIC_AUDIO_FLAC;
music.ctxData = ctxFlac; music.ctxData = ctxFlac;
music.stream = LoadAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels); int sampleSize = ctxFlac->bitsPerSample;
if (ctxFlac->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream()
music.stream = LoadAudioStream(ctxFlac->sampleRate, sampleSize, ctxFlac->channels);
music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount; music.frameCount = (unsigned int)ctxFlac->totalPCMFrameCount;
music.looping = true; // Looping enabled by default music.looping = true; // Looping enabled by default
musicLoaded = true; musicLoaded = true;

View File

@ -934,7 +934,7 @@ typedef enum {
} NPatchLayout; } NPatchLayout;
// Callbacks to hook some internal functions // Callbacks to hook some internal functions
// WARNING: These callbacks are intended for advance users // WARNING: These callbacks are intended for advanced users
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data typedef unsigned char *(*LoadFileDataCallback)(const char *fileName, int *dataSize); // FileIO: Load binary data
typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data typedef bool (*SaveFileDataCallback)(const char *fileName, void *data, int dataSize); // FileIO: Save binary data
@ -1066,7 +1066,7 @@ RLAPI double GetTime(void); // Get elapsed
RLAPI int GetFPS(void); // Get current FPS RLAPI int GetFPS(void); // Get current FPS
// Custom frame control functions // Custom frame control functions
// NOTE: Those functions are intended for advance users that want full control over the frame processing // NOTE: Those functions are intended for advanced users that want full control over the frame processing
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() // By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents()
// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL // To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL
RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing) RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing)
@ -1093,7 +1093,7 @@ RLAPI void *MemRealloc(void *ptr, unsigned int size); // Internal me
RLAPI void MemFree(void *ptr); // Internal memory free RLAPI void MemFree(void *ptr); // Internal memory free
// Set custom callbacks // Set custom callbacks
// WARNING: Callbacks setup is intended for advance users // WARNING: Callbacks setup is intended for advanced users
RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set custom trace log
RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader RLAPI void SetLoadFileDataCallback(LoadFileDataCallback callback); // Set custom file binary data loader
RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver RLAPI void SetSaveFileDataCallback(SaveFileDataCallback callback); // Set custom file binary data saver
@ -1124,6 +1124,7 @@ RLAPI const char *GetWorkingDirectory(void); // Get current
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string) RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
@ -1140,7 +1141,7 @@ RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize
// Automation events functionality // Automation events functionality
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file RLAPI void UnloadAutomationEventList(AutomationEventList list); // Unload automation events list from file
RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file RLAPI bool ExportAutomationEventList(AutomationEventList list, const char *fileName); // Export automation events list as text file
RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to RLAPI void SetAutomationEventList(AutomationEventList *list); // Set automation event list to record to
RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording RLAPI void SetAutomationEventBaseFrame(int frame); // Set automation event internal base frame to start recording
@ -1232,7 +1233,7 @@ RLAPI void DrawPixelV(Vector2 position, Color color);
RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines) RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines)
RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads) RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads)
RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines) RLAPI void DrawLineStrip(const Vector2 *points, int pointCount, Color color); // Draw lines sequence (using gl lines)
RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle
@ -1259,18 +1260,18 @@ RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segment
RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline RLAPI void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!)
RLAPI void DrawTriangleFan(Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) RLAPI void DrawTriangleFan(const Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
RLAPI void DrawTriangleStrip(Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points RLAPI void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
// Splines drawing functions // Splines drawing functions
RLAPI void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points RLAPI void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points
RLAPI void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points RLAPI void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points
RLAPI void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points RLAPI void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points
RLAPI void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] RLAPI void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
RLAPI void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] RLAPI void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points RLAPI void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points
RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points RLAPI void DrawSplineSegmentBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points
RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points
@ -1291,9 +1292,10 @@ RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec);
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
RLAPI bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices RLAPI bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices
RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -1340,10 +1342,10 @@ RLAPI void ImageAlphaClear(Image *image, Color color, float threshold);
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel RLAPI void ImageAlphaPremultiply(Image *image); // Premultiply alpha channel
RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation RLAPI void ImageBlurGaussian(Image *image, int blurSize); // Apply Gaussian blur using a box blur approximation
RLAPI void ImageKernelConvolution(Image *image, float* kernel, int kernelSize); // Apply Custom Square image convolution kernel RLAPI void ImageKernelConvolution(Image *image, const float *kernel, int kernelSize); // Apply custom square convolution kernel to image
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm)
RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight); // Resize image (Nearest-Neighbor scaling algorithm)
RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color
RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image RLAPI void ImageMipmaps(Image *image); // Compute all mipmap levels for a provided image
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
@ -1371,6 +1373,7 @@ RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color);
RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version) RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version)
RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image
RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version) RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version)
RLAPI void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color color); // Draw a line defining thickness within an image
RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image
RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version) RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version)
RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image
@ -1379,6 +1382,11 @@ RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int hei
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image
RLAPI void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle within an image
RLAPI void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3); // Draw triangle with interpolated colors within an image
RLAPI void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline within an image
RLAPI void ImageDrawTriangleFan(Image *dst, Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points within an image (first vertex is the center)
RLAPI void ImageDrawTriangleStrip(Image *dst, Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points within an image
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source)
RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination) RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination)
RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination) RLAPI void ImageDrawTextEx(Image *dst, Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination)
@ -1434,7 +1442,7 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
// Font loading/unloading functions // Font loading/unloading functions
RLAPI Font GetFontDefault(void); // Get the default Font RLAPI Font GetFontDefault(void); // Get the default Font
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM) RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
RLAPI bool IsFontReady(Font font); // Check if a font is ready RLAPI bool IsFontReady(Font font); // Check if a font is ready
@ -1487,6 +1495,9 @@ RLAPI int TextFindIndex(const char *text, const char *find);
RLAPI const char *TextToUpper(const char *text); // Get upper case 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 *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 *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 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 float TextToFloat(const char *text); // Get float value from text (negative values not supported)
@ -1499,7 +1510,7 @@ RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color);
RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line
RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points RLAPI void DrawTriangleStrip3D(const Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires

View File

@ -1837,32 +1837,32 @@ RMAPI Matrix MatrixScale(float x, float y, float z)
} }
// Get perspective projection matrix // Get perspective projection matrix
RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far) RMAPI Matrix MatrixFrustum(double left, double right, double bottom, double top, double nearPlane, double farPlane)
{ {
Matrix result = { 0 }; Matrix result = { 0 };
float rl = (float)(right - left); float rl = (float)(right - left);
float tb = (float)(top - bottom); float tb = (float)(top - bottom);
float fn = (float)(far - near); float fn = (float)(farPlane - nearPlane);
result.m0 = ((float)near*2.0f)/rl; result.m0 = ((float)nearPlane*2.0f)/rl;
result.m1 = 0.0f; result.m1 = 0.0f;
result.m2 = 0.0f; result.m2 = 0.0f;
result.m3 = 0.0f; result.m3 = 0.0f;
result.m4 = 0.0f; result.m4 = 0.0f;
result.m5 = ((float)near*2.0f)/tb; result.m5 = ((float)nearPlane*2.0f)/tb;
result.m6 = 0.0f; result.m6 = 0.0f;
result.m7 = 0.0f; result.m7 = 0.0f;
result.m8 = ((float)right + (float)left)/rl; result.m8 = ((float)right + (float)left)/rl;
result.m9 = ((float)top + (float)bottom)/tb; result.m9 = ((float)top + (float)bottom)/tb;
result.m10 = -((float)far + (float)near)/fn; result.m10 = -((float)farPlane + (float)nearPlane)/fn;
result.m11 = -1.0f; result.m11 = -1.0f;
result.m12 = 0.0f; result.m12 = 0.0f;
result.m13 = 0.0f; result.m13 = 0.0f;
result.m14 = -((float)far*(float)near*2.0f)/fn; result.m14 = -((float)farPlane*(float)nearPlane*2.0f)/fn;
result.m15 = 0.0f; result.m15 = 0.0f;
return result; return result;

View File

@ -856,7 +856,7 @@ void EndDrawing(void)
#ifndef GIF_RECORD_FRAMERATE #ifndef GIF_RECORD_FRAMERATE
#define GIF_RECORD_FRAMERATE 10 #define GIF_RECORD_FRAMERATE 10
#endif #endif
gifFrameCounter += GetFrameTime()*1000; gifFrameCounter += (unsigned int)(GetFrameTime()*1000);
// NOTE: We record one gif frame depending on the desired gif framerate // NOTE: We record one gif frame depending on the desired gif framerate
if (gifFrameCounter > 1000/GIF_RECORD_FRAMERATE) if (gifFrameCounter > 1000/GIF_RECORD_FRAMERATE)
@ -2244,6 +2244,64 @@ bool IsPathFile(const char *path)
return S_ISREG(result.st_mode); return S_ISREG(result.st_mode);
} }
// Check if fileName is valid for the platform/OS
bool IsFileNameValid(const char *fileName)
{
bool valid = true;
if ((fileName != NULL) && (fileName[0] != '\0'))
{
int length = (int)strlen(fileName);
bool allPeriods = true;
for (int i = 0; i < length; i++)
{
// Check invalid characters
if ((fileName[i] == '<') ||
(fileName[i] == '>') ||
(fileName[i] == ':') ||
(fileName[i] == '\"') ||
(fileName[i] == '/') ||
(fileName[i] == '\\') ||
(fileName[i] == '|') ||
(fileName[i] == '?') ||
(fileName[i] == '*')) { valid = false; break; }
// Check non-glyph characters
if ((unsigned char)fileName[i] < 32) { valid = false; break; }
// TODO: Check trailing periods/spaces?
// Check if filename is not all periods
if (fileName[i] != '.') allPeriods = false;
}
if (allPeriods) valid = false;
/*
if (valid)
{
// Check invalid DOS names
if (length >= 3)
{
if (((fileName[0] == 'C') && (fileName[1] == 'O') && (fileName[2] == 'N')) || // CON
((fileName[0] == 'P') && (fileName[1] == 'R') && (fileName[2] == 'N')) || // PRN
((fileName[0] == 'A') && (fileName[1] == 'U') && (fileName[2] == 'X')) || // AUX
((fileName[0] == 'N') && (fileName[1] == 'U') && (fileName[2] == 'L'))) valid = false; // NUL
}
if (length >= 4)
{
if (((fileName[0] == 'C') && (fileName[1] == 'O') && (fileName[2] == 'M') && ((fileName[3] >= '0') && (fileName[3] <= '9'))) || // COM0-9
((fileName[0] == 'L') && (fileName[1] == 'P') && (fileName[2] == 'T') && ((fileName[3] >= '0') && (fileName[3] <= '9')))) valid = false; // LPT0-9
}
}
*/
}
return valid;
}
// Check if a file has been dropped into window // Check if a file has been dropped into window
bool IsFileDropped(void) bool IsFileDropped(void)
{ {

View File

@ -590,7 +590,7 @@ RLAPI void rlMultMatrixf(const float *matf); // Multiply the current
RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar); RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar);
RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar); RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar);
RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area
RLAPI void rlSetClipPlanes(double near, double far); // Set clip planes distances RLAPI void rlSetClipPlanes(double nearPlane, double farPlane); // Set clip planes distances
RLAPI double rlGetCullDistanceNear(void); // Get cull plane distance near RLAPI double rlGetCullDistanceNear(void); // Get cull plane distance near
RLAPI double rlGetCullDistanceFar(void); // Get cull plane distance far RLAPI double rlGetCullDistanceFar(void); // Get cull plane distance far
@ -1371,10 +1371,10 @@ void rlViewport(int x, int y, int width, int height)
} }
// Set clip planes distances // Set clip planes distances
void rlSetClipPlanes(double near, double far) void rlSetClipPlanes(double nearPlane, double farPlane)
{ {
rlCullDistanceNear = near; rlCullDistanceNear = nearPlane;
rlCullDistanceFar = far; rlCullDistanceFar = farPlane;
} }
// Get cull plane distance near // Get cull plane distance near
@ -1406,7 +1406,7 @@ void rlBegin(int mode)
} }
} }
void rlEnd() { glEnd(); } void rlEnd(void) { glEnd(); }
void rlVertex2i(int x, int y) { glVertex2i(x, y); } void rlVertex2i(int x, int y) { glVertex2i(x, y); }
void rlVertex2f(float x, float y) { glVertex2f(x, y); } void rlVertex2f(float x, float y) { glVertex2f(x, y); }
void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); } void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); }
@ -3945,7 +3945,9 @@ void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool norma
// Additional types (depends on OpenGL version or extensions): // Additional types (depends on OpenGL version or extensions):
// - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, // - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED,
// - GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV // - GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV
glVertexAttribPointer(index, compSize, type, normalized, stride, (void *)offset);
size_t offsetNative = offset;
glVertexAttribPointer(index, compSize, type, normalized, stride, (void *)offsetNative);
#endif #endif
} }
@ -4518,7 +4520,7 @@ Matrix rlGetMatrixTransform(void)
} }
// Get internal projection matrix for stereo render (selected eye) // Get internal projection matrix for stereo render (selected eye)
RLAPI Matrix rlGetMatrixProjectionStereo(int eye) Matrix rlGetMatrixProjectionStereo(int eye)
{ {
Matrix mat = rlMatrixIdentity(); Matrix mat = rlMatrixIdentity();
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
@ -4528,7 +4530,7 @@ RLAPI Matrix rlGetMatrixProjectionStereo(int eye)
} }
// Get internal view offset matrix for stereo render (selected eye) // Get internal view offset matrix for stereo render (selected eye)
RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye) Matrix rlGetMatrixViewOffsetStereo(int eye)
{ {
Matrix mat = rlMatrixIdentity(); Matrix mat = rlMatrixIdentity();
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)

View File

@ -226,7 +226,7 @@ void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color)
} }
// Draw a triangle strip defined by points // Draw a triangle strip defined by points
void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color) void DrawTriangleStrip3D(const Vector3 *points, int pointCount, Color color)
{ {
if (pointCount < 3) return; // Security check if (pointCount < 3) return; // Security check
@ -508,6 +508,8 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
const float angleStep = 360.0f/sides;
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
@ -517,43 +519,44 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
if (radiusTop > 0) if (radiusTop > 0)
{ {
// Draw Body ------------------------------------------------------------------------------------- // Draw Body -------------------------------------------------------------------------------------
for (int i = 0; i < 360; i += 360/sides) for (int i = 0; i < sides; i++)
{ {
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); //Bottom Left rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusBottom, 0, cosf(DEG2RAD*i*angleStep)*radiusBottom); //Bottom Left
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360.0f/sides))*radiusBottom); //Bottom Right rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusBottom, 0, cosf(DEG2RAD*(i+1)*angleStep)*radiusBottom); //Bottom Right
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360.0f/sides))*radiusTop); //Top Right rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusTop, height, cosf(DEG2RAD*(i+1)*angleStep)*radiusTop); //Top Right
rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop); //Top Left rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusTop, height, cosf(DEG2RAD*i*angleStep)*radiusTop); //Top Left
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); //Bottom Left rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusBottom, 0, cosf(DEG2RAD*i*angleStep)*radiusBottom); //Bottom Left
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360.0f/sides))*radiusTop); //Top Right rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusTop, height, cosf(DEG2RAD*(i+1)*angleStep)*radiusTop); //Top Right
} }
// Draw Cap -------------------------------------------------------------------------------------- // Draw Cap --------------------------------------------------------------------------------------
for (int i = 0; i < 360; i += 360/sides) for (int i = 0; i < sides; i++)
{ {
rlVertex3f(0, height, 0); rlVertex3f(0, height, 0);
rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop); rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusTop, height, cosf(DEG2RAD*i*angleStep)*radiusTop);
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360.0f/sides))*radiusTop); rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusTop, height, cosf(DEG2RAD*(i+1)*angleStep)*radiusTop);
} }
} }
else else
{ {
// Draw Cone ------------------------------------------------------------------------------------- // Draw Cone -------------------------------------------------------------------------------------
for (int i = 0; i < 360; i += 360/sides) for (int i = 0; i < sides; i++)
{ {
rlVertex3f(0, height, 0); rlVertex3f(0, height, 0);
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusBottom, 0, cosf(DEG2RAD*i*angleStep)*radiusBottom);
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360.0f/sides))*radiusBottom); rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusBottom, 0, cosf(DEG2RAD*(i+1)*angleStep)*radiusBottom);
} }
} }
// Draw Base ----------------------------------------------------------------------------------------- // Draw Base -----------------------------------------------------------------------------------------
for (int i = 0; i < 360; i += 360/sides) for (int i = 0; i < sides; i++)
{ {
rlVertex3f(0, 0, 0); rlVertex3f(0, 0, 0);
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360.0f/sides))*radiusBottom); rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusBottom, 0, cosf(DEG2RAD*(i+1)*angleStep)*radiusBottom);
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusBottom, 0, cosf(DEG2RAD*i*angleStep)*radiusBottom);
} }
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();
} }
@ -623,25 +626,27 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
{ {
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
const float angleStep = 360.0f/sides;
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
for (int i = 0; i < 360; i += 360/sides) for (int i = 0; i < sides; i++)
{ {
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusBottom, 0, cosf(DEG2RAD*i*angleStep)*radiusBottom);
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360.0f/sides))*radiusBottom); rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusBottom, 0, cosf(DEG2RAD*(i+1)*angleStep)*radiusBottom);
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusBottom, 0, cosf(DEG2RAD*(i + 360.0f/sides))*radiusBottom); rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusBottom, 0, cosf(DEG2RAD*(i+1)*angleStep)*radiusBottom);
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360.0f/sides))*radiusTop); rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusTop, height, cosf(DEG2RAD*(i+1)*angleStep)*radiusTop);
rlVertex3f(sinf(DEG2RAD*(i + 360.0f/sides))*radiusTop, height, cosf(DEG2RAD*(i + 360.0f/sides))*radiusTop); rlVertex3f(sinf(DEG2RAD*(i+1)*angleStep)*radiusTop, height, cosf(DEG2RAD*(i+1)*angleStep)*radiusTop);
rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop); rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusTop, height, cosf(DEG2RAD*i*angleStep)*radiusTop);
rlVertex3f(sinf(DEG2RAD*i)*radiusTop, height, cosf(DEG2RAD*i)*radiusTop); rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusTop, height, cosf(DEG2RAD*i*angleStep)*radiusTop);
rlVertex3f(sinf(DEG2RAD*i)*radiusBottom, 0, cosf(DEG2RAD*i)*radiusBottom); rlVertex3f(sinf(DEG2RAD*i*angleStep)*radiusBottom, 0, cosf(DEG2RAD*i*angleStep)*radiusBottom);
} }
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();
@ -1389,14 +1394,14 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], matView); if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], matView);
if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProjection); if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProjection);
// Model transformation matrix is sent to shader uniform location: SHADER_LOC_MATRIX_MODEL
if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], transform);
// Accumulate several model transformations: // Accumulate several model transformations:
// transform: model transformation provided (includes DrawModel() params combined with model.transform) // transform: model transformation provided (includes DrawModel() params combined with model.transform)
// rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack // rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack
matModel = MatrixMultiply(transform, rlGetMatrixTransform()); matModel = MatrixMultiply(transform, rlGetMatrixTransform());
// Model transformation matrix is sent to shader uniform location: SHADER_LOC_MATRIX_MODEL
if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], matModel);
// Get model-view matrix // Get model-view matrix
matModelView = MatrixMultiply(matModel, matView); matModelView = MatrixMultiply(matModel, matView);
@ -3431,7 +3436,12 @@ void GenMeshTangents(Mesh *mesh)
Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3)); Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3)); Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
for (int i = 0; i < mesh->vertexCount - 3; i += 3) if (mesh->vertexCount % 3 != 0)
{
TRACELOG(LOG_WARNING, "MESH: vertexCount expected to be a multiple of 3. Expect uninitialized values.");
}
for (int i = 0; i <= mesh->vertexCount - 3; i += 3)
{ {
// Get triangle vertices // Get triangle vertices
Vector3 v1 = { mesh->vertices[(i + 0)*3 + 0], mesh->vertices[(i + 0)*3 + 1], mesh->vertices[(i + 0)*3 + 2] }; Vector3 v1 = { mesh->vertices[(i + 0)*3 + 0], mesh->vertices[(i + 0)*3 + 1], mesh->vertices[(i + 0)*3 + 2] };
@ -3546,10 +3556,10 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
Color color = model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color; Color color = model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color;
Color colorTint = WHITE; Color colorTint = WHITE;
colorTint.r = (unsigned char)((((float)color.r/255.0f)*((float)tint.r/255.0f))*255.0f); colorTint.r = (unsigned char)(((int)color.r*(int)tint.r)/255);
colorTint.g = (unsigned char)((((float)color.g/255.0f)*((float)tint.g/255.0f))*255.0f); colorTint.g = (unsigned char)(((int)color.g*(int)tint.g)/255);
colorTint.b = (unsigned char)((((float)color.b/255.0f)*((float)tint.b/255.0f))*255.0f); colorTint.b = (unsigned char)(((int)color.b*(int)tint.b)/255);
colorTint.a = (unsigned char)((((float)color.a/255.0f)*((float)tint.a/255.0f))*255.0f); colorTint.a = (unsigned char)(((int)color.a*(int)tint.a)/255);
model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = colorTint; model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = colorTint;
DrawMesh(model.meshes[i], model.materials[model.meshMaterial[i]], model.transform); DrawMesh(model.meshes[i], model.materials[model.meshMaterial[i]], model.transform);
@ -4268,6 +4278,8 @@ static Model LoadIQM(const char *fileName)
// In case file can not be read, return an empty model // In case file can not be read, return an empty model
if (fileDataPtr == NULL) return model; if (fileDataPtr == NULL) return model;
const char* basePath = GetDirectoryPath(fileName);
// Read IQM header // Read IQM header
IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr; IQMHeader *iqmHeader = (IQMHeader *)fileDataPtr;
@ -4312,7 +4324,10 @@ static Model LoadIQM(const char *fileName)
memcpy(material, fileDataPtr + iqmHeader->ofs_text + imesh[i].material, MATERIAL_NAME_LENGTH*sizeof(char)); memcpy(material, fileDataPtr + iqmHeader->ofs_text + imesh[i].material, MATERIAL_NAME_LENGTH*sizeof(char));
model.materials[i] = LoadMaterialDefault(); model.materials[i] = LoadMaterialDefault();
model.materials[i].maps[MATERIAL_MAP_ALBEDO].texture = LoadTexture(TextFormat("%s/%s", basePath, material));
model.meshMaterial[i] = i;
TRACELOG(LOG_DEBUG, "MODEL: [%s] mesh name (%s), material (%s)", fileName, name, material); TRACELOG(LOG_DEBUG, "MODEL: [%s] mesh name (%s), material (%s)", fileName, name, material);
model.meshes[i].vertexCount = imesh[i].num_vertexes; model.meshes[i].vertexCount = imesh[i].num_vertexes;
@ -4621,6 +4636,8 @@ static ModelAnimation *LoadModelAnimationsIQM(const char *fileName, int *animCou
animations[a].boneCount = iqmHeader->num_poses; animations[a].boneCount = iqmHeader->num_poses;
animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo)); animations[a].bones = RL_MALLOC(iqmHeader->num_poses*sizeof(BoneInfo));
animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *)); animations[a].framePoses = RL_MALLOC(anim[a].num_frames*sizeof(Transform *));
memcpy(animations[a].name, fileDataPtr + iqmHeader->ofs_text + anim[a].name, 32); // I don't like this 32 here
TraceLog(LOG_INFO, "IQM Anim %s", animations[a].name);
// animations[a].framerate = anim.framerate; // TODO: Use animation framerate data? // animations[a].framerate = anim.framerate; // TODO: Use animation framerate data?
for (unsigned int j = 0; j < iqmHeader->num_poses; j++) for (unsigned int j = 0; j < iqmHeader->num_poses; j++)
@ -4854,7 +4871,11 @@ static BoneInfo *LoadBoneInfoGLTF(cgltf_skin skin, int *boneCount)
for (unsigned int i = 0; i < skin.joints_count; i++) for (unsigned int i = 0; i < skin.joints_count; i++)
{ {
cgltf_node node = *skin.joints[i]; cgltf_node node = *skin.joints[i];
strncpy(bones[i].name, node.name, sizeof(bones[i].name)); if (node.name != NULL)
{
strncpy(bones[i].name, node.name, sizeof(bones[i].name));
bones[i].name[sizeof(bones[i].name) - 1] = '\0';
}
// Find parent bone index // Find parent bone index
unsigned int parentIndex = -1; unsigned int parentIndex = -1;
@ -4880,6 +4901,7 @@ static Model LoadGLTF(const char *fileName)
/********************************************************************************************* /*********************************************************************************************
Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend) Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend)
Transform handling implemented by Paul Melis (@paulmelis).
Reviewed by Ramon Santamaria (@raysan5) Reviewed by Ramon Santamaria (@raysan5)
FEATURES: FEATURES:
@ -4889,6 +4911,10 @@ static Model LoadGLTF(const char *fileName)
PBR specular/glossiness flow and extended texture flows not supported PBR specular/glossiness flow and extended texture flows not supported
- Supports multiple meshes per model (every primitives is loaded as a separate mesh) - Supports multiple meshes per model (every primitives is loaded as a separate mesh)
- Supports basic animations - Supports basic animations
- Transforms, including parent-child relations, are applied on the mesh data, but the
hierarchy is not kept (as it can't be represented).
- Mesh instances in the glTF file (i.e. same mesh linked from multiple nodes)
are turned into separate raylib Meshes.
RESTRICTIONS: RESTRICTIONS:
- Only triangle meshes supported - Only triangle meshes supported
@ -4898,7 +4924,8 @@ static Model LoadGLTF(const char *fileName)
> Texcoords: vec2: float > Texcoords: vec2: float
> Colors: vec4: u8, u16, f32 (normalized) > Colors: vec4: u8, u16, f32 (normalized)
> Indices: u16, u32 (truncated to u16) > Indices: u16, u32 (truncated to u16)
- Node hierarchies or transforms not supported - Scenes defined in the glTF file are ignored. All nodes in the file
are used.
***********************************************************************************************/ ***********************************************************************************************/
@ -4950,8 +4977,22 @@ static Model LoadGLTF(const char *fileName)
if (result != cgltf_result_success) TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load mesh/material buffers", fileName); if (result != cgltf_result_success) TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load mesh/material buffers", fileName);
int primitivesCount = 0; int primitivesCount = 0;
// NOTE: We will load every primitive in the glTF as a separate raylib mesh // NOTE: We will load every primitive in the glTF as a separate raylib Mesh.
for (unsigned int i = 0; i < data->meshes_count; i++) primitivesCount += (int)data->meshes[i].primitives_count; // Determine total number of meshes needed from the node hierarchy.
for (unsigned int i = 0; i < data->nodes_count; i++)
{
cgltf_node *node = &(data->nodes[i]);
cgltf_mesh *mesh = node->mesh;
if (!mesh)
continue;
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{
if (mesh->primitives[p].type == cgltf_primitive_type_triangles)
primitivesCount++;
}
}
TRACELOG(LOG_DEBUG, " > Primitives (triangles only) count based on hierarchy : %i", primitivesCount);
// Load our model data: meshes and materials // Load our model data: meshes and materials
model.meshCount = primitivesCount; model.meshCount = primitivesCount;
@ -5054,27 +5095,51 @@ static Model LoadGLTF(const char *fileName)
// has_clearcoat, has_transmission, has_volume, has_ior, has specular, has_sheen // has_clearcoat, has_transmission, has_volume, has_ior, has specular, has_sheen
} }
// Load meshes data // Visit each node in the hierarchy and process any mesh linked from it.
// Each primitive within a glTF node becomes a Raylib Mesh.
// The local-to-world transform of each node is used to transform the
// points/normals/tangents of the created Mesh(es).
// Any glTF mesh linked from more than one Node (i.e. instancing)
// is turned into multiple Mesh's, as each Node will have its own
// transform applied.
// Note: the code below disregards the scenes defined in the file, all nodes are used.
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
for (unsigned int i = 0, meshIndex = 0; i < data->meshes_count; i++) int meshIndex = 0;
for (unsigned int i = 0; i < data->nodes_count; i++)
{ {
// NOTE: meshIndex accumulates primitives cgltf_node *node = &(data->nodes[i]);
for (unsigned int p = 0; p < data->meshes[i].primitives_count; p++) cgltf_mesh *mesh = node->mesh;
if (!mesh)
continue;
cgltf_float worldTransform[16];
cgltf_node_transform_world(node, worldTransform);
Matrix worldMatrix = {
worldTransform[0], worldTransform[4], worldTransform[8], worldTransform[12],
worldTransform[1], worldTransform[5], worldTransform[9], worldTransform[13],
worldTransform[2], worldTransform[6], worldTransform[10], worldTransform[14],
worldTransform[3], worldTransform[7], worldTransform[11], worldTransform[15]
};
Matrix worldMatrixNormals = MatrixTranspose(MatrixInvert(worldMatrix));
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{ {
// NOTE: We only support primitives defined by triangles // NOTE: We only support primitives defined by triangles
// Other alternatives: points, lines, line_strip, triangle_strip // Other alternatives: points, lines, line_strip, triangle_strip
if (data->meshes[i].primitives[p].type != cgltf_primitive_type_triangles) continue; if (mesh->primitives[p].type != cgltf_primitive_type_triangles) continue;
// NOTE: Attributes data could be provided in several data formats (8, 8u, 16u, 32...), // NOTE: Attributes data could be provided in several data formats (8, 8u, 16u, 32...),
// Only some formats for each attribute type are supported, read info at the top of this function! // Only some formats for each attribute type are supported, read info at the top of this function!
for (unsigned int j = 0; j < data->meshes[i].primitives[p].attributes_count; j++) for (unsigned int j = 0; j < mesh->primitives[p].attributes_count; j++)
{ {
// Check the different attributes for every primitive // Check the different attributes for every primitive
if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_position) // POSITION, vec3, float if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_position) // POSITION, vec3, float
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
// WARNING: SPECS: POSITION accessor MUST have its min and max properties defined // WARNING: SPECS: POSITION accessor MUST have its min and max properties defined
@ -5086,12 +5151,22 @@ static Model LoadGLTF(const char *fileName)
// Load 3 components of float data type into mesh.vertices // Load 3 components of float data type into mesh.vertices
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices) LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].vertices)
// Transform the vertices
float *vertices = model.meshes[meshIndex].vertices;
for (int k = 0; k < attribute->count; k++)
{
Vector3 vt = Vector3Transform((Vector3){ vertices[3*k], vertices[3*k+1], vertices[3*k+2] }, worldMatrix);
vertices[3*k] = vt.x;
vertices[3*k+1] = vt.y;
vertices[3*k+2] = vt.z;
}
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Vertices attribute data format not supported, use vec3 float", fileName);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL, vec3, float else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_normal) // NORMAL, vec3, float
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f)) if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f))
{ {
@ -5100,12 +5175,22 @@ static Model LoadGLTF(const char *fileName)
// Load 3 components of float data type into mesh.normals // Load 3 components of float data type into mesh.normals
LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals) LOAD_ATTRIBUTE(attribute, 3, float, model.meshes[meshIndex].normals)
// Transform the normals
float *normals = model.meshes[meshIndex].normals;
for (int k = 0; k < attribute->count; k++)
{
Vector3 nt = Vector3Transform((Vector3){ normals[3*k], normals[3*k+1], normals[3*k+2] }, worldMatrixNormals);
normals[3*k] = nt.x;
normals[3*k+1] = nt.y;
normals[3*k+2] = nt.z;
}
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Normal attribute data format not supported, use vec3 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Normal attribute data format not supported, use vec3 float", fileName);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT, vec3, float else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_tangent) // TANGENT, vec3, float
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f)) if ((attribute->type == cgltf_type_vec4) && (attribute->component_type == cgltf_component_type_r_32f))
{ {
@ -5114,15 +5199,25 @@ static Model LoadGLTF(const char *fileName)
// Load 4 components of float data type into mesh.tangents // Load 4 components of float data type into mesh.tangents
LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents) LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].tangents)
// Transform the tangents
float *tangents = model.meshes[meshIndex].tangents;
for (int k = 0; k < attribute->count; k++)
{
Vector3 tt = Vector3Transform((Vector3){ tangents[3*k], tangents[3*k+1], tangents[3*k+2] }, worldMatrix);
tangents[3*k] = tt.x;
tangents[3*k+1] = tt.y;
tangents[3*k+2] = tt.z;
}
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Tangent attribute data format not supported, use vec4 float", fileName);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_texcoord) // TEXCOORD_n, vec2, float/u8n/u16n
{ {
// Support up to 2 texture coordinates attributes // Support up to 2 texture coordinates attributes
float *texcoordPtr = NULL; float *texcoordPtr = NULL;
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
if (attribute->type == cgltf_type_vec2) if (attribute->type == cgltf_type_vec2)
{ {
@ -5166,7 +5261,7 @@ static Model LoadGLTF(const char *fileName)
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Texcoords attribute data format not supported, use vec2 float", fileName);
int index = data->meshes[i].primitives[p].attributes[j].index; int index = mesh->primitives[p].attributes[j].index;
if (index == 0) model.meshes[meshIndex].texcoords = texcoordPtr; if (index == 0) model.meshes[meshIndex].texcoords = texcoordPtr;
else if (index == 1) model.meshes[meshIndex].texcoords2 = texcoordPtr; else if (index == 1) model.meshes[meshIndex].texcoords2 = texcoordPtr;
else else
@ -5175,9 +5270,9 @@ static Model LoadGLTF(const char *fileName)
if (texcoordPtr != NULL) RL_FREE(texcoordPtr); if (texcoordPtr != NULL) RL_FREE(texcoordPtr);
} }
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_color) // COLOR_n, vec3/vec4, float/u8n/u16n else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_color) // COLOR_n, vec3/vec4, float/u8n/u16n
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
// WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range // WARNING: SPECS: All components of each COLOR_n accessor element MUST be clamped to [0.0, 1.0] range
@ -5294,9 +5389,9 @@ static Model LoadGLTF(const char *fileName)
} }
// Load primitive indices data (if provided) // Load primitive indices data (if provided)
if (data->meshes[i].primitives[p].indices != NULL) if (mesh->primitives[p].indices != NULL)
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].indices; cgltf_accessor *attribute = mesh->primitives[p].indices;
model.meshes[meshIndex].triangleCount = (int)attribute->count/3; model.meshes[meshIndex].triangleCount = (int)attribute->count/3;
@ -5336,7 +5431,7 @@ static Model LoadGLTF(const char *fileName)
// raylib instead assigns to the mesh the by its index, as loaded in model.materials array // raylib instead assigns to the mesh the by its index, as loaded in model.materials array
// To get the index, we check if material pointers match, and we assign the corresponding index, // To get the index, we check if material pointers match, and we assign the corresponding index,
// skipping index 0, the default material // skipping index 0, the default material
if (&data->materials[m] == data->meshes[i].primitives[p].material) if (&data->materials[m] == mesh->primitives[p].material)
{ {
model.meshMaterial[meshIndex] = m + 1; model.meshMaterial[meshIndex] = m + 1;
break; break;
@ -5386,20 +5481,27 @@ static Model LoadGLTF(const char *fileName)
TRACELOG(LOG_ERROR, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count); TRACELOG(LOG_ERROR, "MODEL: [%s] can only load one skin (armature) per model, but gltf skins_count == %i", fileName, data->skins_count);
} }
for (unsigned int i = 0, meshIndex = 0; i < data->meshes_count; i++) meshIndex = 0;
for (unsigned int i = 0; i < data->nodes_count; i++)
{ {
for (unsigned int p = 0; p < data->meshes[i].primitives_count; p++) cgltf_node *node = &(data->nodes[i]);
cgltf_mesh *mesh = node->mesh;
if (!mesh)
continue;
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{ {
// NOTE: We only support primitives defined by triangles // NOTE: We only support primitives defined by triangles
if (data->meshes[i].primitives[p].type != cgltf_primitive_type_triangles) continue; if (mesh->primitives[p].type != cgltf_primitive_type_triangles) continue;
for (unsigned int j = 0; j < data->meshes[i].primitives[p].attributes_count; j++) for (unsigned int j = 0; j < mesh->primitives[p].attributes_count; j++)
{ {
// NOTE: JOINTS_1 + WEIGHT_1 will be used for +4 joints influencing a vertex -> Not supported by raylib // NOTE: JOINTS_1 + WEIGHT_1 will be used for +4 joints influencing a vertex -> Not supported by raylib
if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_joints) // JOINTS_n (vec4: 4 bones max per vertex / u8, u16) if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_joints) // JOINTS_n (vec4: 4 bones max per vertex / u8, u16)
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
// NOTE: JOINTS_n can only be vec4 and u8/u16 // NOTE: JOINTS_n can only be vec4 and u8/u16
// SPECS: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview // SPECS: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview
@ -5447,9 +5549,9 @@ static Model LoadGLTF(const char *fileName)
} }
else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported", fileName); else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported", fileName);
} }
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_weights) // WEIGHTS_n (vec4, u8n/u16n/f32) else if (mesh->primitives[p].attributes[j].type == cgltf_attribute_type_weights) // WEIGHTS_n (vec4, u8n/u16n/f32)
{ {
cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; cgltf_accessor *attribute = mesh->primitives[p].attributes[j].data;
if (attribute->type == cgltf_type_vec4) if (attribute->type == cgltf_type_vec4)
{ {
@ -5762,8 +5864,11 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
animDuration = (t > animDuration)? t : animDuration; animDuration = (t > animDuration)? t : animDuration;
} }
strncpy(animations[i].name, animData.name, sizeof(animations[i].name)); if (animData.name != NULL)
animations[i].name[sizeof(animations[i].name) - 1] = '\0'; {
strncpy(animations[i].name, animData.name, sizeof(animations[i].name));
animations[i].name[sizeof(animations[i].name) - 1] = '\0';
}
animations[i].frameCount = (int)(animDuration*1000.0f/GLTF_ANIMDELAY) + 1; animations[i].frameCount = (int)(animDuration*1000.0f/GLTF_ANIMDELAY) + 1;
animations[i].framePoses = RL_MALLOC(animations[i].frameCount*sizeof(Transform *)); animations[i].framePoses = RL_MALLOC(animations[i].frameCount*sizeof(Transform *));
@ -5813,7 +5918,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
BuildPoseFromParentJoints(animations[i].bones, animations[i].boneCount, animations[i].framePoses[j]); BuildPoseFromParentJoints(animations[i].bones, animations[i].boneCount, animations[i].framePoses[j]);
} }
TRACELOG(LOG_INFO, "MODEL: [%s] Loaded animation: %s (%d frames, %fs)", fileName, animData.name, animations[i].frameCount, animDuration); TRACELOG(LOG_INFO, "MODEL: [%s] Loaded animation: %s (%d frames, %fs)", fileName, (animData.name != NULL)? animData.name : "NULL", animations[i].frameCount, animDuration);
RL_FREE(boneChannels); RL_FREE(boneChannels);
} }
} }

View File

@ -126,7 +126,7 @@ Rectangle GetShapesTextureRectangle(void)
// Draw a pixel // Draw a pixel
void DrawPixel(int posX, int posY, Color color) void DrawPixel(int posX, int posY, Color color)
{ {
DrawPixelV((Vector2){ (float)posX, (float)posY }, color); DrawPixelV((Vector2){ (float)posX, (float)posY }, color);
} }
// Draw a pixel (Vector version) // Draw a pixel (Vector version)
@ -178,9 +178,8 @@ void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color colo
{ {
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
// WARNING: Adding 0.5f offset to "center" point on selected pixel rlVertex2f((float)startPosX, (float)startPosY);
rlVertex2f((float)startPosX + 0.5f, (float)startPosY + 0.5f); rlVertex2f((float)endPosX, (float)endPosY);
rlVertex2f((float)endPosX + 0.5f, (float)endPosY + 0.5f);
rlEnd(); rlEnd();
} }
@ -189,14 +188,13 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
{ {
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
// WARNING: Adding 0.5f offset to "center" point on selected pixel rlVertex2f(startPos.x, startPos.y);
rlVertex2f(startPos.x + 0.5f, startPos.y + 0.5f); rlVertex2f(endPos.x, endPos.y);
rlVertex2f(endPos.x + 0.5f, endPos.y + 0.5f);
rlEnd(); rlEnd();
} }
// Draw lines sequuence (using gl lines) // Draw lines sequuence (using gl lines)
void DrawLineStrip(Vector2 *points, int pointCount, Color color) void DrawLineStrip(const Vector2 *points, int pointCount, Color color)
{ {
if (pointCount < 2) return; // Security check if (pointCount < 2) return; // Security check
@ -1385,7 +1383,7 @@ void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
// Draw a triangle fan defined by points // Draw a triangle fan defined by points
// NOTE: First vertex provided is the center, shared by all triangles // NOTE: First vertex provided is the center, shared by all triangles
// By default, following vertex should be provided in counter-clockwise order // By default, following vertex should be provided in counter-clockwise order
void DrawTriangleFan(Vector2 *points, int pointCount, Color color) void DrawTriangleFan(const Vector2 *points, int pointCount, Color color)
{ {
if (pointCount >= 3) if (pointCount >= 3)
{ {
@ -1416,7 +1414,7 @@ void DrawTriangleFan(Vector2 *points, int pointCount, Color color)
// Draw a triangle strip defined by points // Draw a triangle strip defined by points
// NOTE: Every new vertex connects with previous two // NOTE: Every new vertex connects with previous two
void DrawTriangleStrip(Vector2 *points, int pointCount, Color color) void DrawTriangleStrip(const Vector2 *points, int pointCount, Color color)
{ {
if (pointCount >= 3) if (pointCount >= 3)
{ {
@ -1570,7 +1568,7 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw spline: linear, minimum 2 points // Draw spline: linear, minimum 2 points
void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineLinear(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 2) return; if (pointCount < 2) return;
@ -1687,7 +1685,7 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color)
} }
// Draw spline: B-Spline, minimum 4 points // Draw spline: B-Spline, minimum 4 points
void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineBasis(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 4) return; if (pointCount < 4) return;
@ -1759,11 +1757,12 @@ void DrawSplineBasis(Vector2 *points, int pointCount, float thick, Color color)
DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
} }
DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap // Cap circle drawing at the end of every segment
DrawCircleV(currentPoint, thick/2.0f, color);
} }
// Draw spline: Catmull-Rom, minimum 4 points // Draw spline: Catmull-Rom, minimum 4 points
void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineCatmullRom(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 4) return; if (pointCount < 4) return;
@ -1825,28 +1824,31 @@ void DrawSplineCatmullRom(Vector2 *points, int pointCount, float thick, Color co
DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color); DrawTriangleStrip(vertices, 2*SPLINE_SEGMENT_DIVISIONS + 2, color);
} }
DrawCircleV(currentPoint, thick/2.0f, color); // Draw end line circle-cap // Cap circle drawing at the end of every segment
DrawCircleV(currentPoint, thick/2.0f, color);
} }
// Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]
void DrawSplineBezierQuadratic(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineBezierQuadratic(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 3) return; if (pointCount >= 3)
for (int i = 0; i < pointCount - 2; i++)
{ {
DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color); for (int i = 0; i < pointCount - 2; i += 2) DrawSplineSegmentBezierQuadratic(points[i], points[i + 1], points[i + 2], thick, color);
// Cap circle drawing at the end of every segment
//for (int i = 2; i < pointCount - 2; i += 2) DrawCircleV(points[i], thick/2.0f, color);
} }
} }
// Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]
void DrawSplineBezierCubic(Vector2 *points, int pointCount, float thick, Color color) void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, Color color)
{ {
if (pointCount < 4) return; if (pointCount >= 4)
for (int i = 0; i < pointCount - 3; i++)
{ {
DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color); for (int i = 0; i < pointCount - 3; i += 3) DrawSplineSegmentBezierCubic(points[i], points[i + 1], points[i + 2], points[i + 3], thick, color);
// Cap circle drawing at the end of every segment
//for (int i = 3; i < pointCount - 3; i += 3) DrawCircleV(points[i], thick/2.0f, color);
} }
} }
@ -2195,7 +2197,7 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2
// Check if point is within a polygon described by array of vertices // Check if point is within a polygon described by array of vertices
// NOTE: Based on http://jeffreythompson.org/collision-detection/poly-point.php // NOTE: Based on http://jeffreythompson.org/collision-detection/poly-point.php
bool CheckCollisionPointPoly(Vector2 point, Vector2 *points, int pointCount) bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount)
{ {
bool inside = false; bool inside = false;
@ -2233,9 +2235,10 @@ bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, floa
float dx = center2.x - center1.x; // X distance between centers float dx = center2.x - center1.x; // X distance between centers
float dy = center2.y - center1.y; // Y distance between centers float dy = center2.y - center1.y; // Y distance between centers
float distance = sqrtf(dx*dx + dy*dy); // Distance between centers float distanceSquared = dx * dx + dy * dy; // Distance between centers squared
float radiusSum = radius1 + radius2;
if (distance <= (radius1 + radius2)) collision = true; collision = (distanceSquared <= (radiusSum * radiusSum));
return collision; return collision;
} }
@ -2315,6 +2318,30 @@ bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshol
return collision; return collision;
} }
// Check if circle collides with a line created betweeen two points [p1] and [p2]
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2)
{
float dx = p1.x - p2.x;
float dy = p1.y - p2.y;
if ((fabsf(dx) + fabsf(dy)) <= FLT_EPSILON)
{
return CheckCollisionCircles(p1, 0, center, radius);
}
float lengthSQ = ((dx * dx) + (dy * dy));
float dotProduct = (((center.x - p1.x) * (p2.x - p1.x)) + ((center.y - p1.y) * (p2.y - p1.y))) / (lengthSQ);
if (dotProduct > 1.0f) dotProduct = 1.0f;
else if (dotProduct < 0.0f) dotProduct = 0.0f;
float dx2 = (p1.x - (dotProduct * (dx))) - center.x;
float dy2 = (p1.y - (dotProduct * (dy))) - center.y;
float distanceSQ = ((dx2 * dx2) + (dy2 * dy2));
return (distanceSQ <= radius * radius);
}
// Get collision rectangle for two rectangles collision // Get collision rectangle for two rectangles collision
Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2) Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
{ {

View File

@ -362,11 +362,7 @@ Font LoadFont(const char *fileName)
UnloadImage(image); UnloadImage(image);
} }
if (font.texture.id == 0) if (font.texture.id == 0) TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName);
{
TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName);
font = GetFontDefault();
}
else else
{ {
SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); // By default, we set point filter (the best performance) SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); // By default, we set point filter (the best performance)
@ -394,7 +390,6 @@ Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepoi
UnloadFileData(fileData); UnloadFileData(fileData);
} }
else font = GetFontDefault();
return font; return font;
} }
@ -1035,7 +1030,7 @@ bool ExportFontAsCode(Font font, const char *fileName)
// Save font recs data // Save font recs data
byteCount += sprintf(txtData + byteCount, "// Font characters rectangles data\n"); byteCount += sprintf(txtData + byteCount, "// Font characters rectangles data\n");
byteCount += sprintf(txtData + byteCount, "static const Rectangle fontRecs_%s[%i] = {\n", fileNamePascal, font.glyphCount); byteCount += sprintf(txtData + byteCount, "static Rectangle fontRecs_%s[%i] = {\n", fileNamePascal, font.glyphCount);
for (int i = 0; i < font.glyphCount; i++) for (int i = 0; i < font.glyphCount; i++)
{ {
byteCount += sprintf(txtData + byteCount, " { %1.0f, %1.0f, %1.0f , %1.0f },\n", font.recs[i].x, font.recs[i].y, font.recs[i].width, font.recs[i].height); byteCount += sprintf(txtData + byteCount, " { %1.0f, %1.0f, %1.0f , %1.0f },\n", font.recs[i].x, font.recs[i].y, font.recs[i].width, font.recs[i].height);
@ -1047,7 +1042,7 @@ bool ExportFontAsCode(Font font, const char *fileName)
// it could be generated from image and recs // it could be generated from image and recs
byteCount += sprintf(txtData + byteCount, "// Font glyphs info data\n"); byteCount += sprintf(txtData + byteCount, "// Font glyphs info data\n");
byteCount += sprintf(txtData + byteCount, "// NOTE: No glyphs.image data provided\n"); byteCount += sprintf(txtData + byteCount, "// NOTE: No glyphs.image data provided\n");
byteCount += sprintf(txtData + byteCount, "static const GlyphInfo fontGlyphs_%s[%i] = {\n", fileNamePascal, font.glyphCount); byteCount += sprintf(txtData + byteCount, "static GlyphInfo fontGlyphs_%s[%i] = {\n", fileNamePascal, font.glyphCount);
for (int i = 0; i < font.glyphCount; i++) for (int i = 0; i < font.glyphCount; i++)
{ {
byteCount += sprintf(txtData + byteCount, " { %i, %i, %i, %i, { 0 }},\n", font.glyphs[i].value, font.glyphs[i].offsetX, font.glyphs[i].offsetY, font.glyphs[i].advanceX); byteCount += sprintf(txtData + byteCount, " { %i, %i, %i, %i, { 0 }},\n", font.glyphs[i].value, font.glyphs[i].offsetX, font.glyphs[i].offsetY, font.glyphs[i].advanceX);
@ -1786,6 +1781,62 @@ const char *TextToPascal(const char *text)
return buffer; return buffer;
} }
// Get snake case notation version of provided string
// WARNING: Limited functionality, only basic characters set
const char *TextToSnake(const char *text)
{
static char buffer[MAX_TEXT_BUFFER_LENGTH] = {0};
memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH);
if (text != NULL)
{
// Check for next separator to upper case another character
for (int i = 0, j = 0; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[j] != '\0'); i++, j++)
{
if ((text[j] >= 'A') && (text[j] <= 'Z'))
{
if (i >= 1)
{
buffer[i] = '_';
i++;
}
buffer[i] = text[j] + 32;
}
else buffer[i] = text[j];
}
}
return buffer;
}
// Get Camel case notation version of provided string
// WARNING: Limited functionality, only basic characters set
const char *TextToCamel(const char *text)
{
static char buffer[MAX_TEXT_BUFFER_LENGTH] = {0};
memset(buffer, 0, MAX_TEXT_BUFFER_LENGTH);
if (text != NULL)
{
// Lower case first character
if ((text[0] >= 'A') && (text[0] <= 'Z')) buffer[0] = text[0] + 32;
else buffer[0] = text[0];
// Check for next separator to upper case another character
for (int i = 1, j = 1; (i < MAX_TEXT_BUFFER_LENGTH - 1) && (text[j] != '\0'); i++, j++)
{
if (text[j] != '_') buffer[i] = text[j];
else
{
j++;
if ((text[j] >= 'a') && (text[j] <= 'z')) buffer[i] = text[j] - 32;
}
}
}
return buffer;
}
// Encode text codepoint into UTF-8 text // Encode text codepoint into UTF-8 text
// REQUIRES: memcpy() // REQUIRES: memcpy()
// WARNING: Allocated memory must be manually freed // WARNING: Allocated memory must be manually freed
@ -1836,8 +1887,7 @@ int *LoadCodepoints(const char *text, int *count)
} }
// Re-allocate buffer to the actual number of codepoints loaded // Re-allocate buffer to the actual number of codepoints loaded
int *temp = (int *)RL_REALLOC(codepoints, codepointCount*sizeof(int)); codepoints = (int *)RL_REALLOC(codepoints, codepointCount*sizeof(int));
if (temp != NULL) codepoints = temp;
*count = codepointCount; *count = codepointCount;
@ -2242,7 +2292,7 @@ static Font LoadBMFont(const char *fileName)
} }
else else
{ {
font.glyphs[i].image = GenImageColor(font.recs[i].width, font.recs[i].height, BLACK); font.glyphs[i].image = GenImageColor((int)font.recs[i].width, (int)font.recs[i].height, BLACK);
TRACELOG(LOG_WARNING, "FONT: [%s] Some characters data not correctly provided", fileName); TRACELOG(LOG_WARNING, "FONT: [%s] Some characters data not correctly provided", fileName);
} }
} }

View File

@ -2156,8 +2156,9 @@ void ImageBlurGaussian(Image *image, int blurSize)
ImageFormat(image, format); ImageFormat(image, format);
} }
// The kernel matrix is assumed to be square. Only supply the width of the kernel // Apply custom square convolution kernel to image
void ImageKernelConvolution(Image *image, float* kernel, int kernelSize) // NOTE: The convolution kernel matrix is expected to be square
void ImageKernelConvolution(Image *image, const float *kernel, int kernelSize)
{ {
if ((image->data == NULL) || (image->width == 0) || (image->height == 0) || kernel == NULL) return; if ((image->data == NULL) || (image->width == 0) || (image->height == 0) || kernel == NULL) return;
@ -2667,17 +2668,12 @@ void ImageColorTint(Image *image, Color color)
Color *pixels = LoadImageColors(*image); Color *pixels = LoadImageColors(*image);
float cR = (float)color.r/255;
float cG = (float)color.g/255;
float cB = (float)color.b/255;
float cA = (float)color.a/255;
for (int i = 0; i < image->width*image->height; i++) for (int i = 0; i < image->width*image->height; i++)
{ {
unsigned char r = (unsigned char)(((float)pixels[i].r/255*cR)*255.0f); unsigned char r = (unsigned char)(((int)pixels[i].r*(int)color.r)/255);
unsigned char g = (unsigned char)(((float)pixels[i].g/255*cG)*255.0f); unsigned char g = (unsigned char)(((int)pixels[i].g*(int)color.g)/255);
unsigned char b = (unsigned char)(((float)pixels[i].b/255*cB)*255.0f); unsigned char b = (unsigned char)(((int)pixels[i].b*(int)color.b)/255);
unsigned char a = (unsigned char)(((float)pixels[i].a/255*cA)*255.0f); unsigned char a = (unsigned char)(((int)pixels[i].a*(int)color.a)/255);
pixels[i].r = r; pixels[i].r = r;
pixels[i].g = g; pixels[i].g = g;
@ -3408,98 +3404,112 @@ void ImageDrawPixelV(Image *dst, Vector2 position, Color color)
// Draw line within an image // Draw line within an image
void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color) void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color)
{ {
// Using Bresenham's algorithm as described in // Calculate differences in coordinates
// Drawing Lines with Pixels - Joshua Scott - March 2012 int shortLen = endPosY - startPosY;
// https://classic.csunplugged.org/wp-content/uploads/2014/12/Lines.pdf int longLen = endPosX - startPosX;
bool yLonger = false;
int changeInX = (endPosX - startPosX); // Determine if the line is more vertical than horizontal
int absChangeInX = (changeInX < 0)? -changeInX : changeInX; if (abs(shortLen) > abs(longLen))
int changeInY = (endPosY - startPosY);
int absChangeInY = (changeInY < 0)? -changeInY : changeInY;
int startU, startV, endU, stepV; // Substitutions, either U = X, V = Y or vice versa. See loop at end of function
//int endV; // Not needed but left for better understanding, check code below
int A, B, P; // See linked paper above, explained down in the main loop
int reversedXY = (absChangeInY < absChangeInX);
if (reversedXY)
{ {
A = 2*absChangeInY; // Swap the lengths if the line is more vertical
B = A - 2*absChangeInX; int temp = shortLen;
P = A - absChangeInX; shortLen = longLen;
longLen = temp;
yLonger = true;
}
if (changeInX > 0) // Initialize variables for drawing loop
int endVal = longLen;
int sgnInc = 1;
// Adjust direction increment based on longLen sign
if (longLen < 0)
{
longLen = -longLen;
sgnInc = -1;
}
// Calculate fixed-point increment for shorter length
int decInc = (longLen == 0)? 0 : (shortLen<<16) / longLen;
// Draw the line pixel by pixel
if (yLonger)
{
// If line is more vertical, iterate over y-axis
for (int i = 0, j = 0; i != endVal; i += sgnInc, j += decInc)
{ {
startU = startPosX; // Calculate pixel position and draw it
startV = startPosY; ImageDrawPixel(dst, startPosX + (j>>16), startPosY + i, color);
endU = endPosX;
//endV = endPosY;
} }
else
{
startU = endPosX;
startV = endPosY;
endU = startPosX;
//endV = startPosY;
// Since start and end are reversed
changeInX = -changeInX;
changeInY = -changeInY;
}
stepV = (changeInY < 0)? -1 : 1;
ImageDrawPixel(dst, startU, startV, color); // At this point they are correctly ordered...
} }
else else
{ {
A = 2*absChangeInX; // If line is more horizontal, iterate over x-axis
B = A - 2*absChangeInY; for (int i = 0, j = 0; i != endVal; i += sgnInc, j += decInc)
P = A - absChangeInY;
if (changeInY > 0)
{ {
startU = startPosY; // Calculate pixel position and draw it
startV = startPosX; ImageDrawPixel(dst, startPosX + i, startPosY + (j>>16), color);
endU = endPosY;
//endV = endPosX;
} }
else
{
startU = endPosY;
startV = endPosX;
endU = startPosY;
//endV = startPosX;
// Since start and end are reversed
changeInX = -changeInX;
changeInY = -changeInY;
}
stepV = (changeInX < 0)? -1 : 1;
ImageDrawPixel(dst, startV, startU, color); // ... but need to be reversed here. Repeated in the main loop below
}
// We already drew the start point. If we started at startU + 0, the line would be crooked and too short
for (int u = startU + 1, v = startV; u <= endU; u++)
{
if (P >= 0)
{
v += stepV; // Adjusts whenever we stray too far from the direct line. Details in the linked paper above
P += B; // Remembers that we corrected our path
}
else P += A; // Remembers how far we are from the direct line
if (reversedXY) ImageDrawPixel(dst, u, v, color);
else ImageDrawPixel(dst, v, u, color);
} }
} }
// Draw line within an image (Vector version) // Draw line within an image (Vector version)
void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color) void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color)
{ {
ImageDrawLine(dst, (int)start.x, (int)start.y, (int)end.x, (int)end.y, color); // Round start and end positions to nearest integer coordinates
int x1 = (int)(start.x + 0.5f);
int y1 = (int)(start.y + 0.5f);
int x2 = (int)(end.x + 0.5f);
int y2 = (int)(end.y + 0.5f);
// Draw a vertical line using ImageDrawLine function
ImageDrawLine(dst, x1, y1, x2, y2, color);
}
// Draw a line defining thickness within an image
void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color color)
{
// Round start and end positions to nearest integer coordinates
int x1 = (int)(start.x + 0.5f);
int y1 = (int)(start.y + 0.5f);
int x2 = (int)(end.x + 0.5f);
int y2 = (int)(end.y + 0.5f);
// Calculate differences in x and y coordinates
int dx = x2 - x1;
int dy = y2 - y1;
// Draw the main line between (x1, y1) and (x2, y2)
ImageDrawLine(dst, x1, y1, x2, y2, color);
// Determine if the line is more horizontal or vertical
if (dx != 0 && abs(dy/dx) < 1)
{
// Line is more horizontal
// Calculate half the width of the line
int wy = (thick - 1)*sqrtf(dx*dx + dy*dy)/(2*abs(dx));
// Draw additional lines above and below the main line
for (int i = 1; i <= wy; i++)
{
ImageDrawLine(dst, x1, y1 - i, x2, y2 - i, color); // Draw above the main line
ImageDrawLine(dst, x1, y1 + i, x2, y2 + i, color); // Draw below the main line
}
}
else if (dy != 0)
{
// Line is more vertical or perfectly horizontal
// Calculate half the width of the line
int wx = (thick - 1)*sqrtf(dx*dx + dy*dy)/(2*abs(dy));
// Draw additional lines to the left and right of the main line
for (int i = 1; i <= wx; i++)
{
ImageDrawLine(dst, x1 - i, y1, x2 - i, y2, color); // Draw left of the main line
ImageDrawLine(dst, x1 + i, y1, x2 + i, y2, color); // Draw right of the main line
}
}
} }
// Draw circle within an image // Draw circle within an image
@ -3632,6 +3642,194 @@ void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color)
ImageDrawRectangle(dst, (int)rec.x, (int)(rec.y + rec.height - thick), (int)rec.width, thick, color); ImageDrawRectangle(dst, (int)rec.x, (int)(rec.y + rec.height - thick), (int)rec.width, thick, color);
} }
// Draw triangle within an image
void ImageDrawTriangle(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{
// Calculate the 2D bounding box of the triangle
// Determine the minimum and maximum x and y coordinates of the triangle vertices
int xMin = (int)((v1.x < v2.x)? ((v1.x < v3.x) ? v1.x : v3.x) : ((v2.x < v3.x) ? v2.x : v3.x));
int yMin = (int)((v1.y < v2.y)? ((v1.y < v3.y) ? v1.y : v3.y) : ((v2.y < v3.y) ? v2.y : v3.y));
int xMax = (int)((v1.x > v2.x)? ((v1.x > v3.x) ? v1.x : v3.x) : ((v2.x > v3.x) ? v2.x : v3.x));
int yMax = (int)((v1.y > v2.y)? ((v1.y > v3.y) ? v1.y : v3.y) : ((v2.y > v3.y) ? v2.y : v3.y));
// Clamp the bounding box to the image dimensions
if (xMin < 0) xMin = 0;
if (yMin < 0) yMin = 0;
if (xMax > dst->width) xMax = dst->width;
if (yMax > dst->height) yMax = dst->height;
// Check the order of the vertices to determine if it's a front or back face
// NOTE: if signedArea is equal to 0, the face is degenerate
float signedArea = (v2.x - v1.x)*(v3.y - v1.y) - (v3.x - v1.x)*(v2.y - v1.y);
bool isBackFace = (signedArea > 0);
// Barycentric interpolation setup
// Calculate the step increments for the barycentric coordinates
int w1XStep = (int)(v3.y - v2.y), w1YStep = (int)(v2.x - v3.x);
int w2XStep = (int)(v1.y - v3.y), w2YStep = (int)(v3.x - v1.x);
int w3XStep = (int)(v2.y - v1.y), w3YStep = (int)(v1.x - v2.x);
// If the triangle is a back face, invert the steps
if (isBackFace)
{
w1XStep = -w1XStep, w1YStep = -w1YStep;
w2XStep = -w2XStep, w2YStep = -w2YStep;
w3XStep = -w3XStep, w3YStep = -w3YStep;
}
// Calculate the initial barycentric coordinates for the top-left point of the bounding box
int w1Row = (int)((xMin - v2.x)*w1XStep + w1YStep*(yMin - v2.y));
int w2Row = (int)((xMin - v3.x)*w2XStep + w2YStep*(yMin - v3.y));
int w3Row = (int)((xMin - v1.x)*w3XStep + w3YStep*(yMin - v1.y));
// Rasterization loop
// Iterate through each pixel in the bounding box
for (int y = yMin; y <= yMax; y++)
{
int w1 = w1Row;
int w2 = w2Row;
int w3 = w3Row;
for (int x = xMin; x <= xMax; x++)
{
// Check if the pixel is inside the triangle using barycentric coordinates
// If it is then we can draw the pixel with the given color
if ((w1 | w2 | w3) >= 0) ImageDrawPixel(dst, x, y, color);
// Increment the barycentric coordinates for the next pixel
w1 += w1XStep;
w2 += w2XStep;
w3 += w3XStep;
}
// Move to the next row in the bounding box
w1Row += w1YStep;
w2Row += w2YStep;
w3Row += w3YStep;
}
}
// Draw triangle with interpolated colors within an image
void ImageDrawTriangleEx(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color c1, Color c2, Color c3)
{
// Calculate the 2D bounding box of the triangle
// Determine the minimum and maximum x and y coordinates of the triangle vertices
int xMin = (int)((v1.x < v2.x)? ((v1.x < v3.x)? v1.x : v3.x) : ((v2.x < v3.x)? v2.x : v3.x));
int yMin = (int)((v1.y < v2.y)? ((v1.y < v3.y)? v1.y : v3.y) : ((v2.y < v3.y)? v2.y : v3.y));
int xMax = (int)((v1.x > v2.x)? ((v1.x > v3.x)? v1.x : v3.x) : ((v2.x > v3.x)? v2.x : v3.x));
int yMax = (int)((v1.y > v2.y)? ((v1.y > v3.y)? v1.y : v3.y) : ((v2.y > v3.y)? v2.y : v3.y));
// Clamp the bounding box to the image dimensions
if (xMin < 0) xMin = 0;
if (yMin < 0) yMin = 0;
if (xMax > dst->width) xMax = dst->width;
if (yMax > dst->height) yMax = dst->height;
// Check the order of the vertices to determine if it's a front or back face
// NOTE: if signedArea is equal to 0, the face is degenerate
float signedArea = (v2.x - v1.x)*(v3.y - v1.y) - (v3.x - v1.x)*(v2.y - v1.y);
bool isBackFace = (signedArea > 0);
// Barycentric interpolation setup
// Calculate the step increments for the barycentric coordinates
int w1XStep = (int)(v3.y - v2.y), w1YStep = (int)(v2.x - v3.x);
int w2XStep = (int)(v1.y - v3.y), w2YStep = (int)(v3.x - v1.x);
int w3XStep = (int)(v2.y - v1.y), w3YStep = (int)(v1.x - v2.x);
// If the triangle is a back face, invert the steps
if (isBackFace)
{
w1XStep = -w1XStep, w1YStep = -w1YStep;
w2XStep = -w2XStep, w2YStep = -w2YStep;
w3XStep = -w3XStep, w3YStep = -w3YStep;
}
// Calculate the initial barycentric coordinates for the top-left point of the bounding box
int w1Row = (int)((xMin - v2.x)*w1XStep + w1YStep*(yMin - v2.y));
int w2Row = (int)((xMin - v3.x)*w2XStep + w2YStep*(yMin - v3.y));
int w3Row = (int)((xMin - v1.x)*w3XStep + w3YStep*(yMin - v1.y));
// Calculate the inverse of the sum of the barycentric coordinates for normalization
// NOTE 1: Here, we act as if we multiply by 255 the reciprocal, which avoids additional
// calculations in the loop. This is acceptable because we are only interpolating colors.
// NOTE 2: This sum remains constant throughout the triangle
float wInvSum = 255.0f/(w1Row + w2Row + w3Row);
// Rasterization loop
// Iterate through each pixel in the bounding box
for (int y = yMin; y <= yMax; y++)
{
int w1 = w1Row;
int w2 = w2Row;
int w3 = w3Row;
for (int x = xMin; x <= xMax; x++)
{
// Check if the pixel is inside the triangle using barycentric coordinates
if ((w1 | w2 | w3) >= 0)
{
// Compute the normalized barycentric coordinates
unsigned char aW1 = (unsigned char)((float)w1*wInvSum);
unsigned char aW2 = (unsigned char)((float)w2*wInvSum);
unsigned char aW3 = (unsigned char)((float)w3*wInvSum);
// Interpolate the color using the barycentric coordinates
Color finalColor = { 0 };
finalColor.r = (c1.r*aW1 + c2.r*aW2 + c3.r*aW3)/255;
finalColor.g = (c1.g*aW1 + c2.g*aW2 + c3.g*aW3)/255;
finalColor.b = (c1.b*aW1 + c2.b*aW2 + c3.b*aW3)/255;
finalColor.a = (c1.a*aW1 + c2.a*aW2 + c3.a*aW3)/255;
// Draw the pixel with the interpolated color
ImageDrawPixel(dst, x, y, finalColor);
}
// Increment the barycentric coordinates for the next pixel
w1 += w1XStep;
w2 += w2XStep;
w3 += w3XStep;
}
// Move to the next row in the bounding box
w1Row += w1YStep;
w2Row += w2YStep;
w3Row += w3YStep;
}
}
// Draw triangle outline within an image
void ImageDrawTriangleLines(Image *dst, Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{
ImageDrawLine(dst, (int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y, color);
ImageDrawLine(dst, (int)v2.x, (int)v2.y, (int)v3.x, (int)v3.y, color);
ImageDrawLine(dst, (int)v3.x, (int)v3.y, (int)v1.x, (int)v1.y, color);
}
// Draw a triangle fan defined by points within an image (first vertex is the center)
void ImageDrawTriangleFan(Image *dst, Vector2 *points, int pointCount, Color color)
{
if (pointCount >= 3)
{
for (int i = 1; i < pointCount - 1; i++)
{
ImageDrawTriangle(dst, points[0], points[i], points[i + 1], color);
}
}
}
// Draw a triangle strip defined by points within an image
void ImageDrawTriangleStrip(Image *dst, Vector2 *points, int pointCount, Color color)
{
if (pointCount >= 3)
{
for (int i = 2; i < pointCount; i++)
{
if ((i%2) == 0) ImageDrawTriangle(dst, points[i], points[i - 2], points[i - 1], color);
else ImageDrawTriangle(dst, points[i], points[i - 1], points[i - 2], color);
}
}
}
// Draw an image (source) within an image (destination) // Draw an image (source) within an image (destination)
// NOTE: Color tint is applied to source image // NOTE: Color tint is applied to source image
void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint) void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint)
@ -4639,15 +4837,10 @@ Color ColorTint(Color color, Color tint)
{ {
Color result = color; Color result = color;
float cR = (float)tint.r/255; unsigned char r = (unsigned char)(((int)color.r*(int)tint.r)/255);
float cG = (float)tint.g/255; unsigned char g = (unsigned char)(((int)color.g*(int)tint.g)/255);
float cB = (float)tint.b/255; unsigned char b = (unsigned char)(((int)color.b*(int)tint.b)/255);
float cA = (float)tint.a/255; unsigned char a = (unsigned char)(((int)color.a*(int)tint.a)/255);
unsigned char r = (unsigned char)(((float)color.r/255*cR)*255.0f);
unsigned char g = (unsigned char)(((float)color.g/255*cG)*255.0f);
unsigned char b = (unsigned char)(((float)color.b/255*cB)*255.0f);
unsigned char a = (unsigned char)(((float)color.a/255*cA)*255.0f);
result.r = r; result.r = r;
result.g = g; result.g = g;

View File

@ -141,6 +141,11 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB
} }
#output { #output {
border-left: 0px none;
border-right: 0px none;
border-bottom: 0px none;
padding-left: 0;
padding-right: 0;
width: 100%; width: 100%;
height: 140px; height: 140px;
margin: 0 auto; margin: 0 auto;