Merge branch 'raysan5:master' into master

This commit is contained in:
Luiz Pestana 2022-11-26 12:08:41 -03:00 committed by GitHub
commit b572b1e816
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 4197 additions and 1769 deletions

View File

@ -36,7 +36,7 @@ jobs:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Create Build Environment - name: Create Build Environment
# Some projects don't allow in-source building, so create a separate build directory # Some projects don't allow in-source building, so create a separate build directory

View File

@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Setup Environment - name: Setup Environment
run: | run: |

View File

@ -8,13 +8,16 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|:------------------:|:---------------:|:---------:|:----------:|-----------------------------------------------------------| |:------------------:|:---------------:|:---------:|:----------:|-----------------------------------------------------------|
| raylib | **4.2** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib | https://github.com/raysan5/raylib | | raylib | **4.2** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib | https://github.com/raysan5/raylib |
| raylib-boo | 3.7 | [Boo](http://boo-language.github.io/)| MIT | https://github.com/Rabios/raylib-boo | | raylib-boo | 3.7 | [Boo](http://boo-language.github.io/)| MIT | https://github.com/Rabios/raylib-boo |
| Raylib-cs | **4.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib | https://github.com/ChrisDill/Raylib-cs | | Raylib-cs | **4.2** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib | https://github.com/ChrisDill/Raylib-cs |
| Raylib-CsLo | **4.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | https://github.com/NotNotTech/Raylib-CsLo | | Raylib-CsLo | **4.2** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | https://github.com/NotNotTech/Raylib-CsLo |
| cl-raylib | **4.0** | [Common Lisp](https://common-lisp.net/) | MIT | https://github.com/longlene/cl-raylib | | cl-raylib | **4.0** | [Common Lisp](https://common-lisp.net/) | MIT | https://github.com/longlene/cl-raylib |
| raylib-cr | **4.0** | [Crystal](https://crystal-lang.org/) | Apache-2.0 | https://github.com/sol-vin/raylib-cr | | claylib/wrap | **4.2** | [Common Lisp](https://common-lisp.net/) | Zlib | https://github.com/defun-games/claylib |
| chez-raylib | auto | [Chez Scheme](https://cisco.github.io/ChezScheme/) | GPLv3 | https://github.com/Yunoinsky/chez-raylib |
| raylib-cr | **4.5-dev (7e7939e)** | [Crystal](https://crystal-lang.org/) | Apache-2.0 | https://github.com/sol-vin/raylib-cr |
| raylib-c3 | **4.5-dev** | [C3](https://c3-lang.org/) | MIT | https://github.com/Its-Kenta/Raylib-C3 |
| dart-raylib | **4.0** | [Dart](https://dart.dev/) | MIT | https://gitlab.com/wolfenrain/dart-raylib | | dart-raylib | **4.0** | [Dart](https://dart.dev/) | MIT | https://gitlab.com/wolfenrain/dart-raylib |
| bindbc-raylib3 | **4.0** | [D](https://dlang.org/) | BSL-1.0 | https://github.com/o3o/bindbc-raylib3 | | bindbc-raylib3 | **4.0** | [D](https://dlang.org/) | BSL-1.0 | https://github.com/o3o/bindbc-raylib3 |
| dray | **4.0** | [D](https://dlang.org/) | Apache-2.0 | https://github.com/xdrie/dray | | dray | **4.2** | [D](https://dlang.org/) | Apache-2.0 | https://github.com/redthing1/dray |
| raylib-d | **4.2** | [D](https://dlang.org/) | Zlib | https://github.com/schveiguy/raylib-d | | raylib-d | **4.2** | [D](https://dlang.org/) | Zlib | https://github.com/schveiguy/raylib-d |
| dlang_raylib | **4.0** | [D](https://dlang.org) | MPL-2.0 |https://github.com/rc-05/dlang_raylib | | dlang_raylib | **4.0** | [D](https://dlang.org) | MPL-2.0 |https://github.com/rc-05/dlang_raylib |
| rayex | 3.7 | [elixir](https://elixir-lang.org/) | Apache-2.0 | https://github.com/shiryel/rayex | | rayex | 3.7 | [elixir](https://elixir-lang.org/) | Apache-2.0 | https://github.com/shiryel/rayex |
@ -23,6 +26,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| raylib-go | **4.2** | [Go](https://golang.org/) | Zlib | https://github.com/gen2brain/raylib-go | | raylib-go | **4.2** | [Go](https://golang.org/) | Zlib | https://github.com/gen2brain/raylib-go |
| raylib-guile | auto | [Guile](https://www.gnu.org/software/guile/) | Zlib | https://github.com/petelliott/raylib-guile | | raylib-guile | auto | [Guile](https://www.gnu.org/software/guile/) | Zlib | https://github.com/petelliott/raylib-guile |
| gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | MIT | https://github.com/ArnautDaniel/gforth-raylib | | gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | MIT | https://github.com/ArnautDaniel/gforth-raylib |
| h-raylib | 4.5-dev | [Haskell](https://haskell.org/) | Apache-2.0 | https://github.com/Anut-py/h-raylib |
| raylib-hx | 4.0 | [Haxe](https://haxe.org/) | Zlib | https://github.com/foreignsasquatch/raylib-hx | | raylib-hx | 4.0 | [Haxe](https://haxe.org/) | Zlib | https://github.com/foreignsasquatch/raylib-hx |
| hb-raylib | 3.5 | [Harbour](https://harbour.github.io) | MIT | https://github.com/MarcosLeonardoMendezGerencir/hb-raylib | | hb-raylib | 3.5 | [Harbour](https://harbour.github.io) | MIT | https://github.com/MarcosLeonardoMendezGerencir/hb-raylib |
| jaylib | **4.2** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | https://github.com/electronstudio/jaylib/ | | jaylib | **4.2** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | https://github.com/electronstudio/jaylib/ |
@ -43,6 +47,9 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| Raylib.4.0.Pascal | **4.0** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)| Zlib | https://github.com/sysrpl/Raylib.4.0.Pascal | | Raylib.4.0.Pascal | **4.0** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)| Zlib | https://github.com/sysrpl/Raylib.4.0.Pascal |
| pyraylib | 3.7 | [Python](https://www.python.org/) | Zlib | https://github.com/Ho011/pyraylib | | pyraylib | 3.7 | [Python](https://www.python.org/) | Zlib | https://github.com/Ho011/pyraylib |
| raylib-python-cffi | **4.2** | [Python](https://www.python.org/) | EPL-2.0 | https://github.com/electronstudio/raylib-python-cffi | | raylib-python-cffi | **4.2** | [Python](https://www.python.org/) | EPL-2.0 | https://github.com/electronstudio/raylib-python-cffi |
| raylibpyctbg | **4.2** | [Python](https://www.python.org/) | MIT | https://github.com/overdev/raylibpyctbg |
| raylib-py | **4.2** | [Python](https://www.python.org/) | MIT | https://github.com/overdev/raylib-py |
| raylib-python-ctypes | **4.2** | [Python](https://www.python.org/) | MIT | https://github.com/sDos280/raylib-python-ctypes |
| raylib-php | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/joseph-montanez/raylib-php | | raylib-php | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/joseph-montanez/raylib-php |
| raylib-phpcpp | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/oraoto/raylib-phpcpp | | raylib-phpcpp | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/oraoto/raylib-phpcpp |
| raylibr | **4.0** | [R](https://www.r-project.org) | MIT | https://github.com/jeroenjanssens/raylibr | | raylibr | **4.0** | [R](https://www.r-project.org) | MIT | https://github.com/jeroenjanssens/raylibr |
@ -52,7 +59,9 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| raylib-swift | **4.0** | [Swift](https://swift.org/) | MIT | https://github.com/STREGAsGate/Raylib | | raylib-swift | **4.0** | [Swift](https://swift.org/) | MIT | https://github.com/STREGAsGate/Raylib |
| raylib-scopes | auto | [Scopes](http://scopes.rocks) | MIT | https://github.com/salotz/raylib-scopes | | raylib-scopes | auto | [Scopes](http://scopes.rocks) | MIT | https://github.com/salotz/raylib-scopes |
| raylib-smallBasic | 4.1-dev | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 | https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib | | raylib-smallBasic | 4.1-dev | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 | https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib |
| raylib-umka | **4.2** | [Umka](https://github.com/vtereshkov/umka-lang) | Zlib | https://github.com/robloach/raylib-umka |
| raylib.v | **4.2** | [V](https://vlang.io/) | Zlib | https://github.com/irishgreencitrus/raylib.v | | raylib.v | **4.2** | [V](https://vlang.io/) | Zlib | https://github.com/irishgreencitrus/raylib.v |
| raylib-vapi | **4.2** | [Vala](https://vala.dev/) | Zlib | https://github.com/lxmcf/raylib-vapi |
| raylib-wren | **4.0** | [Wren](http://wren.io/) | ISC | https://github.com/TSnake41/raylib-wren | | raylib-wren | **4.0** | [Wren](http://wren.io/) | ISC | https://github.com/TSnake41/raylib-wren |
| raylib-zig | **4.2** | [Zig](https://ziglang.org/) | MIT | https://github.com/Not-Nik/raylib-zig | | raylib-zig | **4.2** | [Zig](https://ziglang.org/) | MIT | https://github.com/Not-Nik/raylib-zig |
| raylib.zig | **4.2** | [Zig](https://ziglang.org/) | MIT | https://github.com/ryupold/raylib.zig | | raylib.zig | **4.2** | [Zig](https://ziglang.org/) | MIT | https://github.com/ryupold/raylib.zig |
@ -65,6 +74,7 @@ These are utility wrappers for specific languages, they are not required to use
| name | raylib version | language | license | repo | | name | raylib version | language | license | repo |
|:------------------:|:-------------: | :--------:|:-------:|:-------------------------------------------------------------| |:------------------:|:-------------: | :--------:|:-------:|:-------------------------------------------------------------|
| raylib-cpp | **4.2** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib | https://github.com/robloach/raylib-cpp | | raylib-cpp | **4.2** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib | https://github.com/robloach/raylib-cpp |
| claylib | **4.2** | [Common Lisp](https://common-lisp.net/) | Zlib | https://github.com/defun-games/claylib |
### Older or Unmaintained Language Bindings ### Older or Unmaintained Language Bindings
These are older raylib bindings that are more than 2 versions old or have not been maintained. These are older raylib bindings that are more than 2 versions old or have not been maintained.
@ -96,8 +106,6 @@ These are older raylib bindings that are more than 2 versions old or have not be
| raylib-ruby | 2.6 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/a0/raylib-ruby | | raylib-ruby | 2.6 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/a0/raylib-ruby |
| raylib-ruby-ffi | 2.0 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/D3nX/raylib-ruby-ffi | | raylib-ruby-ffi | 2.0 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/D3nX/raylib-ruby-ffi |
| raylib-mruby | 2.5-dev | [mruby](https://github.com/mruby/mruby) | https://github.com/lihaochen910/raylib-mruby | | raylib-mruby | 2.5-dev | [mruby](https://github.com/mruby/mruby) | https://github.com/lihaochen910/raylib-mruby |
| raylib-py-ctbg | 2.6 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py-ctbg |
| raylib-py | 2.0 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py |
| raylib-java | 2.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/XoanaIO/raylib-java | | raylib-java | 2.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/XoanaIO/raylib-java |
| clj-raylib | 3.0 | [Clojure](https://clojure.org/) | https://github.com/lsevero/clj-raylib | | clj-raylib | 3.0 | [Clojure](https://clojure.org/) | https://github.com/lsevero/clj-raylib |
| QuickJS-raylib | 3.0 | [QuickJS](https://bellard.org/quickjs/) | https://github.com/sntg-p/QuickJS-raylib | | QuickJS-raylib | 3.0 | [QuickJS](https://bellard.org/quickjs/) | https://github.com/sntg-p/QuickJS-raylib |

0
CMakeLists.txt Executable file → Normal file
View File

View File

@ -25,6 +25,7 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
[![GitHub Releases Downloads](https://img.shields.io/github/downloads/raysan5/raylib/total)](https://github.com/raysan5/raylib/releases) [![GitHub Releases Downloads](https://img.shields.io/github/downloads/raysan5/raylib/total)](https://github.com/raysan5/raylib/releases)
[![GitHub Stars](https://img.shields.io/github/stars/raysan5/raylib?style=flat&label=stars)](https://github.com/raysan5/raylib/stargazers) [![GitHub Stars](https://img.shields.io/github/stars/raysan5/raylib?style=flat&label=stars)](https://github.com/raysan5/raylib/stargazers)
[![GitHub commits since tagged version](https://img.shields.io/github/commits-since/raysan5/raylib/4.2.0)](https://github.com/raysan5/raylib/commits/master) [![GitHub commits since tagged version](https://img.shields.io/github/commits-since/raysan5/raylib/4.2.0)](https://github.com/raysan5/raylib/commits/master)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/raysan5?label=sponsors)](https://github.com/sponsors/raysan5)
[![Packaging Status](https://repology.org/badge/tiny-repos/raylib.svg)](https://repology.org/project/raylib/versions) [![Packaging Status](https://repology.org/badge/tiny-repos/raylib.svg)](https://repology.org/project/raylib/versions)
[![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE) [![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE)

View File

@ -45,7 +45,6 @@ elseif (${PLATFORM} MATCHES "Android")
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2") set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON)
list(APPEND raylib_sources ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) list(APPEND raylib_sources ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
add_definitions(-DANDROID -D__ANDROID_API__=21)
include_directories(${ANDROID_NDK}/sources/android/native_app_glue) include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup")

View File

@ -357,7 +357,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
LDLIBS += -lc LDLIBS += -lc
endif endif
# TODO: On ARM 32bit arch, miniaudio requires atomics library # NOTE: On ARM 32bit arch, miniaudio requires atomics library
LDLIBS += -latomic LDLIBS += -latomic
endif endif
ifeq ($(PLATFORM_OS),OSX) ifeq ($(PLATFORM_OS),OSX)

View File

@ -48,7 +48,7 @@ ifeq ($(ANDROID_ARCH),ARM64)
ANDROID_ARCH_NAME = arm64-v8a ANDROID_ARCH_NAME = arm64-v8a
endif endif
ifeq ($(ANDROID_ARCH),x86) ifeq ($(ANDROID_ARCH),x86)
ANDROID_ARCH_NAME = i686 ANDROID_ARCH_NAME = x86
endif endif
ifeq ($(ANDROID_ARCH),x86_64) ifeq ($(ANDROID_ARCH),x86_64)
ANDROID_ARCH_NAME = x86_64 ANDROID_ARCH_NAME = x86_64

View File

@ -279,11 +279,12 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# -s ASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS # -s ASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS
# -s FORCE_FILESYSTEM=1 # force filesystem to load/save files data # -s FORCE_FILESYSTEM=1 # force filesystem to load/save files data
# -s ASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off) # -s ASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off)
# -s EXPORTED_RUNTIME_METHODS=ccall # require exporting some LEGACY_RUNTIME functions, ccall() is required by miniaudio
# --profiling # include information for code profiling # --profiling # include information for code profiling
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem) # --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
# --preload-file resources # specify a resources folder for data compilation # --preload-file resources # specify a resources folder for data compilation
# --source-map-base # allow debugging in browser with source map # --source-map-base # allow debugging in browser with source map
LDFLAGS += -s USE_GLFW=3 -s ASYNCIFY LDFLAGS += -s USE_GLFW=3 -s ASYNCIFY -s EXPORTED_RUNTIME_METHODS=ccall
# NOTE: Simple raylib examples are compiled to be interpreter with asyncify, that way, # NOTE: Simple raylib examples are compiled to be interpreter with asyncify, that way,
# we can compile same code for ALL platforms with no change required, but, working on bigger # we can compile same code for ALL platforms with no change required, but, working on bigger
@ -328,6 +329,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(RAYLIB_LIBTYPE),SHARED) ifeq ($(RAYLIB_LIBTYPE),SHARED)
LDLIBS += -lc LDLIBS += -lc
endif endif
# NOTE: On ARM 32bit arch, miniaudio requires atomics library
LDLIBS += -latomic
endif endif
ifeq ($(PLATFORM_OS),OSX) ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling # Libraries for OSX 10.9 desktop compiling
@ -466,6 +470,7 @@ MODELS = \
models/models_loading \ models/models_loading \
models/models_loading_vox \ models/models_loading_vox \
models/models_loading_gltf \ models/models_loading_gltf \
models/models_loading_m3d \
models/models_orthographic_projection \ models/models_orthographic_projection \
models/models_rlgl_solar_system \ models/models_rlgl_solar_system \
models/models_skybox \ models/models_skybox \

View File

@ -34,7 +34,7 @@ int main(void)
float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f] float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f]
bool pause = false; // Music playing paused bool pause = false; // Music playing paused
SetTargetFPS(30); // Set our game to run at 60 frames-per-second SetTargetFPS(30); // Set our game to run at 30 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Main game loop // Main game loop
@ -95,4 +95,4 @@ int main(void)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -35,16 +35,16 @@ fn add_module(comptime module: []const u8, b: *std.build.Builder, target: std.zi
else => @panic("Unsupported OS"), else => @panic("Unsupported OS"),
}); });
exe.addIncludeDir("../src"); exe.addIncludePath("../src");
exe.addIncludeDir("../src/external"); exe.addIncludePath("../src/external");
exe.addIncludeDir("../src/external/glfw/include"); exe.addIncludePath("../src/external/glfw/include");
switch (exe.target.toTarget().os.tag) { switch (exe.target.toTarget().os.tag) {
.windows => { .windows => {
exe.linkSystemLibrary("winmm"); exe.linkSystemLibrary("winmm");
exe.linkSystemLibrary("gdi32"); exe.linkSystemLibrary("gdi32");
exe.linkSystemLibrary("opengl32"); exe.linkSystemLibrary("opengl32");
exe.addIncludeDir("external/glfw/deps/mingw"); exe.addIncludePath("external/glfw/deps/mingw");
}, },
.linux => { .linux => {
exe.linkSystemLibrary("GL"); exe.linkSystemLibrary("GL");

View File

@ -13,7 +13,7 @@
* Enjoy using raylib. :) * Enjoy using raylib. :)
* *
* Example originally created with raylib 1.0, last time updated with raylib 1.0 * Example originally created with raylib 1.0, last time updated with raylib 1.0
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software * BSD-like license that allows static linking with closed source software
* *

View File

@ -15,7 +15,6 @@
#include "raylib.h" #include "raylib.h"
Texture2D textureGrid = { 0 };
Camera cameraPlayer1 = { 0 }; Camera cameraPlayer1 = { 0 };
Camera cameraPlayer2 = { 0 }; Camera cameraPlayer2 = { 0 };
@ -32,8 +31,8 @@ void DrawScene(void)
{ {
for (float z = -count*spacing; z <= count*spacing; z += spacing) for (float z = -count*spacing; z <= count*spacing; z += spacing)
{ {
DrawCubeTexture(textureGrid, (Vector3) { x, 1.5f, z }, 1, 1, 1, GREEN); DrawCube((Vector3) { x, 1.5f, z }, 1, 1, 1, LIME);
DrawCubeTexture(textureGrid, (Vector3) { x, 0.5f, z }, 0.25f, 1, 0.25f, BROWN); DrawCube((Vector3) { x, 0.5f, z }, 0.25f, 1, 0.25f, BROWN);
} }
} }
@ -54,13 +53,6 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [core] example - split screen"); InitWindow(screenWidth, screenHeight, "raylib [core] example - split screen");
// Generate a simple texture to use for trees
Image img = GenImageChecked(256, 256, 32, 32, DARKGRAY, WHITE);
textureGrid = LoadTextureFromImage(img);
UnloadImage(img);
SetTextureFilter(textureGrid, TEXTURE_FILTER_ANISOTROPIC_16X);
SetTextureWrap(textureGrid, TEXTURE_WRAP_CLAMP);
// Setup player 1 camera and screen // Setup player 1 camera and screen
cameraPlayer1.fovy = 45.0f; cameraPlayer1.fovy = 45.0f;
cameraPlayer1.up.y = 1.0f; cameraPlayer1.up.y = 1.0f;
@ -151,7 +143,6 @@ int main(void)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
UnloadRenderTexture(screenPlayer1); // Unload render texture UnloadRenderTexture(screenPlayer1); // Unload render texture
UnloadRenderTexture(screenPlayer2); // Unload render texture UnloadRenderTexture(screenPlayer2); // Unload render texture
UnloadTexture(textureGrid); // Unload texture
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

View File

@ -12,6 +12,7 @@
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include "raymath.h"
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
@ -33,11 +34,28 @@ int main(void)
camera.fovy = 45.0f; camera.fovy = 45.0f;
camera.projection = CAMERA_PERSPECTIVE; camera.projection = CAMERA_PERSPECTIVE;
Texture2D bill = LoadTexture("resources/billboard.png"); // Our texture billboard Texture2D bill = LoadTexture("resources/billboard.png"); // Our billboard texture
Vector3 billPosition = { 0.0f, 2.0f, 0.0f }; // Position where draw billboard Vector3 billPositionStatic = { 0.0f, 2.0f, 0.0f }; // Position of billboard
Vector3 billPositionRotating = { 1.0f, 2.0f, 1.0f };
// Entire billboard texture, source is used to take a segment from a larger texture.
Rectangle source = { 0.0f, 0.0f, (float)bill.width, (float)bill.height };
// NOTE: Billboard locked on axis-Y
Vector3 billUp = { 0.0f, 1.0f, 0.0f };
// Rotate around origin
// Here we choose to rotate around the image center
// NOTE: (-1, 1) is the range where origin.x, origin.y is inside the texture
Vector2 rotateOrigin = { 0.0f };
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
// Distance is needed for the correct billboard draw order
// Larger distance (further away from the camera) should be drawn prior to smaller distance.
float distanceStatic;
float distanceRotating;
float rotation = 0.0f;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -47,6 +65,9 @@ int main(void)
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
UpdateCamera(&camera); UpdateCamera(&camera);
rotation += 0.4f;
distanceStatic = Vector3Distance(camera.position, billPositionStatic);
distanceRotating = Vector3Distance(camera.position, billPositionRotating);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -59,8 +80,18 @@ int main(void)
DrawGrid(10, 1.0f); // Draw a grid DrawGrid(10, 1.0f); // Draw a grid
DrawBillboard(camera, bill, billPosition, 2.0f, WHITE); // Draw order matters!
if (distanceStatic > distanceRotating)
{
DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE);
DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, (Vector2) {1.0f, 1.0f}, rotateOrigin, rotation, WHITE);
}
else
{
DrawBillboardPro(camera, bill, source, billPositionRotating, billUp, (Vector2) {1.0f, 1.0f}, rotateOrigin, rotation, WHITE);
DrawBillboard(camera, bill, billPositionStatic, 2.0f, WHITE);
}
EndMode3D(); EndMode3D();
DrawFPS(10, 10); DrawFPS(10, 10);

View File

@ -0,0 +1,245 @@
/*******************************************************************************************
*
* raylib [models] example - Draw textured cube
*
* Example originally created with raylib 4.5, last time updated with raylib 4.5
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2022 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "rlgl.h" // Required to define vertex data (immediate-mode style)
//------------------------------------------------------------------------------------
// Custom Functions Declaration
//------------------------------------------------------------------------------------
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured
void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color); // Draw cube with a region of a texture
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - draw cube texture");
// Define the camera to look into our 3d world
Camera camera = { 0 };
camera.position = (Vector3){ 0.0f, 10.0f, 10.0f };
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
camera.fovy = 45.0f;
camera.projection = CAMERA_PERSPECTIVE;
// Load texture to be applied to the cubes sides
Texture2D texture = LoadTexture("resources/cubicmap_atlas.png");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(camera);
// Draw cube with an applied texture
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
DrawCubeTextureRec(texture, (Rectangle){ 0, texture.height/2, texture.width/2, texture.height/2 },
(Vector3){ 2.0f, 1.0f, 0.0f }, 2.0f, 2.0f, 2.0f, WHITE);
DrawGrid(10, 1.0f); // Draw a grid
EndMode3D();
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texture); // Unload texture
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Custom Functions Definition
//------------------------------------------------------------------------------------
// Draw cube textured
// NOTE: Cube position is the center position
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color)
{
float x = position.x;
float y = position.y;
float z = position.z;
// Set desired texture to be enabled while drawing following vertex data
rlSetTexture(texture.id);
// Vertex data transformation can be defined with the commented lines,
// but in this example we calculate the transformed vertex data directly when calling rlVertex3f()
//rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
//rlTranslatef(2.0f, 0.0f, 0.0f);
//rlRotatef(45, 0, 1, 0);
//rlScalef(2.0f, 2.0f, 2.0f);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad
// Back Face
rlNormal3f(0.0f, 0.0f, - 1.0f); // Normal Pointing Away From Viewer
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad
// Top Face
rlNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
// Bottom Face
rlNormal3f(0.0f, - 1.0f, 0.0f); // Normal Pointing Down
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
// Right face
rlNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
// Left Face
rlNormal3f( - 1.0f, 0.0f, 0.0f); // Normal Pointing Left
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
rlEnd();
//rlPopMatrix();
rlSetTexture(0);
}
// Draw cube with texture piece applied to all faces
void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color)
{
float x = position.x;
float y = position.y;
float z = position.z;
float texWidth = (float)texture.width;
float texHeight = (float)texture.height;
// Set desired texture to be enabled while drawing following vertex data
rlSetTexture(texture.id);
// We calculate the normalized texture coordinates for the desired texture-source-rectangle
// It means converting from (tex.width, tex.height) coordinates to [0.0f, 1.0f] equivalent
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front face
rlNormal3f(0.0f, 0.0f, 1.0f);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z + length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z + length/2);
// Back face
rlNormal3f(0.0f, 0.0f, - 1.0f);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z - length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z - length/2);
// Top face
rlNormal3f(0.0f, 1.0f, 0.0f);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y + height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y + height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z - length/2);
// Bottom face
rlNormal3f(0.0f, - 1.0f, 0.0f);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y - height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y - height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z + length/2);
// Right face
rlNormal3f(1.0f, 0.0f, 0.0f);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z - length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z + length/2);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z + length/2);
// Left face
rlNormal3f( - 1.0f, 0.0f, 0.0f);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z - length/2);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z + length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z - length/2);
rlEnd();
rlSetTexture(0);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -66,6 +66,9 @@ int main(void)
DrawCylinder((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, GOLD); DrawCylinder((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, GOLD);
DrawCylinderWires((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, PINK); DrawCylinderWires((Vector3){1.0f, 0.0f, -4.0f}, 0.0f, 1.5f, 3.0f, 8, PINK);
DrawCapsule ((Vector3){-3.0f, 1.5f, -4.0f}, (Vector3){-4.0f, -1.0f, -4.0f}, 1.2f, 8, 8, VIOLET);
DrawCapsuleWires((Vector3){-3.0f, 1.5f, -4.0f}, (Vector3){-4.0f, -1.0f, -4.0f}, 1.2f, 8, 8, PURPLE);
DrawGrid(10, 1.0f); // Draw a grid DrawGrid(10, 1.0f); // Draw a grid
EndMode3D(); EndMode3D();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -51,7 +51,7 @@ int main(void)
DrawCircleGradient(screenWidth/5, 220, 60, GREEN, SKYBLUE); DrawCircleGradient(screenWidth/5, 220, 60, GREEN, SKYBLUE);
DrawCircleLines(screenWidth/5, 340, 80, DARKBLUE); DrawCircleLines(screenWidth/5, 340, 80, DARKBLUE);
// Rectangle shapes and ines // Rectangle shapes and lines
DrawRectangle(screenWidth/4*2 - 60, 100, 120, 60, RED); DrawRectangle(screenWidth/4*2 - 60, 100, 120, 60, RED);
DrawRectangleGradientH(screenWidth/4*2 - 90, 170, 180, 130, MAROON, GOLD); DrawRectangleGradientH(screenWidth/4*2 - 90, 170, 180, 130, MAROON, GOLD);
DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE); // NOTE: Uses QUADS internally, not lines DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE); // NOTE: Uses QUADS internally, not lines
@ -83,4 +83,4 @@ int main(void)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -263,6 +263,6 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec,
} }
} }
textOffsetX += glyphWidth; if ((textOffsetX != 0) || (codepoint != ' ')) textOffsetX += glyphWidth; // avoid leading spaces
} }
} }

View File

@ -20,6 +20,9 @@
#define MARGIN_SIZE 8 // Size for the margins #define MARGIN_SIZE 8 // Size for the margins
#define COLOR_SIZE 16 // Size of the color select buttons #define COLOR_SIZE 16 // Size of the color select buttons
// Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest.
void DrawTextureTiled(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -168,3 +171,86 @@ int main(void)
return 0; return 0;
} }
// Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest.
void DrawTextureTiled(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint)
{
if ((texture.id <= 0) || (scale <= 0.0f)) return; // Wanna see a infinite loop?!...just delete this line!
if ((source.width == 0) || (source.height == 0)) return;
int tileWidth = (int)(source.width*scale), tileHeight = (int)(source.height*scale);
if ((dest.width < tileWidth) && (dest.height < tileHeight))
{
// Can fit only one tile
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)dest.width/tileWidth)*source.width, ((float)dest.height/tileHeight)*source.height},
(Rectangle){dest.x, dest.y, dest.width, dest.height}, origin, rotation, tint);
}
else if (dest.width <= tileWidth)
{
// Tiled vertically (one column)
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)dest.width/tileWidth)*source.width, source.height}, (Rectangle){dest.x, dest.y + dy, dest.width, (float)tileHeight}, origin, rotation, tint);
}
// Fit last tile
if (dy < dest.height)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)dest.width/tileWidth)*source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
(Rectangle){dest.x, dest.y + dy, dest.width, dest.height - dy}, origin, rotation, tint);
}
}
else if (dest.height <= tileHeight)
{
// Tiled horizontally (one row)
int dx = 0;
for (;dx+tileWidth < dest.width; dx += tileWidth)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, source.width, ((float)dest.height/tileHeight)*source.height}, (Rectangle){dest.x + dx, dest.y, (float)tileWidth, dest.height}, origin, rotation, tint);
}
// Fit last tile
if (dx < dest.width)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, ((float)dest.height/tileHeight)*source.height},
(Rectangle){dest.x + dx, dest.y, dest.width - dx, dest.height}, origin, rotation, tint);
}
}
else
{
// Tiled both horizontally and vertically (rows and columns)
int dx = 0;
for (;dx+tileWidth < dest.width; dx += tileWidth)
{
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, source, (Rectangle){dest.x + dx, dest.y + dy, (float)tileWidth, (float)tileHeight}, origin, rotation, tint);
}
if (dy < dest.height)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
(Rectangle){dest.x + dx, dest.y + dy, (float)tileWidth, dest.height - dy}, origin, rotation, tint);
}
}
// Fit last column of tiles
if (dx < dest.width)
{
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, source.height},
(Rectangle){dest.x + dx, dest.y + dy, dest.width - dx, (float)tileHeight}, origin, rotation, tint);
}
// Draw final tile in the bottom right corner
if (dy < dest.height)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
(Rectangle){dest.x + dx, dest.y + dy, dest.width - dx, dest.height - dy}, origin, rotation, tint);
}
}
}
}

View File

@ -17,7 +17,7 @@
#include <stdlib.h> // Required for: free() #include <stdlib.h> // Required for: free()
#define NUM_PROCESSES 8 #define NUM_PROCESSES 9
typedef enum { typedef enum {
NONE = 0, NONE = 0,
@ -26,6 +26,7 @@ typedef enum {
COLOR_INVERT, COLOR_INVERT,
COLOR_CONTRAST, COLOR_CONTRAST,
COLOR_BRIGHTNESS, COLOR_BRIGHTNESS,
GAUSSIAN_BLUR,
FLIP_VERTICAL, FLIP_VERTICAL,
FLIP_HORIZONTAL FLIP_HORIZONTAL
} ImageProcess; } ImageProcess;
@ -37,6 +38,7 @@ static const char *processText[] = {
"COLOR INVERT", "COLOR INVERT",
"COLOR CONTRAST", "COLOR CONTRAST",
"COLOR BRIGHTNESS", "COLOR BRIGHTNESS",
"GAUSSIAN BLUR",
"FLIP VERTICAL", "FLIP VERTICAL",
"FLIP HORIZONTAL" "FLIP HORIZONTAL"
}; };
@ -125,6 +127,7 @@ int main(void)
case COLOR_INVERT: ImageColorInvert(&imCopy); break; case COLOR_INVERT: ImageColorInvert(&imCopy); break;
case COLOR_CONTRAST: ImageColorContrast(&imCopy, -40); break; case COLOR_CONTRAST: ImageColorContrast(&imCopy, -40); break;
case COLOR_BRIGHTNESS: ImageColorBrightness(&imCopy, -80); break; case COLOR_BRIGHTNESS: ImageColorBrightness(&imCopy, -80); break;
case GAUSSIAN_BLUR: ImageBlurGaussian(&imCopy, 10); break;
case FLIP_VERTICAL: ImageFlipVertical(&imCopy); break; case FLIP_VERTICAL: ImageFlipVertical(&imCopy); break;
case FLIP_HORIZONTAL: ImageFlipHorizontal(&imCopy); break; case FLIP_HORIZONTAL: ImageFlipHorizontal(&imCopy); break;
default: break; default: break;

View File

@ -14,10 +14,15 @@
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include "rlgl.h" // Required for: Vertex definition
#include "raymath.h" #include "raymath.h"
#define MAX_POINTS 11 // 10 points and back to the start #define MAX_POINTS 11 // 10 points and back to the start
// Draw textured polygon, defined by vertex and texture coordinates
void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointCount, Color tint);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Program main entry point // Program main entry point
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -102,3 +107,34 @@ int main(void)
return 0; return 0;
} }
// Draw textured polygon, defined by vertex and texture coordinates
// NOTE: Polygon center must have straight line path to all points
// without crossing perimeter, points must be in anticlockwise order
void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointCount, Color tint)
{
rlSetTexture(texture.id);
// Texturing is only supported on RL_QUADS
rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
for (int i = 0; i < pointCount - 1; i++)
{
rlTexCoord2f(0.5f, 0.5f);
rlVertex2f(center.x, center.y);
rlTexCoord2f(texcoords[i].x, texcoords[i].y);
rlVertex2f(points[i].x + center.x, points[i].y + center.y);
rlTexCoord2f(texcoords[i + 1].x, texcoords[i + 1].y);
rlVertex2f(points[i + 1].x + center.x, points[i + 1].y + center.y);
rlTexCoord2f(texcoords[i + 1].x, texcoords[i + 1].y);
rlVertex2f(points[i + 1].x + center.x, points[i + 1].y + center.y);
}
rlEnd();
rlSetTexture(0);
}

View File

@ -1,28 +1,50 @@
EXTENSION?=txt EXTENSION?=txt
FORMAT?=DEFAULT FORMAT?=DEFAULT
.PHONY: all parse clean raylib_api
raylib_api:
cc raylib_parser.c -o raylib_parser
./raylib_parser -i ../src/raylib.h -o raylib_api.txt -f DEFAULT -d RLAPI
./raylib_parser -i ../src/raylib.h -o raylib_api.json -f JSON -d RLAPI
./raylib_parser -i ../src/raylib.h -o raylib_api.xml -f XML -d RLAPI
./raylib_parser -i ../src/raylib.h -o raylib_api.lua -f LUA -d RLAPI
all: raylib_parser: raylib_parser.c
cc raylib_parser.c -o raylib_parser cc raylib_parser.c -o raylib_parser
raylib_api: ../src/raylib.h raylib_parser
FORMAT=DEFAULT EXTENSION=txt $(MAKE) raylib_api.txt
FORMAT=JSON EXTENSION=json $(MAKE) raylib_api.json
FORMAT=XML EXTENSION=xml $(MAKE) raylib_api.xml
FORMAT=LUA EXTENSION=lua $(MAKE) raylib_api.lua
raylib_api.$(EXTENSION): ../src/raylib.h raylib_parser
./raylib_parser -i ../src/raylib.h -o raylib_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
raymath_api.$(EXTENSION): ../src/raymath.h raylib_parser
./raylib_parser -i ../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
rlgl_api.$(EXTENSION): ../src/rlgl.h raylib_parser
./raylib_parser -i ../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI -t "RLGL IMPLEMENTATION"
reasings_api.$(EXTENSION): ../examples/others/reasings.h raylib_parser
./raylib_parser -i ../examples/others/reasings.h -o reasings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
rmem_api.$(EXTENSION): ../rmem.h raylib_parser
./raylib_parser -i ../rmem.h -o rmem_api.$(EXTENSION) -f $(FORMAT) -d RMEMAPI -t "RMEM IMPLEMENTATION"
physac_api.$(EXTENSION): ../physac.h raylib_parser
./raylib_parser -i ../physac.h -o physac_api.$(EXTENSION) -f $(FORMAT) -d PHYSACDEF -t "PHYSAC IMPLEMENTATION"
raygui_api.$(EXTENSION): ../raygui.h raylib_parser
./raylib_parser -i ../raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI -t "RAYGUI IMPLEMENTATION"
parse: raylib_api.$(EXTENSION) raymath_api.$(EXTENSION) rlgl_api.$(EXTENSION) rmem_api.$(EXTENSION) physac_api.$(EXTENSION) raygui_api.$(EXTENSION)
# `make parse` (and therefore `make all) requires
# rmem.h, physac.h and raygui.h to exist in the correct directory
# API files for individual headers can be created likeso, provided the relevant header exists:
# FORMAT=JSON EXTENSION=json make raygui_api.json
all: raylib_parser
FORMAT=DEFAULT EXTENSION=txt $(MAKE) parse FORMAT=DEFAULT EXTENSION=txt $(MAKE) parse
FORMAT=JSON EXTENSION=json $(MAKE) parse FORMAT=JSON EXTENSION=json $(MAKE) parse
FORMAT=XML EXTENSION=xml $(MAKE) parse FORMAT=XML EXTENSION=xml $(MAKE) parse
FORMAT=LUA EXTENSION=lua $(MAKE) parse FORMAT=LUA EXTENSION=lua $(MAKE) parse
parse:
./raylib_parser -i ../src/raylib.h -o raylib_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
./raylib_parser -i ../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
./raylib_parser -i ../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI -t "RLGL IMPLEMENTATION"
./raylib_parser -i ../src/easings.h -o easings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
./raylib_parser -i ../src/rmem.h -o rmem_api.$(EXTENSION) -f $(FORMAT) -d RMEMAPI -t "RMEM IMPLEMENTATION"
./raylib_parser -i ../physac.h -o physac_api.$(EXTENSION) -f $(FORMAT) -d PHYSACDEF -t "PHYSAC IMPLEMENTATION"
./raylib_parser -i ../raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI -t "RAYGUI IMPLEMENTATION"
clean: clean:
rm -f raylib_parser *.json *.txt *.xml *.lua rm -f raylib_parser *.json *.txt *.xml *.lua

View File

@ -9,7 +9,7 @@
{ {
"name": "RAYLIB_VERSION", "name": "RAYLIB_VERSION",
"type": "STRING", "type": "STRING",
"value": "4.2", "value": "4.5-dev",
"description": "" "description": ""
}, },
{ {
@ -729,7 +729,7 @@
{ {
"type": "float", "type": "float",
"name": "fovy", "name": "fovy",
"description": "Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic" "description": "Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic"
}, },
{ {
"type": "int", "type": "int",
@ -905,7 +905,7 @@
}, },
{ {
"name": "Transform", "name": "Transform",
"description": "Transform, vectex transformation data", "description": "Transform, vertex transformation data",
"fields": [ "fields": [
{ {
"type": "Vector3", "type": "Vector3",
@ -2051,7 +2051,7 @@
{ {
"name": "MOUSE_BUTTON_FORWARD", "name": "MOUSE_BUTTON_FORWARD",
"value": 5, "value": 5,
"description": "Mouse button fordward (advanced mouse device)" "description": "Mouse button forward (advanced mouse device)"
}, },
{ {
"name": "MOUSE_BUTTON_BACK", "name": "MOUSE_BUTTON_BACK",
@ -2795,6 +2795,11 @@
"name": "BLEND_CUSTOM", "name": "BLEND_CUSTOM",
"value": 6, "value": 6,
"description": "Blend textures using custom src/dst factors (use rlSetBlendMode())" "description": "Blend textures using custom src/dst factors (use rlSetBlendMode())"
},
{
"name": "BLEND_CUSTOM_SEPARATE",
"value": 7,
"description": "Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendModeSeparate())"
} }
] ]
}, },
@ -3971,7 +3976,7 @@
"returnType": "void *", "returnType": "void *",
"params": [ "params": [
{ {
"type": "int", "type": "unsigned int",
"name": "size" "name": "size"
} }
] ]
@ -3986,7 +3991,7 @@
"name": "ptr" "name": "ptr"
}, },
{ {
"type": "int", "type": "unsigned int",
"name": "size" "name": "size"
} }
] ]
@ -5995,6 +6000,25 @@
} }
] ]
}, },
{
"name": "CheckCollisionPointPoly",
"description": "Check if point is within a polygon described by array of vertices",
"returnType": "bool",
"params": [
{
"type": "Vector2",
"name": "point"
},
{
"type": "Vector2 *",
"name": "points"
},
{
"type": "int",
"name": "pointCount"
}
]
},
{ {
"name": "CheckCollisionLines", "name": "CheckCollisionLines",
"description": "Check the collision between two lines defined by two points each, returns collision point by reference", "description": "Check the collision between two lines defined by two points each, returns collision point by reference",
@ -6331,6 +6355,33 @@
} }
] ]
}, },
{
"name": "GenImagePerlinNoise",
"description": "Generate image: perlin noise",
"returnType": "Image",
"params": [
{
"type": "int",
"name": "width"
},
{
"type": "int",
"name": "height"
},
{
"type": "int",
"name": "offsetX"
},
{
"type": "int",
"name": "offsetY"
},
{
"type": "float",
"name": "scale"
}
]
},
{ {
"name": "GenImageCellular", "name": "GenImageCellular",
"description": "Generate image: cellular algorithm, bigger tileSize means bigger cells", "description": "Generate image: cellular algorithm, bigger tileSize means bigger cells",
@ -6963,7 +7014,7 @@
}, },
{ {
"name": "ImageDrawCircle", "name": "ImageDrawCircle",
"description": "Draw circle within an image", "description": "Draw a filled circle within an image",
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
@ -6990,7 +7041,57 @@
}, },
{ {
"name": "ImageDrawCircleV", "name": "ImageDrawCircleV",
"description": "Draw circle within an image (Vector version)", "description": "Draw a filled circle within an image (Vector version)",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "Vector2",
"name": "center"
},
{
"type": "int",
"name": "radius"
},
{
"type": "Color",
"name": "color"
}
]
},
{
"name": "ImageDrawCircleLines",
"description": "Draw circle outline within an image",
"returnType": "void",
"params": [
{
"type": "Image *",
"name": "dst"
},
{
"type": "int",
"name": "centerX"
},
{
"type": "int",
"name": "centerY"
},
{
"type": "int",
"name": "radius"
},
{
"type": "Color",
"name": "color"
}
]
},
{
"name": "ImageDrawCircleLinesV",
"description": "Draw circle outline within an image (Vector version)",
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
@ -8221,6 +8322,32 @@
} }
] ]
}, },
{
"name": "LoadUTF8",
"description": "Load UTF-8 text encoded from codepoints array",
"returnType": "char *",
"params": [
{
"type": "const int *",
"name": "codepoints"
},
{
"type": "int",
"name": "length"
}
]
},
{
"name": "UnloadUTF8",
"description": "Unload UTF-8 text encoded from codepoints array",
"returnType": "void",
"params": [
{
"type": "char *",
"name": "text"
}
]
},
{ {
"name": "LoadCodepoints", "name": "LoadCodepoints",
"description": "Load all codepoints from a UTF-8 text string, codepoints count returned by parameter", "description": "Load all codepoints from a UTF-8 text string, codepoints count returned by parameter",
@ -8269,7 +8396,37 @@
}, },
{ {
"type": "int *", "type": "int *",
"name": "bytesProcessed" "name": "codepointSize"
}
]
},
{
"name": "GetCodepointNext",
"description": "Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure",
"returnType": "int",
"params": [
{
"type": "const char *",
"name": "text"
},
{
"type": "int *",
"name": "codepointSize"
}
]
},
{
"name": "GetCodepointPrevious",
"description": "Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure",
"returnType": "int",
"params": [
{
"type": "const char *",
"name": "text"
},
{
"type": "int *",
"name": "codepointSize"
} }
] ]
}, },
@ -8284,22 +8441,7 @@
}, },
{ {
"type": "int *", "type": "int *",
"name": "byteSize" "name": "utf8Size"
}
]
},
{
"name": "TextCodepointsToUTF8",
"description": "Encode text as codepoints array into UTF-8 text string (WARNING: memory must be freed!)",
"returnType": "char *",
"params": [
{
"type": "const int *",
"name": "codepoints"
},
{
"type": "int",
"name": "length"
} }
] ]
}, },
@ -10685,7 +10827,7 @@
}, },
{ {
"name": "AttachAudioStreamProcessor", "name": "AttachAudioStreamProcessor",
"description": "", "description": "Attach audio stream processor to stream",
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {
@ -10700,7 +10842,7 @@
}, },
{ {
"name": "DetachAudioStreamProcessor", "name": "DetachAudioStreamProcessor",
"description": "", "description": "Detach audio stream processor from stream",
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {

View File

@ -9,7 +9,7 @@ return {
{ {
name = "RAYLIB_VERSION", name = "RAYLIB_VERSION",
type = "STRING", type = "STRING",
value = "4.2", value = "4.5-dev",
description = "" description = ""
}, },
{ {
@ -729,7 +729,7 @@ return {
{ {
type = "float", type = "float",
name = "fovy", name = "fovy",
description = "Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic" description = "Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic"
}, },
{ {
type = "int", type = "int",
@ -905,7 +905,7 @@ return {
}, },
{ {
name = "Transform", name = "Transform",
description = "Transform, vectex transformation data", description = "Transform, vertex transformation data",
fields = { fields = {
{ {
type = "Vector3", type = "Vector3",
@ -2051,7 +2051,7 @@ return {
{ {
name = "MOUSE_BUTTON_FORWARD", name = "MOUSE_BUTTON_FORWARD",
value = 5, value = 5,
description = "Mouse button fordward (advanced mouse device)" description = "Mouse button forward (advanced mouse device)"
}, },
{ {
name = "MOUSE_BUTTON_BACK", name = "MOUSE_BUTTON_BACK",
@ -2795,6 +2795,11 @@ return {
name = "BLEND_CUSTOM", name = "BLEND_CUSTOM",
value = 6, value = 6,
description = "Blend textures using custom src/dst factors (use rlSetBlendMode())" description = "Blend textures using custom src/dst factors (use rlSetBlendMode())"
},
{
name = "BLEND_CUSTOM_SEPARATE",
value = 7,
description = "Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendModeSeparate())"
} }
} }
}, },
@ -3673,7 +3678,7 @@ return {
description = "Internal memory allocator", description = "Internal memory allocator",
returnType = "void *", returnType = "void *",
params = { params = {
{type = "int", name = "size"} {type = "unsigned int", name = "size"}
} }
}, },
{ {
@ -3682,7 +3687,7 @@ return {
returnType = "void *", returnType = "void *",
params = { params = {
{type = "void *", name = "ptr"}, {type = "void *", name = "ptr"},
{type = "int", name = "size"} {type = "unsigned int", name = "size"}
} }
}, },
{ {
@ -4846,6 +4851,16 @@ return {
{type = "Vector2", name = "p3"} {type = "Vector2", name = "p3"}
} }
}, },
{
name = "CheckCollisionPointPoly",
description = "Check if point is within a polygon described by array of vertices",
returnType = "bool",
params = {
{type = "Vector2", name = "point"},
{type = "Vector2 *", name = "points"},
{type = "int", name = "pointCount"}
}
},
{ {
name = "CheckCollisionLines", name = "CheckCollisionLines",
description = "Check the collision between two lines defined by two points each, returns collision point by reference", description = "Check the collision between two lines defined by two points each, returns collision point by reference",
@ -5023,6 +5038,18 @@ return {
{type = "float", name = "factor"} {type = "float", name = "factor"}
} }
}, },
{
name = "GenImagePerlinNoise",
description = "Generate image: perlin noise",
returnType = "Image",
params = {
{type = "int", name = "width"},
{type = "int", name = "height"},
{type = "int", name = "offsetX"},
{type = "int", name = "offsetY"},
{type = "float", name = "scale"}
}
},
{ {
name = "GenImageCellular", name = "GenImageCellular",
description = "Generate image: cellular algorithm, bigger tileSize means bigger cells", description = "Generate image: cellular algorithm, bigger tileSize means bigger cells",
@ -5382,7 +5409,7 @@ return {
}, },
{ {
name = "ImageDrawCircle", name = "ImageDrawCircle",
description = "Draw circle within an image", description = "Draw a filled circle within an image",
returnType = "void", returnType = "void",
params = { params = {
{type = "Image *", name = "dst"}, {type = "Image *", name = "dst"},
@ -5394,7 +5421,30 @@ return {
}, },
{ {
name = "ImageDrawCircleV", name = "ImageDrawCircleV",
description = "Draw circle within an image (Vector version)", description = "Draw a filled circle within an image (Vector version)",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "Vector2", name = "center"},
{type = "int", name = "radius"},
{type = "Color", name = "color"}
}
},
{
name = "ImageDrawCircleLines",
description = "Draw circle outline within an image",
returnType = "void",
params = {
{type = "Image *", name = "dst"},
{type = "int", name = "centerX"},
{type = "int", name = "centerY"},
{type = "int", name = "radius"},
{type = "Color", name = "color"}
}
},
{
name = "ImageDrawCircleLinesV",
description = "Draw circle outline within an image (Vector version)",
returnType = "void", returnType = "void",
params = { params = {
{type = "Image *", name = "dst"}, {type = "Image *", name = "dst"},
@ -6019,6 +6069,23 @@ return {
{type = "int", name = "codepoint"} {type = "int", name = "codepoint"}
} }
}, },
{
name = "LoadUTF8",
description = "Load UTF-8 text encoded from codepoints array",
returnType = "char *",
params = {
{type = "const int *", name = "codepoints"},
{type = "int", name = "length"}
}
},
{
name = "UnloadUTF8",
description = "Unload UTF-8 text encoded from codepoints array",
returnType = "void",
params = {
{type = "char *", name = "text"}
}
},
{ {
name = "LoadCodepoints", name = "LoadCodepoints",
description = "Load all codepoints from a UTF-8 text string, codepoints count returned by parameter", description = "Load all codepoints from a UTF-8 text string, codepoints count returned by parameter",
@ -6050,7 +6117,25 @@ return {
returnType = "int", returnType = "int",
params = { params = {
{type = "const char *", name = "text"}, {type = "const char *", name = "text"},
{type = "int *", name = "bytesProcessed"} {type = "int *", name = "codepointSize"}
}
},
{
name = "GetCodepointNext",
description = "Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure",
returnType = "int",
params = {
{type = "const char *", name = "text"},
{type = "int *", name = "codepointSize"}
}
},
{
name = "GetCodepointPrevious",
description = "Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure",
returnType = "int",
params = {
{type = "const char *", name = "text"},
{type = "int *", name = "codepointSize"}
} }
}, },
{ {
@ -6059,16 +6144,7 @@ return {
returnType = "const char *", returnType = "const char *",
params = { params = {
{type = "int", name = "codepoint"}, {type = "int", name = "codepoint"},
{type = "int *", name = "byteSize"} {type = "int *", name = "utf8Size"}
}
},
{
name = "TextCodepointsToUTF8",
description = "Encode text as codepoints array into UTF-8 text string (WARNING: memory must be freed!)",
returnType = "char *",
params = {
{type = "const int *", name = "codepoints"},
{type = "int", name = "length"}
} }
}, },
{ {
@ -7415,7 +7491,7 @@ return {
}, },
{ {
name = "AttachAudioStreamProcessor", name = "AttachAudioStreamProcessor",
description = "", description = "Attach audio stream processor to stream",
returnType = "void", returnType = "void",
params = { params = {
{type = "AudioStream", name = "stream"}, {type = "AudioStream", name = "stream"},
@ -7424,7 +7500,7 @@ return {
}, },
{ {
name = "DetachAudioStreamProcessor", name = "DetachAudioStreamProcessor",
description = "", description = "Detach audio stream processor from stream",
returnType = "void", returnType = "void",
params = { params = {
{type = "AudioStream", name = "stream"}, {type = "AudioStream", name = "stream"},

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
<raylibAPI> <raylibAPI>
<Defines count="53"> <Defines count="53">
<Define name="RAYLIB_H" type="GUARD" value="" desc="" /> <Define name="RAYLIB_H" type="GUARD" value="" desc="" />
<Define name="RAYLIB_VERSION" type="STRING" value="4.2" desc="" /> <Define name="RAYLIB_VERSION" type="STRING" value="4.5-dev" desc="" />
<Define name="__declspec(x)" type="MACRO" value="__attribute__((x))" desc="" /> <Define name="__declspec(x)" type="MACRO" value="__attribute__((x))" desc="" />
<Define name="RLAPI" type="UNKNOWN" value="__declspec(dllexport)" desc="We are building the library as a Win32 shared library (.dll)" /> <Define name="RLAPI" type="UNKNOWN" value="__declspec(dllexport)" desc="We are building the library as a Win32 shared library (.dll)" />
<Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" /> <Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" />
@ -147,7 +147,7 @@
<Field type="Vector3" name="position" desc="Camera position" /> <Field type="Vector3" name="position" desc="Camera position" />
<Field type="Vector3" name="target" desc="Camera target it looks-at" /> <Field type="Vector3" name="target" desc="Camera target it looks-at" />
<Field type="Vector3" name="up" desc="Camera up vector (rotation over its axis)" /> <Field type="Vector3" name="up" desc="Camera up vector (rotation over its axis)" />
<Field type="float" name="fovy" desc="Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic" /> <Field type="float" name="fovy" desc="Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic" />
<Field type="int" name="projection" desc="Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC" /> <Field type="int" name="projection" desc="Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC" />
</Struct> </Struct>
<Struct name="Camera2D" fieldCount="4" desc="Camera2D, defines position/orientation in 2d space"> <Struct name="Camera2D" fieldCount="4" desc="Camera2D, defines position/orientation in 2d space">
@ -187,7 +187,7 @@
<Field type="MaterialMap *" name="maps" desc="Material maps array (MAX_MATERIAL_MAPS)" /> <Field type="MaterialMap *" name="maps" desc="Material maps array (MAX_MATERIAL_MAPS)" />
<Field type="float[4]" name="params" desc="Material generic parameters (if required)" /> <Field type="float[4]" name="params" desc="Material generic parameters (if required)" />
</Struct> </Struct>
<Struct name="Transform" fieldCount="3" desc="Transform, vectex transformation data"> <Struct name="Transform" fieldCount="3" desc="Transform, vertex transformation data">
<Field type="Vector3" name="translation" desc="Translation" /> <Field type="Vector3" name="translation" desc="Translation" />
<Field type="Quaternion" name="rotation" desc="Rotation" /> <Field type="Quaternion" name="rotation" desc="Rotation" />
<Field type="Vector3" name="scale" desc="Scale" /> <Field type="Vector3" name="scale" desc="Scale" />
@ -433,7 +433,7 @@
<Value name="MOUSE_BUTTON_MIDDLE" integer="2" desc="Mouse button middle (pressed wheel)" /> <Value name="MOUSE_BUTTON_MIDDLE" integer="2" desc="Mouse button middle (pressed wheel)" />
<Value name="MOUSE_BUTTON_SIDE" integer="3" desc="Mouse button side (advanced mouse device)" /> <Value name="MOUSE_BUTTON_SIDE" integer="3" desc="Mouse button side (advanced mouse device)" />
<Value name="MOUSE_BUTTON_EXTRA" integer="4" desc="Mouse button extra (advanced mouse device)" /> <Value name="MOUSE_BUTTON_EXTRA" integer="4" desc="Mouse button extra (advanced mouse device)" />
<Value name="MOUSE_BUTTON_FORWARD" integer="5" desc="Mouse button fordward (advanced mouse device)" /> <Value name="MOUSE_BUTTON_FORWARD" integer="5" desc="Mouse button forward (advanced mouse device)" />
<Value name="MOUSE_BUTTON_BACK" integer="6" desc="Mouse button back (advanced mouse device)" /> <Value name="MOUSE_BUTTON_BACK" integer="6" desc="Mouse button back (advanced mouse device)" />
</Enum> </Enum>
<Enum name="MouseCursor" valueCount="11" desc="Mouse cursor"> <Enum name="MouseCursor" valueCount="11" desc="Mouse cursor">
@ -585,7 +585,7 @@
<Value name="FONT_BITMAP" integer="1" desc="Bitmap font generation, no anti-aliasing" /> <Value name="FONT_BITMAP" integer="1" desc="Bitmap font generation, no anti-aliasing" />
<Value name="FONT_SDF" integer="2" desc="SDF font generation, requires external shader" /> <Value name="FONT_SDF" integer="2" desc="SDF font generation, requires external shader" />
</Enum> </Enum>
<Enum name="BlendMode" valueCount="7" desc="Color blending modes (pre-defined)"> <Enum name="BlendMode" valueCount="8" desc="Color blending modes (pre-defined)">
<Value name="BLEND_ALPHA" integer="0" desc="Blend textures considering alpha (default)" /> <Value name="BLEND_ALPHA" integer="0" desc="Blend textures considering alpha (default)" />
<Value name="BLEND_ADDITIVE" integer="1" desc="Blend textures adding colors" /> <Value name="BLEND_ADDITIVE" integer="1" desc="Blend textures adding colors" />
<Value name="BLEND_MULTIPLIED" integer="2" desc="Blend textures multiplying colors" /> <Value name="BLEND_MULTIPLIED" integer="2" desc="Blend textures multiplying colors" />
@ -593,6 +593,7 @@
<Value name="BLEND_SUBTRACT_COLORS" integer="4" desc="Blend textures subtracting colors (alternative)" /> <Value name="BLEND_SUBTRACT_COLORS" integer="4" desc="Blend textures subtracting colors (alternative)" />
<Value name="BLEND_ALPHA_PREMULTIPLY" integer="5" desc="Blend premultiplied textures considering alpha" /> <Value name="BLEND_ALPHA_PREMULTIPLY" integer="5" desc="Blend premultiplied textures considering alpha" />
<Value name="BLEND_CUSTOM" integer="6" desc="Blend textures using custom src/dst factors (use rlSetBlendMode())" /> <Value name="BLEND_CUSTOM" integer="6" desc="Blend textures using custom src/dst factors (use rlSetBlendMode())" />
<Value name="BLEND_CUSTOM_SEPARATE" integer="7" desc="Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendModeSeparate())" />
</Enum> </Enum>
<Enum name="Gesture" valueCount="11" desc="Gesture"> <Enum name="Gesture" valueCount="11" desc="Gesture">
<Value name="GESTURE_NONE" integer="0" desc="No gesture" /> <Value name="GESTURE_NONE" integer="0" desc="No gesture" />
@ -651,7 +652,7 @@
<Param type="unsigned int" name="frames" desc="" /> <Param type="unsigned int" name="frames" desc="" />
</Callback> </Callback>
</Callbacks> </Callbacks>
<Functions count="502"> <Functions count="509">
<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="" />
@ -935,11 +936,11 @@
<Param type="int" name="logLevel" desc="" /> <Param type="int" name="logLevel" desc="" />
</Function> </Function>
<Function name="MemAlloc" retType="void *" paramCount="1" desc="Internal memory allocator"> <Function name="MemAlloc" retType="void *" paramCount="1" desc="Internal memory allocator">
<Param type="int" name="size" desc="" /> <Param type="unsigned int" name="size" desc="" />
</Function> </Function>
<Function name="MemRealloc" retType="void *" paramCount="2" desc="Internal memory reallocator"> <Function name="MemRealloc" retType="void *" paramCount="2" desc="Internal memory reallocator">
<Param type="void *" name="ptr" desc="" /> <Param type="void *" name="ptr" desc="" />
<Param type="int" name="size" desc="" /> <Param type="unsigned int" name="size" desc="" />
</Function> </Function>
<Function name="MemFree" retType="void" paramCount="1" desc="Internal memory free"> <Function name="MemFree" retType="void" paramCount="1" desc="Internal memory free">
<Param type="void *" name="ptr" desc="" /> <Param type="void *" name="ptr" desc="" />
@ -1486,6 +1487,11 @@
<Param type="Vector2" name="p2" desc="" /> <Param type="Vector2" name="p2" desc="" />
<Param type="Vector2" name="p3" desc="" /> <Param type="Vector2" name="p3" desc="" />
</Function> </Function>
<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="points" desc="" />
<Param type="int" name="pointCount" desc="" />
</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">
<Param type="Vector2" name="startPos1" desc="" /> <Param type="Vector2" name="startPos1" desc="" />
<Param type="Vector2" name="endPos1" desc="" /> <Param type="Vector2" name="endPos1" desc="" />
@ -1575,6 +1581,13 @@
<Param type="int" name="height" desc="" /> <Param type="int" name="height" desc="" />
<Param type="float" name="factor" desc="" /> <Param type="float" name="factor" desc="" />
</Function> </Function>
<Function name="GenImagePerlinNoise" retType="Image" paramCount="5" desc="Generate image: perlin noise">
<Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" />
<Param type="int" name="offsetX" desc="" />
<Param type="int" name="offsetY" desc="" />
<Param type="float" name="scale" desc="" />
</Function>
<Function name="GenImageCellular" retType="Image" paramCount="3" desc="Generate image: cellular algorithm, bigger tileSize means bigger cells"> <Function name="GenImageCellular" retType="Image" paramCount="3" desc="Generate image: cellular algorithm, bigger tileSize means bigger cells">
<Param type="int" name="width" desc="" /> <Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" /> <Param type="int" name="height" desc="" />
@ -1742,14 +1755,27 @@
<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="ImageDrawCircle" retType="void" paramCount="5" desc="Draw 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="" />
<Param type="int" name="centerY" desc="" /> <Param type="int" name="centerY" desc="" />
<Param type="int" name="radius" desc="" /> <Param type="int" name="radius" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>
<Function name="ImageDrawCircleV" retType="void" paramCount="4" desc="Draw circle within an image (Vector version)"> <Function name="ImageDrawCircleV" retType="void" paramCount="4" desc="Draw a filled circle within an image (Vector version)">
<Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="center" desc="" />
<Param type="int" name="radius" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawCircleLines" retType="void" paramCount="5" desc="Draw circle outline within an image">
<Param type="Image *" name="dst" desc="" />
<Param type="int" name="centerX" desc="" />
<Param type="int" name="centerY" desc="" />
<Param type="int" name="radius" desc="" />
<Param type="Color" name="color" desc="" />
</Function>
<Function name="ImageDrawCircleLinesV" retType="void" paramCount="4" desc="Draw circle outline within an image (Vector version)">
<Param type="Image *" name="dst" desc="" /> <Param type="Image *" name="dst" desc="" />
<Param type="Vector2" name="center" desc="" /> <Param type="Vector2" name="center" desc="" />
<Param type="int" name="radius" desc="" /> <Param type="int" name="radius" desc="" />
@ -2073,6 +2099,13 @@
<Param type="Font" name="font" desc="" /> <Param type="Font" name="font" desc="" />
<Param type="int" name="codepoint" desc="" /> <Param type="int" name="codepoint" desc="" />
</Function> </Function>
<Function name="LoadUTF8" retType="char *" paramCount="2" desc="Load UTF-8 text encoded from codepoints array">
<Param type="const int *" name="codepoints" desc="" />
<Param type="int" name="length" desc="" />
</Function>
<Function name="UnloadUTF8" retType="void" paramCount="1" desc="Unload UTF-8 text encoded from codepoints array">
<Param type="char *" name="text" desc="" />
</Function>
<Function name="LoadCodepoints" retType="int *" paramCount="2" desc="Load all codepoints from a UTF-8 text string, codepoints count returned by parameter"> <Function name="LoadCodepoints" retType="int *" paramCount="2" desc="Load all codepoints from a UTF-8 text string, codepoints count returned by parameter">
<Param type="const char *" name="text" desc="" /> <Param type="const char *" name="text" desc="" />
<Param type="int *" name="count" desc="" /> <Param type="int *" name="count" desc="" />
@ -2085,15 +2118,19 @@
</Function> </Function>
<Function name="GetCodepoint" retType="int" paramCount="2" desc="Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure"> <Function name="GetCodepoint" retType="int" paramCount="2" desc="Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure">
<Param type="const char *" name="text" desc="" /> <Param type="const char *" name="text" desc="" />
<Param type="int *" name="bytesProcessed" desc="" /> <Param type="int *" name="codepointSize" desc="" />
</Function>
<Function name="GetCodepointNext" retType="int" paramCount="2" desc="Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure">
<Param type="const char *" name="text" desc="" />
<Param type="int *" name="codepointSize" desc="" />
</Function>
<Function name="GetCodepointPrevious" retType="int" paramCount="2" desc="Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure">
<Param type="const char *" name="text" desc="" />
<Param type="int *" name="codepointSize" desc="" />
</Function> </Function>
<Function name="CodepointToUTF8" retType="const char *" paramCount="2" desc="Encode one codepoint into UTF-8 byte array (array length returned as parameter)"> <Function name="CodepointToUTF8" retType="const char *" paramCount="2" desc="Encode one codepoint into UTF-8 byte array (array length returned as parameter)">
<Param type="int" name="codepoint" desc="" /> <Param type="int" name="codepoint" desc="" />
<Param type="int *" name="byteSize" desc="" /> <Param type="int *" name="utf8Size" desc="" />
</Function>
<Function name="TextCodepointsToUTF8" retType="char *" paramCount="2" desc="Encode text as codepoints array into UTF-8 text string (WARNING: memory must be freed!)">
<Param type="const int *" name="codepoints" desc="" />
<Param type="int" name="length" desc="" />
</Function> </Function>
<Function name="TextCopy" retType="int" paramCount="2" desc="Copy one string to another, returns bytes copied"> <Function name="TextCopy" retType="int" paramCount="2" desc="Copy one string to another, returns bytes copied">
<Param type="char *" name="dst" desc="" /> <Param type="char *" name="dst" desc="" />
@ -2729,11 +2766,11 @@
<Param type="AudioStream" name="stream" desc="" /> <Param type="AudioStream" name="stream" desc="" />
<Param type="AudioCallback" name="callback" desc="" /> <Param type="AudioCallback" name="callback" desc="" />
</Function> </Function>
<Function name="AttachAudioStreamProcessor" retType="void" paramCount="2" desc=""> <Function name="AttachAudioStreamProcessor" retType="void" paramCount="2" desc="Attach audio stream processor to stream">
<Param type="AudioStream" name="stream" desc="" /> <Param type="AudioStream" name="stream" desc="" />
<Param type="AudioCallback" name="processor" desc="" /> <Param type="AudioCallback" name="processor" desc="" />
</Function> </Function>
<Function name="DetachAudioStreamProcessor" retType="void" paramCount="2" desc=""> <Function name="DetachAudioStreamProcessor" retType="void" paramCount="2" desc="Detach audio stream processor from stream">
<Param type="AudioStream" name="stream" desc="" /> <Param type="AudioStream" name="stream" desc="" />
<Param type="AudioCallback" name="processor" desc="" /> <Param type="AudioCallback" name="processor" desc="" />
</Function> </Function>

View File

@ -207,6 +207,12 @@ int main(int argc, char* argv[])
int length = 0; int length = 0;
char *buffer = LoadFileText(inFileName, &length); char *buffer = LoadFileText(inFileName, &length);
if (buffer == NULL)
{
printf("Could not read input file: %s\n", inFileName);
return 1;
}
// Preprocess buffer to get separate lines // Preprocess buffer to get separate lines
// NOTE: GetTextLines() also removes leading spaces/tabs // NOTE: GetTextLines() also removes leading spaces/tabs
int linesCount = 0; int linesCount = 0;

View File

@ -190,13 +190,15 @@ endif
endif endif
ifeq ($(PLATFORM),PLATFORM_WEB) ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables ifeq ($(PLATFORM_OS), WINDOWS)
EMSDK_PATH ?= C:/emsdk # Emscripten required variables
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten EMSDK_PATH ?= C:/emsdk
CLANG_PATH = $(EMSDK_PATH)/upstream/bin EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
PYTHON_PATH = $(EMSDK_PATH)/python/3.9.2-1_64bit CLANG_PATH := $(EMSDK_PATH)/upstream/bin
NODE_PATH = $(EMSDK_PATH)/node/14.15.5_64bit/bin PYTHON_PATH := $(EMSDK_PATH)/python/3.9.2-1_64bit
export PATH := $(EMSDK_PATH):$(EMSCRIPTEN_PATH):$(CLANG_PATH):$(NODE_PATH):$(PYTHON_PATH):C:\raylib\MinGW\bin:$(PATH) NODE_PATH := $(EMSDK_PATH)/node/14.15.5_64bit/bin
export PATH := $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH);C:/raylib/MinGW/bin;$(PATH)
endif
endif endif
ifeq ($(PLATFORM),PLATFORM_ANDROID) ifeq ($(PLATFORM),PLATFORM_ANDROID)

View File

@ -1,20 +1,16 @@
const std = @import("std"); const std = @import("std");
pub fn addRaylib(b: *std.build.Builder, target: std.zig.CrossTarget) *std.build.LibExeObjStep { pub fn addRaylib(b: *std.build.Builder, target: std.zig.CrossTarget) *std.build.LibExeObjStep {
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const raylib_flags = &[_][]const u8{ const raylib_flags = &[_][]const u8{
"-std=gnu99", "-std=gnu99",
"-DPLATFORM_DESKTOP", "-DPLATFORM_DESKTOP",
"-D_GNU_SOURCE",
"-DGL_SILENCE_DEPRECATION=199309L", "-DGL_SILENCE_DEPRECATION=199309L",
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891 "-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891
}; };
const raylib = b.addStaticLibrary("raylib", srcdir ++ "/raylib.h"); const raylib = b.addStaticLibrary("raylib", null);
raylib.setTarget(target); raylib.setTarget(target);
raylib.setBuildMode(mode);
raylib.linkLibC(); raylib.linkLibC();
raylib.addIncludePath(srcdir ++ "/external/glfw/include"); raylib.addIncludePath(srcdir ++ "/external/glfw/include");
@ -68,6 +64,10 @@ pub fn addRaylib(b: *std.build.Builder, target: std.zig.CrossTarget) *std.build.
raylib_flags ++ raylib_flags_extra_macos, raylib_flags ++ raylib_flags_extra_macos,
); );
raylib.linkFramework("Foundation"); raylib.linkFramework("Foundation");
raylib.linkFramework("CoreServices");
raylib.linkFramework("CoreGraphics");
raylib.linkFramework("AppKit");
raylib.linkFramework("IOKit");
}, },
else => { else => {
@panic("Unsupported OS"); @panic("Unsupported OS");
@ -89,8 +89,8 @@ pub fn build(b: *std.build.Builder) void {
lib.install(); lib.install();
} }
const srcdir = getSrcDir(); const srcdir = struct{
fn getSrcDir() []const u8 {
fn getSrcDir() []const u8 { return std.fs.path.dirname(@src().file).?;
return std.fs.path.dirname(@src().file) orelse "."; }
} }.getSrcDir();

File diff suppressed because it is too large Load Diff

1414
src/external/miniaudio.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -778,28 +778,28 @@ static int get_pixel_data_size(int width, int height, int format)
switch (format) switch (format)
{ {
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break; case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
case PIXELFORMAT_UNCOMPRESSED_R5G6B5: case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break; case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break; case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break; case PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
case PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break; case PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break; case PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break; case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break;
case PIXELFORMAT_COMPRESSED_DXT1_RGB: case PIXELFORMAT_COMPRESSED_DXT1_RGB:
case PIXELFORMAT_COMPRESSED_DXT1_RGBA: case PIXELFORMAT_COMPRESSED_DXT1_RGBA:
case PIXELFORMAT_COMPRESSED_ETC1_RGB: case PIXELFORMAT_COMPRESSED_ETC1_RGB:
case PIXELFORMAT_COMPRESSED_ETC2_RGB: case PIXELFORMAT_COMPRESSED_ETC2_RGB:
case PIXELFORMAT_COMPRESSED_PVRT_RGB: case PIXELFORMAT_COMPRESSED_PVRT_RGB:
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break; case PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
case PIXELFORMAT_COMPRESSED_DXT3_RGBA: case PIXELFORMAT_COMPRESSED_DXT3_RGBA:
case PIXELFORMAT_COMPRESSED_DXT5_RGBA: case PIXELFORMAT_COMPRESSED_DXT5_RGBA:
case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break; case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break; case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
default: break; default: break;
} }
data_size = width*height*bpp/8; // Total data size in bytes data_size = width*height*bpp/8; // Total data size in bytes

View File

@ -67,7 +67,7 @@ revision history:
#define VOX_SUCCESS (0) #define VOX_SUCCESS (0)
#define VOX_ERROR_FILE_NOT_FOUND (-1) #define VOX_ERROR_FILE_NOT_FOUND (-1)
#define VOX_ERROR_INVALID_FORMAT (-2) #define VOX_ERROR_INVALID_FORMAT (-2)
#define VOX_ERROR_FILE_VERSION_TOO_OLD (-3) #define VOX_ERROR_FILE_VERSION_NOT_MATCH (-3)
// VoxColor, 4 components, R8G8B8A8 (32bit) // VoxColor, 4 components, R8G8B8A8 (32bit)
typedef struct { typedef struct {
@ -538,31 +538,26 @@ int Vox_LoadFromMemory(unsigned char* pvoxData, unsigned int voxDataSize, VoxArr
// @raysan5: Reviewed (unsigned long) -> (unsigned int), possible issue with Ubuntu 18.04 64bit // @raysan5: Reviewed (unsigned long) -> (unsigned int), possible issue with Ubuntu 18.04 64bit
// @raysan5: reviewed signature loading // @raysan5: reviewed signature loading
unsigned char signature[4] = { 0 };
unsigned char* fileData = pvoxData; unsigned char* fileData = pvoxData;
unsigned char* fileDataPtr = fileData; unsigned char* fileDataPtr = fileData;
unsigned char* endfileDataPtr = fileData + voxDataSize; unsigned char* endfileDataPtr = fileData + voxDataSize;
signature[0] = fileDataPtr[0]; if (strncmp((char*)fileDataPtr, "VOX ", 4) != 0)
signature[1] = fileDataPtr[1];
signature[2] = fileDataPtr[2];
signature[3] = fileDataPtr[3];
fileDataPtr += 4;
if ((signature[0] != 'V') && (signature[0] != 'O') && (signature[0] != 'X') && (signature[0] != ' '))
{ {
return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format" return VOX_ERROR_INVALID_FORMAT; //"Not an MagicaVoxel File format"
} }
fileDataPtr += 4;
// @raysan5: reviewed version loading // @raysan5: reviewed version loading
unsigned int version = 0; unsigned int version = 0;
version = ((unsigned int*)fileDataPtr)[0]; version = ((unsigned int*)fileDataPtr)[0];
fileDataPtr += 4; fileDataPtr += 4;
if (version < 150) if (version != 150)
{ {
return VOX_ERROR_FILE_VERSION_TOO_OLD; //"MagicaVoxel version too old" return VOX_ERROR_FILE_VERSION_NOT_MATCH; //"MagicaVoxel version doesn't match"
} }

View File

@ -526,7 +526,9 @@ void CloseAudioDevice(void)
AUDIO.System.isReady = false; AUDIO.System.isReady = false;
RL_FREE(AUDIO.System.pcmBuffer); RL_FREE(AUDIO.System.pcmBuffer);
AUDIO.System.pcmBuffer = NULL;
AUDIO.System.pcmBufferSize = 0;
TRACELOG(LOG_INFO, "AUDIO: Device closed successfully"); TRACELOG(LOG_INFO, "AUDIO: Device closed successfully");
} }
else TRACELOG(LOG_WARNING, "AUDIO: Device could not be closed, not currently initialized"); else TRACELOG(LOG_WARNING, "AUDIO: Device could not be closed, not currently initialized");

View File

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raylib v4.2 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) * raylib v4.5-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
* *
* FEATURES: * FEATURES:
* - NO external dependencies, all required libraries included with raylib * - NO external dependencies, all required libraries included with raylib
@ -81,7 +81,7 @@
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback #include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
#define RAYLIB_VERSION "4.2" #define RAYLIB_VERSION "4.5-dev"
// Function specifiers in case library is build/used as a shared library (Windows) // Function specifiers in case library is build/used as a shared library (Windows)
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
@ -305,7 +305,7 @@ typedef struct Camera3D {
Vector3 position; // Camera position Vector3 position; // Camera position
Vector3 target; // Camera target it looks-at Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis) Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic float fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic
int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
} Camera3D; } Camera3D;
@ -364,7 +364,7 @@ typedef struct Material {
float params[4]; // Material generic parameters (if required) float params[4]; // Material generic parameters (if required)
} Material; } Material;
// Transform, vectex transformation data // Transform, vertex transformation data
typedef struct Transform { typedef struct Transform {
Vector3 translation; // Translation Vector3 translation; // Translation
Quaternion rotation; // Rotation Quaternion rotation; // Rotation
@ -663,7 +663,7 @@ typedef enum {
MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel) MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel)
MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device) MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device)
MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device) MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device)
MOUSE_BUTTON_FORWARD = 5, // Mouse button fordward (advanced mouse device) MOUSE_BUTTON_FORWARD = 5, // Mouse button forward (advanced mouse device)
MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device) MOUSE_BUTTON_BACK = 6, // Mouse button back (advanced mouse device)
} MouseButton; } MouseButton;
@ -857,7 +857,8 @@ typedef enum {
BLEND_ADD_COLORS, // Blend textures adding colors (alternative) BLEND_ADD_COLORS, // Blend textures adding colors (alternative)
BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative)
BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha
BLEND_CUSTOM // Blend textures using custom src/dst factors (use rlSetBlendMode()) BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors())
BLEND_CUSTOM_SEPARATE // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate())
} BlendMode; } BlendMode;
// Gesture // Gesture
@ -967,7 +968,7 @@ RLAPI void DisableEventWaiting(void); // Disable wai
// 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 advance users that want full control over the frame processing
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + 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)
RLAPI void PollInputEvents(void); // Register all input events RLAPI void PollInputEvents(void); // Register all input events
@ -1057,7 +1058,7 @@ RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom
RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read) RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read)
RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData() RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success
RLAPI bool ExportDataAsCode(const char *data, unsigned int size, const char *fileName); // Export data to code (.h), returns true on success RLAPI bool ExportDataAsCode(const unsigned char *data, unsigned int size, const char *fileName); // Export data to code (.h), returns true on success
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText() RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText()
RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
@ -1243,6 +1244,7 @@ RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Col
RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise
RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise
RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells
RLAPI Image GenImageText(int width, int height, const char *text); // Generate image: grayscale image from text data
// Image manipulation functions // Image manipulation functions
RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
@ -1256,6 +1258,7 @@ RLAPI void ImageAlphaCrop(Image *image, float threshold);
RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); // Clear alpha channel to desired color RLAPI void ImageAlphaClear(Image *image, Color color, float threshold); // Clear alpha channel to desired color
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 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
@ -1318,11 +1321,8 @@ RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint);
RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
RLAPI void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle RLAPI void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
RLAPI void DrawTextureQuad(Texture2D texture, Vector2 tiling, Vector2 offset, Rectangle quad, Color tint); // Draw texture quad with tiling and offset parameters RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
RLAPI void DrawTextureTiled(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint); // Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest. RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely
RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely
RLAPI void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointCount, Color tint); // Draw a textured polygon
// Color/pixel related functions // Color/pixel related functions
RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f
@ -1412,8 +1412,6 @@ RLAPI void DrawCube(Vector3 position, float width, float height, float length, C
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
RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version) RLAPI void DrawCubeWiresV(Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version)
RLAPI void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color); // Draw cube textured
RLAPI void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color); // Draw cube with a region of a texture
RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere RLAPI void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters RLAPI void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires RLAPI void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
@ -1421,6 +1419,8 @@ RLAPI void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, f
RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos RLAPI void DrawCylinderEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos
RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires RLAPI void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos RLAPI void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos
RLAPI void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos
RLAPI void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos
RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ RLAPI void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line RLAPI void DrawRay(Ray ray, Color color); // Draw a ray line
RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) RLAPI void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
@ -1437,11 +1437,11 @@ RLAPI void UnloadModelKeepMeshes(Model model);
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes) RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
// Model drawing functions // Model drawing functions
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation

View File

@ -246,7 +246,7 @@
//#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition //#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition
#include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow() #include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow()
#endif #endif
// TODO: HACK: Added flag if not provided by GLFW when using external library // TODO: HACK: Added flag if not provided by GLFW when using external library
// Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev // Latest GLFW release (GLFW 3.3.8) does not implement this flag, it was added for 3.4.0-dev
#if !defined(GLFW_MOUSE_PASSTHROUGH) #if !defined(GLFW_MOUSE_PASSTHROUGH)
@ -1732,49 +1732,58 @@ int GetMonitorCount(void)
// Get number of monitors // Get number of monitors
int GetCurrentMonitor(void) int GetCurrentMonitor(void)
{ {
int index = 0;
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
int monitorCount; int monitorCount;
GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
GLFWmonitor* monitor = NULL; GLFWmonitor *monitor = NULL;
if (monitorCount == 1) // easy out if (monitorCount > 1)
return 0;
if (IsWindowFullscreen())
{ {
monitor = glfwGetWindowMonitor(CORE.Window.handle); if (IsWindowFullscreen())
for (int i = 0; i < monitorCount; i++)
{ {
if (monitors[i] == monitor) // Get the handle of the monitor that the specified window is in full screen on
return i; monitor = glfwGetWindowMonitor(CORE.Window.handle);
for (int i = 0; i < monitorCount; i++)
{
if (monitors[i] == monitor)
{
index = i;
break;
}
}
} }
return 0; else
}
else
{
int x = 0;
int y = 0;
glfwGetWindowPos(CORE.Window.handle, &x, &y);
for (int i = 0; i < monitorCount; i++)
{ {
int mx = 0; int x = 0;
int my = 0; int y = 0;
int width = 0; glfwGetWindowPos(CORE.Window.handle, &x, &y);
int height = 0;
monitor = monitors[i]; for (int i = 0; i < monitorCount; i++)
glfwGetMonitorWorkarea(monitor, &mx, &my, &width, &height); {
if (x >= mx && x <= (mx + width) && y >= my && y <= (my + height)) int mx = 0;
return i; int my = 0;
int width = 0;
int height = 0;
monitor = monitors[i];
glfwGetMonitorWorkarea(monitor, &mx, &my, &width, &height);
if (x >= mx && x <= (mx + width) && y >= my && y <= (my + height))
{
index = i;
break;
}
}
} }
} }
return 0;
#else
return 0;
#endif #endif
return index;
} }
// Get selected monitor position // Get selected monitor position
@ -1782,7 +1791,7 @@ Vector2 GetMonitorPosition(int monitor)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
int monitorCount; int monitorCount;
GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
if ((monitor >= 0) && (monitor < monitorCount)) if ((monitor >= 0) && (monitor < monitorCount))
{ {
@ -1852,7 +1861,7 @@ int GetMonitorPhysicalWidth(int monitor)
return 0; return 0;
} }
// Get primary monitor physical height in millimetres // Get selected monitor physical height in millimetres
int GetMonitorPhysicalHeight(int monitor) int GetMonitorPhysicalHeight(int monitor)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
@ -1870,6 +1879,7 @@ int GetMonitorPhysicalHeight(int monitor)
return 0; return 0;
} }
// Get selected monitor refresh rate
int GetMonitorRefreshRate(int monitor) int GetMonitorRefreshRate(int monitor)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
@ -1903,7 +1913,7 @@ Vector2 GetWindowPosition(void)
return (Vector2){ (float)x, (float)y }; return (Vector2){ (float)x, (float)y };
} }
// Get window scale DPI factor // Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void) Vector2 GetWindowScaleDPI(void)
{ {
Vector2 scale = { 1.0f, 1.0f }; Vector2 scale = { 1.0f, 1.0f };
@ -1937,7 +1947,7 @@ Vector2 GetWindowScaleDPI(void)
return scale; return scale;
} }
// Get the human-readable, UTF-8 encoded name of the primary monitor // Get the human-readable, UTF-8 encoded name of the selected monitor
const char *GetMonitorName(int monitor) const char *GetMonitorName(int monitor)
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
@ -1964,18 +1974,6 @@ void SetClipboardText(const char *text)
#endif #endif
} }
// Enable waiting for events on EndDrawing(), no automatic event polling
void EnableEventWaiting(void)
{
CORE.Window.eventWaiting = true;
}
// Disable waiting for events on EndDrawing(), automatic events polling
void DisableEventWaiting(void)
{
CORE.Window.eventWaiting = false;
}
// Get clipboard text content // Get clipboard text content
// NOTE: returned string is allocated and freed by GLFW // NOTE: returned string is allocated and freed by GLFW
const char *GetClipboardText(void) const char *GetClipboardText(void)
@ -1989,6 +1987,18 @@ const char *GetClipboardText(void)
return NULL; return NULL;
} }
// Enable waiting for events on EndDrawing(), no automatic event polling
void EnableEventWaiting(void)
{
CORE.Window.eventWaiting = true;
}
// Disable waiting for events on EndDrawing(), automatic events polling
void DisableEventWaiting(void)
{
CORE.Window.eventWaiting = false;
}
// Show mouse cursor // Show mouse cursor
void ShowCursor(void) void ShowCursor(void)
{ {
@ -2843,6 +2853,13 @@ int GetRandomValue(int min, int max)
max = min; max = min;
min = tmp; min = tmp;
} }
// WARNING: Ranges higher than RAND_MAX will return invalid results. More specifically, if (max - min) > INT_MAX there will
// be an overflow, and otherwise if (max - min) > RAND_MAX the random value will incorrectly never exceed a certain threshold.
if ((unsigned int)(max - min) > (unsigned int)RAND_MAX)
{
TRACELOG(LOG_WARNING, "Invalid GetRandomValue arguments. Range should not be higher than %i.", RAND_MAX);
}
return (rand()%(abs(max - min) + 1) + min); return (rand()%(abs(max - min) + 1) + min);
} }
@ -3208,14 +3225,12 @@ FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool
} }
// Unload directory filepaths // Unload directory filepaths
// WARNING: files.count is not reseted to 0 after unloading
void UnloadDirectoryFiles(FilePathList files) void UnloadDirectoryFiles(FilePathList files)
{ {
if (files.capacity > 0) for (unsigned int i = 0; i < files.capacity; i++) RL_FREE(files.paths[i]);
{
for (unsigned int i = 0; i < files.capacity; i++) RL_FREE(files.paths[i]);
RL_FREE(files.paths); RL_FREE(files.paths);
}
} }
// Change working directory, returns true on success // Change working directory, returns true on success
@ -3315,6 +3330,9 @@ unsigned char *DecompressData(const unsigned char *compData, int compDataSize, i
// Decompress data from a valid DEFLATE stream // Decompress data from a valid DEFLATE stream
data = RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1); data = RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1);
int length = sinflate(data, MAX_DECOMPRESSION_SIZE*1024*1024, compData, compDataSize); int length = sinflate(data, MAX_DECOMPRESSION_SIZE*1024*1024, compData, compDataSize);
// WARNING: RL_REALLOC can make (and leave) data copies in memory, be careful with sensitive compressed data!
// TODO: Use a different approach, create another buffer, copy data manually to it and wipe original buffer memory
unsigned char *temp = RL_REALLOC(data, length); unsigned char *temp = RL_REALLOC(data, length);
if (temp != NULL) data = temp; if (temp != NULL) data = temp;
@ -3438,7 +3456,7 @@ void OpenURL(const char *url)
else else
{ {
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
char *cmd = (char *)RL_CALLOC(strlen(url) + 10, sizeof(char)); char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char));
#if defined(_WIN32) #if defined(_WIN32)
sprintf(cmd, "explorer \"%s\"", url); sprintf(cmd, "explorer \"%s\"", url);
#endif #endif
@ -3817,7 +3835,7 @@ float GetMouseWheelMove(void)
Vector2 GetMouseWheelMoveV(void) Vector2 GetMouseWheelMoveV(void)
{ {
Vector2 result = { 0 }; Vector2 result = { 0 };
result = CORE.Input.Mouse.currentWheelMove; result = CORE.Input.Mouse.currentWheelMove;
return result; return result;
@ -3934,30 +3952,6 @@ static bool InitGraphicsDevice(int width, int height)
return false; return false;
} }
// NOTE: Getting video modes is not implemented in emscripten GLFW3 version
#if defined(PLATFORM_DESKTOP)
// Find monitor resolution
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return false;
}
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
#endif // PLATFORM_DESKTOP
#if defined(PLATFORM_WEB)
CORE.Window.display.width = CORE.Window.screen.width;
CORE.Window.display.height = CORE.Window.screen.height;
#endif // PLATFORM_WEB
glfwDefaultWindowHints(); // Set default windows hints glfwDefaultWindowHints(); // Set default windows hints
//glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
//glfwWindowHint(GLFW_GREEN_BITS, 8); // Framebuffer green color component bits //glfwWindowHint(GLFW_GREEN_BITS, 8); // Framebuffer green color component bits
@ -4074,6 +4068,31 @@ static bool InitGraphicsDevice(int width, int height)
if (MAX_GAMEPADS > 0) glfwSetJoystickCallback(NULL); if (MAX_GAMEPADS > 0) glfwSetJoystickCallback(NULL);
#endif #endif
#if defined(PLATFORM_DESKTOP)
// Find monitor resolution
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return false;
}
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
#endif // PLATFORM_DESKTOP
#if defined(PLATFORM_WEB)
// NOTE: Getting video modes is not implemented in emscripten GLFW3 version
CORE.Window.display.width = CORE.Window.screen.width;
CORE.Window.display.height = CORE.Window.screen.height;
#endif // PLATFORM_WEB
if (CORE.Window.fullscreen) if (CORE.Window.fullscreen)
{ {
// remember center for switchinging from fullscreen to window // remember center for switchinging from fullscreen to window
@ -4133,16 +4152,6 @@ static bool InitGraphicsDevice(int width, int height)
if (CORE.Window.handle) if (CORE.Window.handle)
{ {
#if defined(PLATFORM_DESKTOP)
// Center window on screen
int windowPosX = CORE.Window.display.width/2 - CORE.Window.screen.width/2;
int windowPosY = CORE.Window.display.height/2 - CORE.Window.screen.height/2;
if (windowPosX < 0) windowPosX = 0;
if (windowPosY < 0) windowPosY = 0;
glfwSetWindowPos(CORE.Window.handle, windowPosX, windowPosY);
#endif
CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.width = CORE.Window.screen.width;
CORE.Window.render.height = CORE.Window.screen.height; CORE.Window.render.height = CORE.Window.screen.height;
} }
@ -4163,6 +4172,7 @@ static bool InitGraphicsDevice(int width, int height)
glfwSetWindowIconifyCallback(CORE.Window.handle, WindowIconifyCallback); glfwSetWindowIconifyCallback(CORE.Window.handle, WindowIconifyCallback);
glfwSetWindowFocusCallback(CORE.Window.handle, WindowFocusCallback); glfwSetWindowFocusCallback(CORE.Window.handle, WindowFocusCallback);
glfwSetDropCallback(CORE.Window.handle, WindowDropCallback); glfwSetDropCallback(CORE.Window.handle, WindowDropCallback);
// Set input callback events // Set input callback events
glfwSetKeyCallback(CORE.Window.handle, KeyCallback); glfwSetKeyCallback(CORE.Window.handle, KeyCallback);
glfwSetCharCallback(CORE.Window.handle, CharCallback); glfwSetCharCallback(CORE.Window.handle, CharCallback);
@ -4171,11 +4181,11 @@ static bool InitGraphicsDevice(int width, int height)
glfwSetScrollCallback(CORE.Window.handle, MouseScrollCallback); glfwSetScrollCallback(CORE.Window.handle, MouseScrollCallback);
glfwSetCursorEnterCallback(CORE.Window.handle, CursorEnterCallback); glfwSetCursorEnterCallback(CORE.Window.handle, CursorEnterCallback);
glfwSetInputMode(CORE.Window.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM)
glfwMakeContextCurrent(CORE.Window.handle); glfwMakeContextCurrent(CORE.Window.handle);
#if !defined(PLATFORM_WEB) #if !defined(PLATFORM_WEB)
glfwSetInputMode(CORE.Window.handle, GLFW_LOCK_KEY_MODS, GLFW_TRUE); // Enable lock keys modifiers (CAPS, NUM)
glfwSwapInterval(0); // No V-Sync by default glfwSwapInterval(0); // No V-Sync by default
#endif #endif
@ -4295,6 +4305,7 @@ static bool InitGraphicsDevice(int width, int height)
drmModeFreeConnector(con); drmModeFreeConnector(con);
} }
} }
if (!CORE.Window.connector) if (!CORE.Window.connector)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found"); TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
@ -4340,18 +4351,20 @@ static bool InitGraphicsDevice(int width, int height)
const bool allowInterlaced = CORE.Window.flags & FLAG_INTERLACED_HINT; const bool allowInterlaced = CORE.Window.flags & FLAG_INTERLACED_HINT;
const int fps = (CORE.Time.target > 0) ? (1.0/CORE.Time.target) : 60; const int fps = (CORE.Time.target > 0) ? (1.0/CORE.Time.target) : 60;
// try to find an exact matching mode
// Try to find an exact matching mode
CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced); CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
// if nothing found, try to find a nearly matching mode
if (CORE.Window.modeIndex < 0) // If nothing found, try to find a nearly matching mode
CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced); if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
// if nothing found, try to find an exactly matching mode including interlaced
if (CORE.Window.modeIndex < 0) // If nothing found, try to find an exactly matching mode including interlaced
CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true); if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
// if nothing found, try to find a nearly matching mode including interlaced
if (CORE.Window.modeIndex < 0) // If nothing found, try to find a nearly matching mode including interlaced
CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true); if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
// if nothing found, there is no suitable mode
// If nothing found, there is no suitable mode
if (CORE.Window.modeIndex < 0) if (CORE.Window.modeIndex < 0)
{ {
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode"); TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
@ -5514,15 +5527,17 @@ static void WindowFocusCallback(GLFWwindow *window, int focused)
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{ {
if (key < 0) return; // Security check, macOS fn key generates -1 if (key < 0) return; // Security check, macOS fn key generates -1
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
// to work properly with our implementation (IsKeyDown/IsKeyUp checks) // to work properly with our implementation (IsKeyDown/IsKeyUp checks)
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
else CORE.Input.Keyboard.currentKeyState[key] = 1; else CORE.Input.Keyboard.currentKeyState[key] = 1;
#if !defined(PLATFORM_WEB)
// WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys // WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys
if (((key == KEY_CAPS_LOCK) && ((mods & GLFW_MOD_CAPS_LOCK) > 0)) || if (((key == KEY_CAPS_LOCK) && ((mods & GLFW_MOD_CAPS_LOCK) > 0)) ||
((key == KEY_NUM_LOCK) && ((mods & GLFW_MOD_NUM_LOCK) > 0))) CORE.Input.Keyboard.currentKeyState[key] = 1; ((key == KEY_NUM_LOCK) && ((mods & GLFW_MOD_NUM_LOCK) > 0))) CORE.Input.Keyboard.currentKeyState[key] = 1;
#endif
// Check if there is space available in the key queue // Check if there is space available in the key queue
if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (action == GLFW_PRESS)) if ((CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE) && (action == GLFW_PRESS))

View File

@ -151,6 +151,7 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
#if defined(GESTURES_IMPLEMENTATION) #if defined(GESTURES_IMPLEMENTATION)
#if defined(GESTURES_STANDALONE)
#if defined(_WIN32) #if defined(_WIN32)
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { // Prevents name mangling of functions extern "C" { // Prevents name mangling of functions
@ -175,6 +176,7 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
#include <mach/clock.h> // Required for: clock_get_time() #include <mach/clock.h> // Required for: clock_get_time()
#include <mach/mach.h> // Required for: mach_timespec_t #include <mach/mach.h> // Required for: mach_timespec_t
#endif #endif
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
@ -526,6 +528,9 @@ static double rgGetCurrentTime(void)
{ {
double time = 0; double time = 0;
#if !defined(GESTURES_STANDALONE)
time = GetTime();
#else
#if defined(_WIN32) #if defined(_WIN32)
unsigned long long int clockFrequency, currentTime; unsigned long long int clockFrequency, currentTime;
@ -558,6 +563,7 @@ static double rgGetCurrentTime(void)
unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec; // Time in nanoseconds
time = ((double)nowTime/1000000.0); // Time in miliseconds time = ((double)nowTime/1000000.0); // Time in miliseconds
#endif
#endif #endif
return time; return time;

View File

@ -413,7 +413,8 @@ typedef enum {
RL_BLEND_ADD_COLORS, // Blend textures adding colors (alternative) RL_BLEND_ADD_COLORS, // Blend textures adding colors (alternative)
RL_BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) RL_BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative)
RL_BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha RL_BLEND_ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha
RL_BLEND_CUSTOM // Blend textures using custom src/dst factors (use rlSetBlendFactors()) RL_BLEND_CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors())
RL_BLEND_CUSTOM_SEPARATE // Blend textures using custom src/dst factors (use rlSetBlendFactorsSeparate())
} rlBlendMode; } rlBlendMode;
// Shader location point type // Shader location point type
@ -449,7 +450,7 @@ typedef enum {
#define RL_SHADER_LOC_MAP_DIFFUSE RL_SHADER_LOC_MAP_ALBEDO #define RL_SHADER_LOC_MAP_DIFFUSE RL_SHADER_LOC_MAP_ALBEDO
#define RL_SHADER_LOC_MAP_SPECULAR RL_SHADER_LOC_MAP_METALNESS #define RL_SHADER_LOC_MAP_SPECULAR RL_SHADER_LOC_MAP_METALNESS
// Shader uniform data type // Shader uniform data type
typedef enum { typedef enum {
RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float
RL_SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float) RL_SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float)
@ -497,6 +498,12 @@ typedef enum {
RL_ATTACHMENT_RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer RL_ATTACHMENT_RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer
} rlFramebufferAttachTextureType; } rlFramebufferAttachTextureType;
// Face culling mode
typedef enum {
RL_CULL_FACE_FRONT = 0,
RL_CULL_FACE_BACK
} rlCullMode;
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - Matrix operations // Functions Declaration - Matrix operations
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -512,7 +519,7 @@ RLAPI void rlLoadIdentity(void); // Reset current matrix to
RLAPI void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix RLAPI void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix
RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix
RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix
RLAPI void rlMultMatrixf(float *matf); // Multiply the current matrix by another matrix RLAPI void rlMultMatrixf(const float *matf); // Multiply the current matrix by another matrix
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
@ -577,6 +584,7 @@ RLAPI void rlEnableDepthMask(void); // Enable depth write
RLAPI void rlDisableDepthMask(void); // Disable depth write RLAPI void rlDisableDepthMask(void); // Disable depth write
RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling
RLAPI void rlDisableBackfaceCulling(void); // Disable backface culling RLAPI void rlDisableBackfaceCulling(void); // Disable backface culling
RLAPI void rlSetCullFace(int mode); // Set face culling mode
RLAPI void rlEnableScissorTest(void); // Enable scissor test RLAPI void rlEnableScissorTest(void); // Enable scissor test
RLAPI void rlDisableScissorTest(void); // Disable scissor test RLAPI void rlDisableScissorTest(void); // Disable scissor test
RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
@ -595,6 +603,7 @@ RLAPI void rlClearScreenBuffers(void); // Clear used screen buf
RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes
RLAPI void rlSetBlendMode(int mode); // Set blending mode RLAPI void rlSetBlendMode(int mode); // Set blending mode
RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors) RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors)
RLAPI void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha); // Set blending mode factors and equations separately (using OpenGL factors)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - rlgl functionality // Functions Declaration - rlgl functionality
@ -687,7 +696,7 @@ RLAPI void rlCopyShaderBuffer(unsigned int destId, unsigned int srcId, unsigned
RLAPI unsigned int rlGetShaderBufferSize(unsigned int id); // Get SSBO buffer size RLAPI unsigned int rlGetShaderBufferSize(unsigned int id); // Get SSBO buffer size
// Buffer management // Buffer management
RLAPI void rlBindImageTexture(unsigned int id, unsigned int index, unsigned int format, int readonly); // Bind image texture RLAPI void rlBindImageTexture(unsigned int id, unsigned int index, int format, bool readonly); // Bind image texture
// Matrix state management // Matrix state management
RLAPI Matrix rlGetMatrixModelview(void); // Get internal modelview matrix RLAPI Matrix rlGetMatrixModelview(void); // Get internal modelview matrix
@ -926,10 +935,18 @@ typedef struct rlglData {
Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices
Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices
// Blending variables
int currentBlendMode; // Blending mode active int currentBlendMode; // Blending mode active
int glBlendSrcFactor; // Blending source factor int glBlendSrcFactor; // Blending source factor
int glBlendDstFactor; // Blending destination factor int glBlendDstFactor; // Blending destination factor
int glBlendEquation; // Blending equation int glBlendEquation; // Blending equation
int glBlendSrcFactorRGB; // Blending source RGB factor
int glBlendDestFactorRGB; // Blending destination RGB factor
int glBlendSrcFactorAlpha; // Blending source alpha factor
int glBlendDestFactorAlpha; // Blending destination alpha factor
int glBlendEquationRGB; // Blending equation for RGB
int glBlendEquationAlpha; // Blending equation for alpha
bool glCustomBlendModeModified; // Custom blending factor and equation modification status
int framebufferWidth; // Current framebuffer width int framebufferWidth; // Current framebuffer width
int framebufferHeight; // Current framebuffer height int framebufferHeight; // Current framebuffer height
@ -1031,7 +1048,7 @@ void rlLoadIdentity(void) { glLoadIdentity(); }
void rlTranslatef(float x, float y, float z) { glTranslatef(x, y, z); } void rlTranslatef(float x, float y, float z) { glTranslatef(x, y, z); }
void rlRotatef(float angle, float x, float y, float z) { glRotatef(angle, x, y, z); } void rlRotatef(float angle, float x, float y, float z) { glRotatef(angle, x, y, z); }
void rlScalef(float x, float y, float z) { glScalef(x, y, z); } void rlScalef(float x, float y, float z) { glScalef(x, y, z); }
void rlMultMatrixf(float *matf) { glMultMatrixf(matf); } void rlMultMatrixf(const float *matf) { glMultMatrixf(matf); }
#endif #endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Choose the current matrix to be transformed // Choose the current matrix to be transformed
@ -1156,7 +1173,7 @@ void rlScalef(float x, float y, float z)
} }
// Multiply the current matrix by another matrix // Multiply the current matrix by another matrix
void rlMultMatrixf(float *matf) void rlMultMatrixf(const float *matf)
{ {
// Matrix creation from array // Matrix creation from array
Matrix mat = { matf[0], matf[4], matf[8], matf[12], Matrix mat = { matf[0], matf[4], matf[8], matf[12],
@ -1661,6 +1678,17 @@ void rlEnableBackfaceCulling(void) { glEnable(GL_CULL_FACE); }
// Disable backface culling // Disable backface culling
void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); } void rlDisableBackfaceCulling(void) { glDisable(GL_CULL_FACE); }
// Set face culling mode
void rlSetCullFace(int mode)
{
switch (mode)
{
case RL_CULL_FACE_BACK: glCullFace(GL_BACK); break;
case RL_CULL_FACE_FRONT: glCullFace(GL_FRONT); break;
default: break;
}
}
// Enable scissor test // Enable scissor test
void rlEnableScissorTest(void) { glEnable(GL_SCISSOR_TEST); } void rlEnableScissorTest(void) { glEnable(GL_SCISSOR_TEST); }
@ -1788,7 +1816,7 @@ void rlCheckErrors()
void rlSetBlendMode(int mode) void rlSetBlendMode(int mode)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.State.currentBlendMode != mode) if ((RLGL.State.currentBlendMode != mode) || ((mode == RL_BLEND_CUSTOM || mode == RL_BLEND_CUSTOM_SEPARATE) && RLGL.State.glCustomBlendModeModified))
{ {
rlDrawRenderBatch(RLGL.currentBatch); rlDrawRenderBatch(RLGL.currentBatch);
@ -1804,11 +1832,20 @@ void rlSetBlendMode(int mode)
{ {
// NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors() // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors()
glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation);
} break;
case RL_BLEND_CUSTOM_SEPARATE:
{
// NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactorsSeparate()
glBlendFuncSeparate(RLGL.State.glBlendSrcFactorRGB, RLGL.State.glBlendDestFactorRGB, RLGL.State.glBlendSrcFactorAlpha, RLGL.State.glBlendDestFactorAlpha);
glBlendEquationSeparate(RLGL.State.glBlendEquationRGB, RLGL.State.glBlendEquationAlpha);
} break; } break;
default: break; default: break;
} }
RLGL.State.currentBlendMode = mode; RLGL.State.currentBlendMode = mode;
RLGL.State.glCustomBlendModeModified = false;
} }
#endif #endif
} }
@ -1817,9 +1854,39 @@ void rlSetBlendMode(int mode)
void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation) void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
RLGL.State.glBlendSrcFactor = glSrcFactor; if ((RLGL.State.glBlendSrcFactor != glSrcFactor) ||
RLGL.State.glBlendDstFactor = glDstFactor; (RLGL.State.glBlendDstFactor != glDstFactor) ||
RLGL.State.glBlendEquation = glEquation; (RLGL.State.glBlendEquation != glEquation))
{
RLGL.State.glBlendSrcFactor = glSrcFactor;
RLGL.State.glBlendDstFactor = glDstFactor;
RLGL.State.glBlendEquation = glEquation;
RLGL.State.glCustomBlendModeModified = true;
}
#endif
}
// Set blending mode factor and equation separately for RGB and alpha
void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if ((RLGL.State.glBlendSrcFactorRGB != glSrcRGB) ||
(RLGL.State.glBlendDestFactorRGB != glDstRGB) ||
(RLGL.State.glBlendSrcFactorAlpha != glSrcAlpha) ||
(RLGL.State.glBlendDestFactorAlpha != glDstAlpha) ||
(RLGL.State.glBlendEquationRGB != glEqRGB) ||
(RLGL.State.glBlendEquationAlpha != glEqAlpha))
{
RLGL.State.glBlendSrcFactorRGB = glSrcRGB;
RLGL.State.glBlendDestFactorRGB = glDstRGB;
RLGL.State.glBlendSrcFactorAlpha = glSrcAlpha;
RLGL.State.glBlendDestFactorAlpha = glDstAlpha;
RLGL.State.glBlendEquationRGB = glEqRGB;
RLGL.State.glBlendEquationAlpha = glEqAlpha;
RLGL.State.glCustomBlendModeModified = true;
}
#endif #endif
} }
@ -3988,7 +4055,7 @@ void rlCopyShaderBuffer(unsigned int destId, unsigned int srcId, unsigned int de
} }
// Bind image texture // Bind image texture
void rlBindImageTexture(unsigned int id, unsigned int index, unsigned int format, int readonly) void rlBindImageTexture(unsigned int id, unsigned int index, int format, bool readonly)
{ {
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
unsigned int glInternalFormat = 0, glFormat = 0, glType = 0; unsigned int glInternalFormat = 0, glFormat = 0, glType = 0;

View File

@ -397,151 +397,6 @@ void DrawCubeWiresV(Vector3 position, Vector3 size, Color color)
DrawCubeWires(position, size.x, size.y, size.z, color); DrawCubeWires(position, size.x, size.y, size.z, color);
} }
// Draw cube
// NOTE: Cube position is the center position
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float length, Color color)
{
float x = position.x;
float y = position.y;
float z = position.z;
rlSetTexture(texture.id);
//rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
//rlTranslatef(2.0f, 0.0f, 0.0f);
//rlRotatef(45, 0, 1, 0);
//rlScalef(2.0f, 2.0f, 2.0f);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front Face
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad
// Back Face
rlNormal3f(0.0f, 0.0f, - 1.0f); // Normal Pointing Away From Viewer
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad
// Top Face
rlNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
// Bottom Face
rlNormal3f(0.0f, - 1.0f, 0.0f); // Normal Pointing Down
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
// Right face
rlNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z - length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z - length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x + width/2, y + height/2, z + length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x + width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
// Left Face
rlNormal3f( - 1.0f, 0.0f, 0.0f); // Normal Pointing Left
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z - length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z + length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x - width/2, y + height/2, z - length/2); // Top Left Of The Texture and Quad
rlEnd();
//rlPopMatrix();
rlSetTexture(0);
}
// Draw cube with texture piece applied to all faces
void DrawCubeTextureRec(Texture2D texture, Rectangle source, Vector3 position, float width, float height, float length, Color color)
{
float x = position.x;
float y = position.y;
float z = position.z;
float texWidth = (float)texture.width;
float texHeight = (float)texture.height;
rlSetTexture(texture.id);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
// Front face
rlNormal3f(0.0f, 0.0f, 1.0f);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z + length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z + length/2);
// Back face
rlNormal3f(0.0f, 0.0f, - 1.0f);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z - length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z - length/2);
// Top face
rlNormal3f(0.0f, 1.0f, 0.0f);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y + height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y + height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z - length/2);
// Bottom face
rlNormal3f(0.0f, - 1.0f, 0.0f);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y - height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y - height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z + length/2);
// Right face
rlNormal3f(1.0f, 0.0f, 0.0f);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z - length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z - length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x + width/2, y + height/2, z + length/2);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x + width/2, y - height/2, z + length/2);
// Left face
rlNormal3f( - 1.0f, 0.0f, 0.0f);
rlTexCoord2f(source.x/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z - length/2);
rlTexCoord2f((source.x + source.width)/texWidth, (source.y + source.height)/texHeight);
rlVertex3f(x - width/2, y - height/2, z + length/2);
rlTexCoord2f((source.x + source.width)/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z + length/2);
rlTexCoord2f(source.x/texWidth, source.y/texHeight);
rlVertex3f(x - width/2, y + height/2, z - length/2);
rlEnd();
rlSetTexture(0);
}
// Draw sphere // Draw sphere
void DrawSphere(Vector3 centerPos, float radius, Color color) void DrawSphere(Vector3 centerPos, float radius, Color color)
{ {
@ -817,6 +672,284 @@ void DrawCylinderWiresEx(Vector3 startPos, Vector3 endPos, float startRadius, fl
rlEnd(); rlEnd();
} }
// Draw a capsule with the center of its sphere caps at startPos and endPos
void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color)
{
if (slices < 3) slices = 3;
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
// draw a sphere if start and end points are the same
bool sphereCase = (direction.x == 0) && (direction.y == 0) && (direction.z == 0);
if (sphereCase) direction = (Vector3){0.0f, 1.0f, 0.0f};
// Construct a basis of the base and the caps:
Vector3 b0 = Vector3Normalize(direction);
Vector3 b1 = Vector3Normalize(Vector3Perpendicular(direction));
Vector3 b2 = Vector3Normalize(Vector3CrossProduct(b1, direction));
Vector3 capCenter = endPos;
float baseSliceAngle = (2.0f*PI)/slices;
float baseRingAngle = PI * 0.5 / rings;
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
// render both caps
for (int c = 0; c < 2; c++)
{
for (int i = 0; i < rings; i++)
{
for (int j = 0; j < slices; j++)
{
// we build up the rings from capCenter in the direction of the 'direction' vector we computed earlier
// as we iterate through the rings they must be placed higher above the center, the height we need is sin(angle(i))
// as we iterate through the rings they must get smaller by the cos(angle(i))
// compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 ));
float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 ));
Vector3 w1 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin1*b1.x + ringCos1*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin1*b1.y + ringCos1*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin1*b1.z + ringCos1*b2.z) * radius
};
float ringSin2 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 ));
float ringCos2 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 ));
Vector3 w2 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin2*b1.x + ringCos2*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin2*b1.y + ringCos2*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin2*b1.z + ringCos2*b2.z) * radius
};
float ringSin3 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 ));
float ringCos3 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 ));
Vector3 w3 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin3*b1.x + ringCos3*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin3*b1.y + ringCos3*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin3*b1.z + ringCos3*b2.z) * radius
};
float ringSin4 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 ));
float ringCos4 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 ));
Vector3 w4 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin4*b1.x + ringCos4*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin4*b1.y + ringCos4*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin4*b1.z + ringCos4*b2.z) * radius
};
// make sure cap triangle normals are facing outwards
if(c == 0)
{
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w4.x, w4.y, w4.z);
rlVertex3f(w3.x, w3.y, w3.z);
}
else
{
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w4.x, w4.y, w4.z);
}
}
}
capCenter = startPos;
b0 = Vector3Scale(b0, -1.0f);
}
// render middle
if (!sphereCase)
{
for (int j = 0; j < slices; j++)
{
// compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*radius;
float ringCos1 = cosf(baseSliceAngle*(j + 0))*radius;
Vector3 w1 = {
startPos.x + ringSin1*b1.x + ringCos1*b2.x,
startPos.y + ringSin1*b1.y + ringCos1*b2.y,
startPos.z + ringSin1*b1.z + ringCos1*b2.z
};
float ringSin2 = sinf(baseSliceAngle*(j + 1))*radius;
float ringCos2 = cosf(baseSliceAngle*(j + 1))*radius;
Vector3 w2 = {
startPos.x + ringSin2*b1.x + ringCos2*b2.x,
startPos.y + ringSin2*b1.y + ringCos2*b2.y,
startPos.z + ringSin2*b1.z + ringCos2*b2.z
};
float ringSin3 = sinf(baseSliceAngle*(j + 0))*radius;
float ringCos3 = cosf(baseSliceAngle*(j + 0))*radius;
Vector3 w3 = {
endPos.x + ringSin3*b1.x + ringCos3*b2.x,
endPos.y + ringSin3*b1.y + ringCos3*b2.y,
endPos.z + ringSin3*b1.z + ringCos3*b2.z
};
float ringSin4 = sinf(baseSliceAngle*(j + 1))*radius;
float ringCos4 = cosf(baseSliceAngle*(j + 1))*radius;
Vector3 w4 = {
endPos.x + ringSin4*b1.x + ringCos4*b2.x,
endPos.y + ringSin4*b1.y + ringCos4*b2.y,
endPos.z + ringSin4*b1.z + ringCos4*b2.z
};
// w2 x.-----------x startPos
rlVertex3f(w1.x, w1.y, w1.z); // | |\'. T0 /
rlVertex3f(w2.x, w2.y, w2.z); // T1 | \ '. /
rlVertex3f(w3.x, w3.y, w3.z); // | |T \ '. /
// | 2 \ T 'x w1
rlVertex3f(w2.x, w2.y, w2.z); // | w4 x.---\-1-|---x endPos
rlVertex3f(w4.x, w4.y, w4.z); // T2 '. \ |T3/
rlVertex3f(w3.x, w3.y, w3.z); // | '. \ | /
// '.\|/
// 'x w3
}
}
rlEnd();
}
// Draw capsule wires with the center of its sphere caps at startPos and endPos
void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color)
{
if (slices < 3) slices = 3;
Vector3 direction = { endPos.x - startPos.x, endPos.y - startPos.y, endPos.z - startPos.z };
// draw a sphere if start and end points are the same
bool sphereCase = (direction.x == 0) && (direction.y == 0) && (direction.z == 0);
if (sphereCase) direction = (Vector3){0.0f, 1.0f, 0.0f};
// Construct a basis of the base and the caps:
Vector3 b0 = Vector3Normalize(direction);
Vector3 b1 = Vector3Normalize(Vector3Perpendicular(direction));
Vector3 b2 = Vector3Normalize(Vector3CrossProduct(b1, direction));
Vector3 capCenter = endPos;
float baseSliceAngle = (2.0f*PI)/slices;
float baseRingAngle = PI * 0.5 / rings;
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
// render both caps
for (int c = 0; c < 2; c++)
{
for (int i = 0; i < rings; i++)
{
for (int j = 0; j < slices; j++)
{
// we build up the rings from capCenter in the direction of the 'direction' vector we computed earlier
// as we iterate through the rings they must be placed higher above the center, the height we need is sin(angle(i))
// as we iterate through the rings they must get smaller by the cos(angle(i))
// compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 ));
float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 0 ));
Vector3 w1 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin1*b1.x + ringCos1*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin1*b1.y + ringCos1*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin1*b1.z + ringCos1*b2.z) * radius
};
float ringSin2 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 ));
float ringCos2 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 0 ));
Vector3 w2 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 0 ))*b0.x + ringSin2*b1.x + ringCos2*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 0 ))*b0.y + ringSin2*b1.y + ringCos2*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 0 ))*b0.z + ringSin2*b1.z + ringCos2*b2.z) * radius
};
float ringSin3 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 ));
float ringCos3 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle * ( i + 1 ));
Vector3 w3 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin3*b1.x + ringCos3*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin3*b1.y + ringCos3*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin3*b1.z + ringCos3*b2.z) * radius
};
float ringSin4 = sinf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 ));
float ringCos4 = cosf(baseSliceAngle*(j + 1))*cosf(baseRingAngle * ( i + 1 ));
Vector3 w4 = (Vector3){
capCenter.x + (sinf(baseRingAngle * ( i + 1 ))*b0.x + ringSin4*b1.x + ringCos4*b2.x) * radius,
capCenter.y + (sinf(baseRingAngle * ( i + 1 ))*b0.y + ringSin4*b1.y + ringCos4*b2.y) * radius,
capCenter.z + (sinf(baseRingAngle * ( i + 1 ))*b0.z + ringSin4*b1.z + ringCos4*b2.z) * radius
};
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w4.x, w4.y, w4.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w4.x, w4.y, w4.z);
}
}
capCenter = startPos;
b0 = Vector3Scale(b0, -1.0f);
}
// render middle
if (!sphereCase)
{
for (int j = 0; j < slices; j++)
{
// compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*radius;
float ringCos1 = cosf(baseSliceAngle*(j + 0))*radius;
Vector3 w1 = {
startPos.x + ringSin1*b1.x + ringCos1*b2.x,
startPos.y + ringSin1*b1.y + ringCos1*b2.y,
startPos.z + ringSin1*b1.z + ringCos1*b2.z
};
float ringSin2 = sinf(baseSliceAngle*(j + 1))*radius;
float ringCos2 = cosf(baseSliceAngle*(j + 1))*radius;
Vector3 w2 = {
startPos.x + ringSin2*b1.x + ringCos2*b2.x,
startPos.y + ringSin2*b1.y + ringCos2*b2.y,
startPos.z + ringSin2*b1.z + ringCos2*b2.z
};
float ringSin3 = sinf(baseSliceAngle*(j + 0))*radius;
float ringCos3 = cosf(baseSliceAngle*(j + 0))*radius;
Vector3 w3 = {
endPos.x + ringSin3*b1.x + ringCos3*b2.x,
endPos.y + ringSin3*b1.y + ringCos3*b2.y,
endPos.z + ringSin3*b1.z + ringCos3*b2.z
};
float ringSin4 = sinf(baseSliceAngle*(j + 1))*radius;
float ringCos4 = cosf(baseSliceAngle*(j + 1))*radius;
Vector3 w4 = {
endPos.x + ringSin4*b1.x + ringCos4*b2.x,
endPos.y + ringSin4*b1.y + ringCos4*b2.y,
endPos.z + ringSin4*b1.z + ringCos4*b2.z
};
rlVertex3f(w1.x, w1.y, w1.z);
rlVertex3f(w3.x, w3.y, w3.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w4.x, w4.y, w4.z);
rlVertex3f(w2.x, w2.y, w2.z);
rlVertex3f(w3.x, w3.y, w3.z);
}
}
rlEnd();
}
// Draw a plane // Draw a plane
void DrawPlane(Vector3 centerPos, Vector2 size, Color color) void DrawPlane(Vector3 centerPos, Vector2 size, Color color)
{ {
@ -1839,13 +1972,14 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
for (int m = 0; m < model.meshCount; m++) for (int m = 0; m < model.meshCount; m++)
{ {
Mesh mesh = model.meshes[m]; Mesh mesh = model.meshes[m];
if (mesh.boneIds == NULL || mesh.boneWeights == NULL) if (mesh.boneIds == NULL || mesh.boneWeights == NULL)
{ {
TRACELOG(LOG_WARNING, "MODEL: UpdateModelAnimation Mesh %i has no connection to bones",m); TRACELOG(LOG_WARNING, "MODEL: UpdateModelAnimation(): Mesh %i has no connection to bones", m);
continue; continue;
} }
bool updated = false; // set to true when anim vertex information is updated bool updated = false; // Flag to check when anim vertex information is updated
Vector3 animVertex = { 0 }; Vector3 animVertex = { 0 };
Vector3 animNormal = { 0 }; Vector3 animNormal = { 0 };
@ -1862,13 +1996,13 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
float boneWeight = 0.0; float boneWeight = 0.0;
const int vValues = mesh.vertexCount*3; const int vValues = mesh.vertexCount*3;
for (int vCounter = 0; vCounter < vValues; vCounter+=3) for (int vCounter = 0; vCounter < vValues; vCounter += 3)
{ {
mesh.animVertices[vCounter] = 0; mesh.animVertices[vCounter] = 0;
mesh.animVertices[vCounter + 1] = 0; mesh.animVertices[vCounter + 1] = 0;
mesh.animVertices[vCounter + 2] = 0; mesh.animVertices[vCounter + 2] = 0;
if (mesh.animNormals!=NULL) if (mesh.animNormals != NULL)
{ {
mesh.animNormals[vCounter] = 0; mesh.animNormals[vCounter] = 0;
mesh.animNormals[vCounter + 1] = 0; mesh.animNormals[vCounter + 1] = 0;
@ -1879,16 +2013,15 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
for (int j = 0; j < 4; j++, boneCounter++) for (int j = 0; j < 4; j++, boneCounter++)
{ {
boneWeight = mesh.boneWeights[boneCounter]; boneWeight = mesh.boneWeights[boneCounter];
// early stop when no transformation will be applied
if (boneWeight == 0.0f) // Early stop when no transformation will be applied
{ if (boneWeight == 0.0f) continue;
continue;
}
boneId = mesh.boneIds[boneCounter]; boneId = mesh.boneIds[boneCounter];
//int boneIdParent = model.bones[boneId].parent; //int boneIdParent = model.bones[boneId].parent;
inTranslation = model.bindPose[boneId].translation; inTranslation = model.bindPose[boneId].translation;
inRotation = model.bindPose[boneId].rotation; inRotation = model.bindPose[boneId].rotation;
// inScale = model.bindPose[boneId].scale; //inScale = model.bindPose[boneId].scale;
outTranslation = anim.framePoses[frame][boneId].translation; outTranslation = anim.framePoses[frame][boneId].translation;
outRotation = anim.framePoses[frame][boneId].rotation; outRotation = anim.framePoses[frame][boneId].rotation;
outScale = anim.framePoses[frame][boneId].scale; outScale = anim.framePoses[frame][boneId].scale;
@ -1900,7 +2033,7 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
animVertex = Vector3Subtract(animVertex, inTranslation); animVertex = Vector3Subtract(animVertex, inTranslation);
animVertex = Vector3RotateByQuaternion(animVertex, QuaternionMultiply(outRotation, QuaternionInvert(inRotation))); animVertex = Vector3RotateByQuaternion(animVertex, QuaternionMultiply(outRotation, QuaternionInvert(inRotation)));
animVertex = Vector3Add(animVertex, outTranslation); animVertex = Vector3Add(animVertex, outTranslation);
// animVertex = Vector3Transform(animVertex, model.transform); //animVertex = Vector3Transform(animVertex, model.transform);
mesh.animVertices[vCounter] += animVertex.x*boneWeight; mesh.animVertices[vCounter] += animVertex.x*boneWeight;
mesh.animVertices[vCounter + 1] += animVertex.y*boneWeight; mesh.animVertices[vCounter + 1] += animVertex.y*boneWeight;
mesh.animVertices[vCounter + 2] += animVertex.z*boneWeight; mesh.animVertices[vCounter + 2] += animVertex.z*boneWeight;
@ -1920,10 +2053,11 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
} }
// Upload new vertex data to GPU for model drawing // Upload new vertex data to GPU for model drawing
// Only update data when values changed. // NOTE: Only update data when values changed
if (updated){ if (updated)
rlUpdateVertexBuffer(mesh.vboId[0], mesh.animVertices, mesh.vertexCount*3*sizeof(float), 0); // Update vertex position {
rlUpdateVertexBuffer(mesh.vboId[2], mesh.animNormals, mesh.vertexCount*3*sizeof(float), 0); // Update vertex normals rlUpdateVertexBuffer(mesh.vboId[0], mesh.animVertices, mesh.vertexCount*3*sizeof(float), 0); // Update vertex position
rlUpdateVertexBuffer(mesh.vboId[2], mesh.animNormals, mesh.vertexCount*3*sizeof(float), 0); // Update vertex normals
} }
} }
} }

View File

@ -58,6 +58,7 @@
#include <math.h> // Required for: sinf(), asinf(), cosf(), acosf(), sqrtf(), fabsf() #include <math.h> // Required for: sinf(), asinf(), cosf(), acosf(), sqrtf(), fabsf()
#include <float.h> // Required for: FLT_EPSILON #include <float.h> // Required for: FLT_EPSILON
#include <stdlib.h> // Required for: RL_FREE
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
@ -104,21 +105,50 @@ void SetShapesTexture(Texture2D texture, Rectangle source)
// Draw a pixel // Draw a pixel
void DrawPixel(int posX, int posY, Color color) void DrawPixel(int posX, int posY, Color color)
{ {
rlBegin(RL_LINES); DrawPixelV((Vector2){ posX, posY }, color);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(posX, posY);
rlVertex2f(posX + 1, posY + 1);
rlEnd();
} }
// Draw a pixel (Vector version) // Draw a pixel (Vector version)
void DrawPixelV(Vector2 position, Color color) void DrawPixelV(Vector2 position, Color color)
{ {
rlBegin(RL_LINES); #if defined(SUPPORT_QUADS_DRAW_MODE)
rlSetTexture(texShapes.id);
rlBegin(RL_QUADS);
rlNormal3f(0.0f, 0.0f, 1.0f);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(position.x, position.y); rlVertex2f(position.x, position.y);
rlVertex2f(position.x + 1.0f, position.y + 1.0f);
rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(position.x, position.y + 1);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height);
rlVertex2f(position.x + 1, position.y + 1);
rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(position.x + 1, position.y);
rlEnd(); rlEnd();
rlSetTexture(0);
#else
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(position.x, position.y);
rlVertex2f(position.x, position.y + 1);
rlVertex2f(position.x + 1, position.y);
rlVertex2f(position.x + 1, position.y);
rlVertex2f(position.x, position.y + 1);
rlVertex2f(position.x + 1, position.y + 1);
rlEnd();
#endif
} }
// Draw a line // Draw a line
@ -168,6 +198,8 @@ void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color)
Vector2 previous = startPos; Vector2 previous = startPos;
Vector2 current = { 0 }; Vector2 current = { 0 };
Vector2 points[2*BEZIER_LINE_DIVISIONS + 2] = { 0 };
for (int i = 1; i <= BEZIER_LINE_DIVISIONS; i++) for (int i = 1; i <= BEZIER_LINE_DIVISIONS; i++)
{ {
// Cubic easing in-out // Cubic easing in-out
@ -175,10 +207,27 @@ void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color)
current.y = EaseCubicInOut((float)i, startPos.y, endPos.y - startPos.y, (float)BEZIER_LINE_DIVISIONS); current.y = EaseCubicInOut((float)i, startPos.y, endPos.y - startPos.y, (float)BEZIER_LINE_DIVISIONS);
current.x = previous.x + (endPos.x - startPos.x)/ (float)BEZIER_LINE_DIVISIONS; current.x = previous.x + (endPos.x - startPos.x)/ (float)BEZIER_LINE_DIVISIONS;
DrawLineEx(previous, current, thick, color); float dy = current.y-previous.y;
float dx = current.x-previous.x;
float size = 0.5*thick/sqrt(dx*dx+dy*dy);
if (i==1)
{
points[0].x = previous.x+dy*size;
points[0].y = previous.y-dx*size;
points[1].x = previous.x-dy*size;
points[1].y = previous.y+dx*size;
}
points[2*i+1].x = current.x-dy*size;
points[2*i+1].y = current.y+dx*size;
points[2*i].x = current.x+dy*size;
points[2*i].y = current.y-dx*size;
previous = current; previous = current;
} }
DrawTriangleStrip(points, 2*BEZIER_LINE_DIVISIONS+2, color);
} }
// Draw line using quadratic bezier curves with a control point // Draw line using quadratic bezier curves with a control point
@ -190,6 +239,8 @@ void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, fl
Vector2 current = { 0 }; Vector2 current = { 0 };
float t = 0.0f; float t = 0.0f;
Vector2 points[2*BEZIER_LINE_DIVISIONS + 2] = { 0 };
for (int i = 0; i <= BEZIER_LINE_DIVISIONS; i++) for (int i = 0; i <= BEZIER_LINE_DIVISIONS; i++)
{ {
t = step*i; t = step*i;
@ -201,10 +252,27 @@ void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, fl
current.y = a*startPos.y + b*controlPos.y + c*endPos.y; current.y = a*startPos.y + b*controlPos.y + c*endPos.y;
current.x = a*startPos.x + b*controlPos.x + c*endPos.x; current.x = a*startPos.x + b*controlPos.x + c*endPos.x;
DrawLineEx(previous, current, thick, color); float dy = current.y-previous.y;
float dx = current.x-previous.x;
float size = 0.5*thick/sqrt(dx*dx+dy*dy);
if (i==1)
{
points[0].x = previous.x+dy*size;
points[0].y = previous.y-dx*size;
points[1].x = previous.x-dy*size;
points[1].y = previous.y+dx*size;
}
points[2*i+1].x = current.x-dy*size;
points[2*i+1].y = current.y+dx*size;
points[2*i].x = current.x+dy*size;
points[2*i].y = current.y-dx*size;
previous = current; previous = current;
} }
DrawTriangleStrip(points, 2*BEZIER_LINE_DIVISIONS+2, color);
} }
// Draw line using cubic bezier curves with 2 control points // Draw line using cubic bezier curves with 2 control points
@ -216,6 +284,8 @@ void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlP
Vector2 current = { 0 }; Vector2 current = { 0 };
float t = 0.0f; float t = 0.0f;
Vector2 points[2*BEZIER_LINE_DIVISIONS + 2] = { 0 };
for (int i = 0; i <= BEZIER_LINE_DIVISIONS; i++) for (int i = 0; i <= BEZIER_LINE_DIVISIONS; i++)
{ {
t = step*i; t = step*i;
@ -227,10 +297,27 @@ void DrawLineBezierCubic(Vector2 startPos, Vector2 endPos, Vector2 startControlP
current.y = a*startPos.y + b*startControlPos.y + c*endControlPos.y + d*endPos.y; current.y = a*startPos.y + b*startControlPos.y + c*endControlPos.y + d*endPos.y;
current.x = a*startPos.x + b*startControlPos.x + c*endControlPos.x + d*endPos.x; current.x = a*startPos.x + b*startControlPos.x + c*endControlPos.x + d*endPos.x;
DrawLineEx(previous, current, thick, color); float dy = current.y-previous.y;
float dx = current.x-previous.x;
float size = 0.5*thick/sqrt(dx*dx+dy*dy);
if (i==1)
{
points[0].x = previous.x+dy*size;
points[0].y = previous.y-dx*size;
points[1].x = previous.x-dy*size;
points[1].y = previous.y+dx*size;
}
points[2*i+1].x = current.x-dy*size;
points[2*i+1].y = current.y+dx*size;
points[2*i].x = current.x+dy*size;
points[2*i].y = current.y-dx*size;
previous = current; previous = current;
} }
DrawTriangleStrip(points, 2*BEZIER_LINE_DIVISIONS+2, color);
} }
// Draw lines sequence // Draw lines sequence

View File

@ -58,7 +58,7 @@
#if defined(SUPPORT_MODULE_RTEXT) #if defined(SUPPORT_MODULE_RTEXT)
#include "utils.h" // Required for: LoadFileText() #include "utils.h" // Required for: LoadFile*()
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro() #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro()
#include <stdlib.h> // Required for: malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
@ -359,7 +359,7 @@ Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCou
// Loading font from memory data // Loading font from memory data
font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, glyphCount); font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, glyphCount);
RL_FREE(fileData); UnloadFileData(fileData);
} }
else font = GetFontDefault(); else font = GetFontDefault();

View File

@ -194,6 +194,10 @@
#define PIXELFORMAT_UNCOMPRESSED_R5G5B5A1_ALPHA_THRESHOLD 50 // Threshold over 255 to set alpha as 0 #define PIXELFORMAT_UNCOMPRESSED_R5G5B5A1_ALPHA_THRESHOLD 50 // Threshold over 255 to set alpha as 0
#endif #endif
#ifndef GAUSSIAN_BLUR_ITERATIONS
#define GAUSSIAN_BLUR_ITERATIONS 4 // Number of box blur iterations to approximate gaussian blur
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -402,7 +406,6 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
#if defined(SUPPORT_FILEFORMAT_DDS) #if defined(SUPPORT_FILEFORMAT_DDS)
else if (strcmp(fileType, ".dds") == 0) else if (strcmp(fileType, ".dds") == 0)
{ {
int format = 0;
image.data = rl_load_dds_from_memory(fileData, dataSize, &image.width, &image.height, &image.format, &image.mipmaps); image.data = rl_load_dds_from_memory(fileData, dataSize, &image.width, &image.height, &image.format, &image.mipmaps);
} }
#endif #endif
@ -894,6 +897,25 @@ Image GenImageCellular(int width, int height, int tileSize)
return image; return image;
} }
// Generate image: grayscale image from text data
Image GenImageText(int width, int height, const char *text)
{
Image image = { 0 };
int textLength = TextLength(text);
int imageViewSize = width*height;
image.width = width;
image.height = height;
image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
image.data = RL_CALLOC(imageViewSize, 1);
image.mipmaps = 1;
memcpy(image.data, text, (textLength > imageViewSize)? imageViewSize : textLength);
return image;
}
#endif // SUPPORT_IMAGE_GENERATION #endif // SUPPORT_IMAGE_GENERATION
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -1230,6 +1252,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
// NOTE: Text image is generated at font base size, later scaled to desired font size // NOTE: Text image is generated at font base size, later scaled to desired font size
Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing); // WARNING: Module required: rtext Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing); // WARNING: Module required: rtext
Vector2 textSize = MeasureTextEx(font, text, fontSize, spacing);
// Create image to store text // Create image to store text
imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK); imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK);
@ -1268,12 +1291,13 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
} }
// Scale image depending on text size // Scale image depending on text size
if (fontSize > imSize.y) if (textSize.y != imSize.y)
{ {
float scaleFactor = fontSize/imSize.y; float scaleFactor = textSize.y / imSize.y;
TRACELOG(LOG_INFO, "IMAGE: Text scaled by factor: %f", scaleFactor); TRACELOG(LOG_INFO, "IMAGE: Text scaled by factor: %f", scaleFactor);
// Using nearest-neighbor scaling algorithm for default font // Using nearest-neighbor scaling algorithm for default font
// TODO: Allow defining the preferred scaling mechanism externally
// WARNING: Module required: rtext // WARNING: Module required: rtext
if (font.texture.id == GetFontDefault().texture.id) ImageResizeNN(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor)); if (font.texture.id == GetFontDefault().texture.id) ImageResizeNN(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
else ImageResize(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor)); else ImageResize(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
@ -1475,6 +1499,158 @@ void ImageAlphaPremultiply(Image *image)
ImageFormat(image, format); ImageFormat(image, format);
} }
// Apply box blur
void ImageBlurGaussian(Image *image, int blurSize) {
// Security check to avoid program crash
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
ImageAlphaPremultiply(image);
Color *pixels = LoadImageColors(*image);
// Loop switches between pixelsCopy1 and pixelsCopy2
Vector4 *pixelsCopy1 = RL_MALLOC((image->height)*(image->width)*sizeof(Vector4));
Vector4 *pixelsCopy2 = RL_MALLOC((image->height)*(image->width)*sizeof(Vector4));
for (int i = 0; i < (image->height)*(image->width); i++) {
pixelsCopy1[i].x = pixels[i].r;
pixelsCopy1[i].y = pixels[i].g;
pixelsCopy1[i].z = pixels[i].b;
pixelsCopy1[i].w = pixels[i].a;
}
// Repeated convolution of rectangular window signal by itself converges to a gaussian distribution
for (int j = 0; j < GAUSSIAN_BLUR_ITERATIONS; j++) {
// Horizontal motion blur
for (int row = 0; row < image->height; row++)
{
float avgR = 0.0f;
float avgG = 0.0f;
float avgB = 0.0f;
float avgAlpha = 0.0f;
int convolutionSize = blurSize+1;
for (int i = 0; i < blurSize+1; i++)
{
avgR += pixelsCopy1[row*image->width + i].x;
avgG += pixelsCopy1[row*image->width + i].y;
avgB += pixelsCopy1[row*image->width + i].z;
avgAlpha += pixelsCopy1[row*image->width + i].w;
}
pixelsCopy2[row*image->width].x = avgR/convolutionSize;
pixelsCopy2[row*image->width].y = avgG/convolutionSize;
pixelsCopy2[row*image->width].z = avgB/convolutionSize;
pixelsCopy2[row*image->width].w = avgAlpha/convolutionSize;
for (int x = 1; x < image->width; x++)
{
if (x-blurSize >= 0)
{
avgR -= pixelsCopy1[row*image->width + x-blurSize].x;
avgG -= pixelsCopy1[row*image->width + x-blurSize].y;
avgB -= pixelsCopy1[row*image->width + x-blurSize].z;
avgAlpha -= pixelsCopy1[row*image->width + x-blurSize].w;
convolutionSize--;
}
if (x+blurSize < image->width)
{
avgR += pixelsCopy1[row*image->width + x+blurSize].x;
avgG += pixelsCopy1[row*image->width + x+blurSize].y;
avgB += pixelsCopy1[row*image->width + x+blurSize].z;
avgAlpha += pixelsCopy1[row*image->width + x+blurSize].w;
convolutionSize++;
}
pixelsCopy2[row*image->width + x].x = avgR/convolutionSize;
pixelsCopy2[row*image->width + x].y = avgG/convolutionSize;
pixelsCopy2[row*image->width + x].z = avgB/convolutionSize;
pixelsCopy2[row*image->width + x].w = avgAlpha/convolutionSize;
}
}
// Vertical motion blur
for (int col = 0; col < image->width; col++)
{
float avgR = 0.0f;
float avgG = 0.0f;
float avgB = 0.0f;
float avgAlpha = 0.0f;
int convolutionSize = blurSize+1;
for (int i = 0; i < blurSize+1; i++)
{
avgR += pixelsCopy2[i*image->width + col].x;
avgG += pixelsCopy2[i*image->width + col].y;
avgB += pixelsCopy2[i*image->width + col].z;
avgAlpha += pixelsCopy2[i*image->width + col].w;
}
pixelsCopy1[col].x = (unsigned char) (avgR/convolutionSize);
pixelsCopy1[col].y = (unsigned char) (avgG/convolutionSize);
pixelsCopy1[col].z = (unsigned char) (avgB/convolutionSize);
pixelsCopy1[col].w = (unsigned char) (avgAlpha/convolutionSize);
for (int y = 1; y < image->height; y++)
{
if (y-blurSize >= 0)
{
avgR -= pixelsCopy2[(y-blurSize)*image->width + col].x;
avgG -= pixelsCopy2[(y-blurSize)*image->width + col].y;
avgB -= pixelsCopy2[(y-blurSize)*image->width + col].z;
avgAlpha -= pixelsCopy2[(y-blurSize)*image->width + col].w;
convolutionSize--;
}
if (y+blurSize < image->height)
{
avgR += pixelsCopy2[(y+blurSize)*image->width + col].x;
avgG += pixelsCopy2[(y+blurSize)*image->width + col].y;
avgB += pixelsCopy2[(y+blurSize)*image->width + col].z;
avgAlpha += pixelsCopy2[(y+blurSize)*image->width + col].w;
convolutionSize++;
}
pixelsCopy1[y*image->width + col].x = (unsigned char) (avgR/convolutionSize);
pixelsCopy1[y*image->width + col].y = (unsigned char) (avgG/convolutionSize);
pixelsCopy1[y*image->width + col].z = (unsigned char) (avgB/convolutionSize);
pixelsCopy1[y*image->width + col].w = (unsigned char) (avgAlpha/convolutionSize);
}
}
}
// Reverse premultiply
for (int i = 0; i < (image->width)*(image->height); i++)
{
if (pixelsCopy1[i].w == 0.0f)
{
pixels[i].r = 0;
pixels[i].g = 0;
pixels[i].b = 0;
pixels[i].a = 0;
}
else if (pixelsCopy1[i].w <= 255.0f)
{
float alpha = (float)pixelsCopy1[i].w/255.0f;
pixels[i].r = (unsigned char)((float)pixelsCopy1[i].x/alpha);
pixels[i].g = (unsigned char)((float)pixelsCopy1[i].y/alpha);
pixels[i].b = (unsigned char)((float)pixelsCopy1[i].z/alpha);
pixels[i].a = (unsigned char) pixelsCopy1[i].w;
}
}
int format = image->format;
RL_FREE(image->data);
RL_FREE(pixelsCopy1);
RL_FREE(pixelsCopy2);
image->data = pixels;
image->format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format);
}
// Resize and image to new size // Resize and image to new size
// NOTE: Uses stb default scaling filters (both bicubic): // NOTE: Uses stb default scaling filters (both bicubic):
// STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM // STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM
@ -3436,104 +3612,6 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
} }
} }
// Draw texture quad with tiling and offset parameters
// NOTE: Tiling and offset should be provided considering normalized texture values [0..1]
// i.e tiling = { 1.0f, 1.0f } refers to all texture, offset = { 0.5f, 0.5f } moves texture origin to center
void DrawTextureQuad(Texture2D texture, Vector2 tiling, Vector2 offset, Rectangle quad, Color tint)
{
// WARNING: This solution only works if TEXTURE_WRAP_REPEAT is supported,
// NPOT textures supported is required and OpenGL ES 2.0 could not support it
Rectangle source = { offset.x*texture.width, offset.y*texture.height, tiling.x*texture.width, tiling.y*texture.height };
Vector2 origin = { 0.0f, 0.0f };
DrawTexturePro(texture, source, quad, origin, 0.0f, tint);
}
// Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest.
// NOTE: For tilling a whole texture DrawTextureQuad() is better
void DrawTextureTiled(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint)
{
if ((texture.id <= 0) || (scale <= 0.0f)) return; // Wanna see a infinite loop?!...just delete this line!
if ((source.width == 0) || (source.height == 0)) return;
int tileWidth = (int)(source.width*scale), tileHeight = (int)(source.height*scale);
if ((dest.width < tileWidth) && (dest.height < tileHeight))
{
// Can fit only one tile
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)dest.width/tileWidth)*source.width, ((float)dest.height/tileHeight)*source.height},
(Rectangle){dest.x, dest.y, dest.width, dest.height}, origin, rotation, tint);
}
else if (dest.width <= tileWidth)
{
// Tiled vertically (one column)
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)dest.width/tileWidth)*source.width, source.height}, (Rectangle){dest.x, dest.y + dy, dest.width, (float)tileHeight}, origin, rotation, tint);
}
// Fit last tile
if (dy < dest.height)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)dest.width/tileWidth)*source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
(Rectangle){dest.x, dest.y + dy, dest.width, dest.height - dy}, origin, rotation, tint);
}
}
else if (dest.height <= tileHeight)
{
// Tiled horizontally (one row)
int dx = 0;
for (;dx+tileWidth < dest.width; dx += tileWidth)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, source.width, ((float)dest.height/tileHeight)*source.height}, (Rectangle){dest.x + dx, dest.y, (float)tileWidth, dest.height}, origin, rotation, tint);
}
// Fit last tile
if (dx < dest.width)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, ((float)dest.height/tileHeight)*source.height},
(Rectangle){dest.x + dx, dest.y, dest.width - dx, dest.height}, origin, rotation, tint);
}
}
else
{
// Tiled both horizontally and vertically (rows and columns)
int dx = 0;
for (;dx+tileWidth < dest.width; dx += tileWidth)
{
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, source, (Rectangle){dest.x + dx, dest.y + dy, (float)tileWidth, (float)tileHeight}, origin, rotation, tint);
}
if (dy < dest.height)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
(Rectangle){dest.x + dx, dest.y + dy, (float)tileWidth, dest.height - dy}, origin, rotation, tint);
}
}
// Fit last column of tiles
if (dx < dest.width)
{
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, source.height},
(Rectangle){dest.x + dx, dest.y + dy, dest.width - dx, (float)tileHeight}, origin, rotation, tint);
}
// Draw final tile in the bottom right corner
if (dy < dest.height)
{
DrawTexturePro(texture, (Rectangle){source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
(Rectangle){dest.x + dx, dest.y + dy, dest.width - dx, dest.height - dy}, origin, rotation, tint);
}
}
}
}
// Draws a texture (or part of it) that stretches or shrinks nicely using n-patch info // Draws a texture (or part of it) that stretches or shrinks nicely using n-patch info
void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint) void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint)
{ {
@ -3731,37 +3809,6 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest,
} }
} }
// Draw textured polygon, defined by vertex and texturecoordinates
// NOTE: Polygon center must have straight line path to all points
// without crossing perimeter, points must be in anticlockwise order
void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointCount, Color tint)
{
rlSetTexture(texture.id);
// Texturing is only supported on RL_QUADS
rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
for (int i = 0; i < pointCount - 1; i++)
{
rlTexCoord2f(0.5f, 0.5f);
rlVertex2f(center.x, center.y);
rlTexCoord2f(texcoords[i].x, texcoords[i].y);
rlVertex2f(points[i].x + center.x, points[i].y + center.y);
rlTexCoord2f(texcoords[i + 1].x, texcoords[i + 1].y);
rlVertex2f(points[i + 1].x + center.x, points[i + 1].y + center.y);
rlTexCoord2f(texcoords[i + 1].x, texcoords[i + 1].y);
rlVertex2f(points[i + 1].x + center.x, points[i + 1].y + center.y);
}
rlEnd();
rlSetTexture(0);
}
// Get color with alpha applied, alpha goes from 0.0f to 1.0f // Get color with alpha applied, alpha goes from 0.0f to 1.0f
Color Fade(Color color, float alpha) Color Fade(Color color, float alpha)
{ {

View File

@ -270,7 +270,7 @@ bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite)
} }
// Export data to code (.h), returns true on success // Export data to code (.h), returns true on success
bool ExportDataAsCode(const char *data, unsigned int size, const char *fileName) bool ExportDataAsCode(const unsigned char *data, unsigned int size, const char *fileName)
{ {
bool success = false; bool success = false;