Merge branch 'master' into drm_gamepad_polling
1
.gitignore
vendored
|
|
@ -54,6 +54,7 @@ packages/
|
|||
*.bc
|
||||
*.so
|
||||
*.so.*
|
||||
*.dll
|
||||
|
||||
# Ignore wasm data in examples/
|
||||
examples/**/*.wasm
|
||||
|
|
|
|||
22
BINDINGS.md
|
|
@ -6,7 +6,8 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
|
||||
| name | raylib version | language | license | repo |
|
||||
|:------------------:|:---------------:|:---------:|:----------:|-----------------------------------------------------------|
|
||||
| raylib | **4.5** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib | https://github.com/raysan5/raylib |
|
||||
| raylib | **5.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib | https://github.com/raysan5/raylib |
|
||||
| raylib-beef | **5.0** | [Beef](https://www.beeflang.org/) | MIT | https://github.com/Starpelly/raylib-beef |
|
||||
| raylib-boo | 3.7 | [Boo](http://boo-language.github.io/)| MIT | https://github.com/Rabios/raylib-boo |
|
||||
| Raylib-cs | **4.5** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib | https://github.com/ChrisDill/Raylib-cs |
|
||||
| Raylib-CsLo | 4.2 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | https://github.com/NotNotTech/Raylib-CsLo |
|
||||
|
|
@ -20,20 +21,20 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| dart-raylib | 4.0 | [Dart](https://dart.dev/) | MIT | https://gitlab.com/wolfenrain/dart-raylib |
|
||||
| bindbc-raylib3 | **4.5** | [D](https://dlang.org/) | BSL-1.0 | https://github.com/o3o/bindbc-raylib3 |
|
||||
| dray | 4.2 | [D](https://dlang.org/) | Apache-2.0 | https://github.com/redthing1/dray |
|
||||
| raylib-d | **4.5** | [D](https://dlang.org/) | Zlib | https://github.com/schveiguy/raylib-d |
|
||||
| raylib-d | **5.0** | [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 |
|
||||
| rayex | 3.7 | [elixir](https://elixir-lang.org/) | Apache-2.0 | https://github.com/shiryel/rayex |
|
||||
| raylib-factor | **4.5** | [Factor](https://factorcode.org/) | BSD | https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor |
|
||||
| raylib-freebasic | **4.5** | [FreeBASIC](https://www.freebasic.net/) | MIT | https://github.com/WIITD/raylib-freebasic |
|
||||
| raylib-freebasic | **5.0** | [FreeBASIC](https://www.freebasic.net/) | MIT | https://github.com/WIITD/raylib-freebasic |
|
||||
| fortran-raylib | **4.5** | [Fortran](https://fortran-lang.org/) | ISC | https://github.com/interkosmos/fortran-raylib |
|
||||
| raylib for Pascal | **4.5** | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | Modified Zlib | https://github.com/tinyBigGAMES/raylib |
|
||||
| raylib-go | **5.0** | [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 |
|
||||
| gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | MIT | https://github.com/ArnautDaniel/gforth-raylib |
|
||||
| gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | **???** | https://github.com/ArnautDaniel/gforth-raylib |
|
||||
| h-raylib | **4.6-dev** | [Haskell](https://haskell.org/) | Apache-2.0 | https://github.com/Anut-py/h-raylib |
|
||||
| raylib-hx | 4.2 | [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 |
|
||||
| jaylib | 4.5 | [Janet](https://janet-lang.org/) | MIT | https://github.com/janet-lang/jaylib |
|
||||
| jaylib | 5.0 | [Janet](https://janet-lang.org/) | MIT | https://github.com/janet-lang/jaylib |
|
||||
| jaylib | **4.5** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3+CE | https://github.com/electronstudio/jaylib/ |
|
||||
| raylib-j | 4.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | https://github.com/CreedVI/Raylib-J |
|
||||
| raylib.jl | 4.2 | [Julia](https://julialang.org/) | Zlib | https://github.com/irishgreencitrus/raylib.jl |
|
||||
|
|
@ -43,7 +44,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| raylua | 4.0 | [Lua](http://www.lua.org/) | MIT | https://github.com/Rabios/raylua |
|
||||
| raylib-matte | 4.6-dev | [Matte](https://github.com/jcorks/matte/) | MIT | https://github.com/jcorks/raylib-matte |
|
||||
| nelua-raylib | 4.0 | [nelua](https://nelua.io/) | MIT | https://github.com/AKDev21/nelua-raylib |
|
||||
| Raylib.nelua | **4.5** | [nelua](https://nelua.io/) | Zlib | https://github.com/Its-Kenta/Raylib-Nelua |
|
||||
| Raylib.nelua | **5.0** | [nelua](https://nelua.io/) | Zlib | https://github.com/AuzFox/Raylib.nelua |
|
||||
| NimraylibNow! | 4.2 | [Nim](https://nim-lang.org/) | MIT | https://github.com/greenfork/nimraylib_now |
|
||||
| raylib-bindings | **4.5** | [Ruby](https://www.ruby-lang.org/en/) | Zlib | https://github.com/vaiorabbit/raylib-bindings |
|
||||
| raylib-Forever | auto | [Nim](https://nim-lang.org/) | ? | https://github.com/Guevara-chan/Raylib-Forever |
|
||||
|
|
@ -53,12 +54,12 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| raylib_odin_bindings | 4.0-dev | [Odin](https://odin-lang.org/) | MIT | https://github.com/Deathbat2190/raylib_odin_bindings |
|
||||
| raylib-ocaml | **4.5** | [OCaml](https://ocaml.org/) | MIT | https://github.com/tjammer/raylib-ocaml |
|
||||
| TurboRaylib | **4.5** | [Object Pascal](https://en.wikipedia.org/wiki/Object_Pascal) | MIT | https://github.com/turborium/TurboRaylib |
|
||||
| Ray4Laz | **4.5** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)| Zlib | https://github.com/GuvaCode/Ray4Laz |
|
||||
| Ray4Laz | **5.0** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)| Zlib | https://github.com/GuvaCode/Ray4Laz |
|
||||
| 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 |
|
||||
| raylib-python-cffi | 4.2 | [Python](https://www.python.org/) | EPL-2.0 | https://github.com/electronstudio/raylib-python-cffi |
|
||||
| raylibpyctbg | **4.5** | [Python](https://www.python.org/) | MIT | https://github.com/overdev/raylibpyctbg |
|
||||
| raylib-py | **4.5** | [Python](https://www.python.org/) | MIT | https://github.com/overdev/raylib-py |
|
||||
| raylib-py | **5.0b1** | [Python](https://www.python.org/) | MIT | https://github.com/overdev/raylib-py |
|
||||
| raylib-python-ctypes | 4.6-dev | [Python](https://www.python.org/) | MIT | https://github.com/sDos280/raylib-python-ctypes |
|
||||
| raylib-pkpy-bindings | 4.6-dev | [pocketpy](https://pocketpy.dev/) | MIT | https://github.com/blueloveTH/pkpy-bindings |
|
||||
| raylib-php | **4.5** | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/joseph-montanez/raylib-php |
|
||||
|
|
@ -70,7 +71,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| racket-raylib | 4.0 | [Racket](https://racket-lang.org/) | MIT/Apache-2.0 | https://github.com/eutro/racket-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-smallBasic | 4.1-dev | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 | https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib |
|
||||
| raylib-SmallBASIC | 5.0 | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 | https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib |
|
||||
| raylib-umka | **4.5** | [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-vapi | 4.2 | [Vala](https://vala.dev/) | Zlib | https://github.com/lxmcf/raylib-vapi |
|
||||
|
|
@ -83,12 +84,13 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| rayjs | 4.6-dev | [QuickJS](https://bellard.org/quickjs/) | MIT | https://github.com/mode777/rayjs |
|
||||
| raylib-raku | **auto** | [Raku](https://www.raku.org/) | Artistic License 2.0 | https://github.com/vushu/raylib-raku |
|
||||
| Raylib.lean | 4.5 | [Lean4](https://lean-lang.org/) | BSD-3-Clause | https://github.com/KislyjKisel/Raylib.lean |
|
||||
| Raylib-CSharp-Vinculum | 5.0 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | https://github.com/ZeroElectric/Raylib-CSharp-Vinculum |
|
||||
|
||||
### Utility Wrapers
|
||||
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's pardigm.
|
||||
| name | raylib version | language | license | repo |
|
||||
|:------------------:|:-------------: | :--------:|:-------:|:-------------------------------------------------------------|
|
||||
| raylib-cpp | **4.5** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib | https://github.com/robloach/raylib-cpp |
|
||||
| raylib-cpp | **5.0** | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | Zlib | https://github.com/robloach/raylib-cpp |
|
||||
| claylib | **4.5** | [Common Lisp](https://common-lisp.net/) | Zlib | https://github.com/defun-games/claylib |
|
||||
|
||||
### Older or Unmaintained Language Bindings
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(raylib)
|
||||
|
||||
# Avoid excessive expansion of variables in conditionals. In particular, if
|
||||
# "PLATFORM" is "DRM" than:
|
||||
# "PLATFORM" is "DRM" then:
|
||||
#
|
||||
# if (${PLATFORM} MATCHES "DRM")
|
||||
#
|
||||
|
|
@ -13,6 +13,11 @@ project(raylib)
|
|||
# See https://cmake.org/cmake/help/latest/policy/CMP0054.html
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
|
||||
# Makes a hidden visibility preset on a static lib respected
|
||||
# This is used to hide glfw's symbols from the library exports when building an so/dylib
|
||||
# See https://cmake.org/cmake/help/latest/policy/CMP0063.html
|
||||
cmake_policy(SET CMP0063 NEW)
|
||||
|
||||
# Directory for easier includes
|
||||
# Anywhere you see include(...) you can check <root>/cmake for that file
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
|
|
|||
|
|
@ -17,14 +17,15 @@ if(NOT glfw3_FOUND AND NOT USE_EXTERNAL_GLFW STREQUAL "ON" AND "${PLATFORM}" MAT
|
|||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
|
||||
set(GLFW_USE_WAYLAND ${USE_WAYLAND} CACHE BOOL "" FORCE)
|
||||
set(GLFW_LIBRARY_TYPE "OBJECT" CACHE STRING "" FORCE)
|
||||
|
||||
set(WAS_SHARED ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL " " FORCE)
|
||||
|
||||
add_subdirectory(external/glfw)
|
||||
|
||||
set(BUILD_SHARED_LIBS ${WAS_SHARED} CACHE BOOL " " FORCE)
|
||||
unset(WAS_SHARED)
|
||||
# Hide glfw's symbols when building a shared lib
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set_property(TARGET glfw PROPERTY C_VISIBILITY_PRESET hidden)
|
||||
endif()
|
||||
|
||||
list(APPEND raylib_sources $<TARGET_OBJECTS:glfw>)
|
||||
include_directories(BEFORE SYSTEM external/glfw/include)
|
||||
|
|
|
|||
|
|
@ -490,6 +490,7 @@ TEXTURES = \
|
|||
textures/textures_gif_player \
|
||||
textures/textures_image_drawing \
|
||||
textures/textures_image_generation \
|
||||
textures/textures_image_kernel \
|
||||
textures/textures_image_loading \
|
||||
textures/textures_image_processing \
|
||||
textures/textures_image_rotate \
|
||||
|
|
|
|||
|
|
@ -396,6 +396,7 @@ TEXTURES = \
|
|||
textures/textures_gif_player \
|
||||
textures/textures_image_drawing \
|
||||
textures/textures_image_generation \
|
||||
textures/textures_image_kernel \
|
||||
textures/textures_image_loading \
|
||||
textures/textures_image_processing \
|
||||
textures/textures_image_rotate \
|
||||
|
|
@ -703,6 +704,10 @@ textures/textures_image_drawing: textures/textures_image_drawing.c
|
|||
textures/textures_image_generation: textures/textures_image_generation.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s TOTAL_MEMORY=67108864
|
||||
|
||||
textures/textures_image_kernel: textures/textures_image_kernel.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/cat.png@resources/cat.png
|
||||
|
||||
textures/textures_image_loading: textures/textures_image_loading.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file textures/resources/raylib_logo.png@resources/raylib_logo.png
|
||||
|
|
@ -968,10 +973,10 @@ shaders/shaders_julia_set: shaders/shaders_julia_set.c
|
|||
|
||||
shaders/shaders_lightmap: shaders/shaders_lightmap.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -s FORCE_FILESYSTEM=1 \
|
||||
--preload-file shaders/resources/shaders/glsl330/lightmap.vs \
|
||||
--preload-file shaders/resources/shaders/glsl330/lightmap.fs \
|
||||
--preload-file shaders/resources/cubicmap_atlas.png \
|
||||
--preload-file shaders/resources/spark_flame.png
|
||||
--preload-file shaders/resources/shaders/glsl100/lightmap.vs@resources/shaders/glsl100/lightmap.vs \
|
||||
--preload-file shaders/resources/shaders/glsl100/lightmap.fs@resources/shaders/glsl100/lightmap.fs \
|
||||
--preload-file shaders/resources/cubicmap_atlas.png@resources/cubicmap_atlas.png \
|
||||
--preload-file shaders/resources/spark_flame.png@resources/spark_flame.png
|
||||
|
||||
shaders/shaders_mesh_instancing: shaders/shaders_mesh_instancing.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ float sineIdx = 0.0f;
|
|||
void AudioInputCallback(void *buffer, unsigned int frames)
|
||||
{
|
||||
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
|
||||
audioFrequency += 1.0f;
|
||||
audioFrequency -= 1.0f;
|
||||
|
||||
float incr = audioFrequency/44100.0f;
|
||||
short *d = (short *)buffer;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* raylib [audio] example - Music stream processing effects
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 5.0
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
|
|
@ -149,13 +149,17 @@ static void AudioProcessEffectLPF(void *buffer, unsigned int frames)
|
|||
static const float cutoff = 70.0f / 44100.0f; // 70 Hz lowpass filter
|
||||
const float k = cutoff / (cutoff + 0.1591549431f); // RC filter formula
|
||||
|
||||
// Converts the buffer data before using it
|
||||
float *bufferData = (float *)buffer;
|
||||
for (unsigned int i = 0; i < frames*2; i += 2)
|
||||
{
|
||||
float l = ((float *)buffer)[i], r = ((float *)buffer)[i + 1];
|
||||
const float l = bufferData[i];
|
||||
const float r = bufferData[i + 1];
|
||||
|
||||
low[0] += k * (l - low[0]);
|
||||
low[1] += k * (r - low[1]);
|
||||
((float *)buffer)[i] = low[0];
|
||||
((float *)buffer)[i + 1] = low[1];
|
||||
bufferData[i] = low[0];
|
||||
bufferData[i + 1] = low[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ int main(void)
|
|||
.vResolution = 1200, // Vertical resolution in pixels
|
||||
.hScreenSize = 0.133793f, // Horizontal size in meters
|
||||
.vScreenSize = 0.0669f, // Vertical size in meters
|
||||
.vScreenCenter = 0.04678f, // Screen center in meters
|
||||
.eyeToScreenDistance = 0.041f, // Distance between eye and display in meters
|
||||
.lensSeparationDistance = 0.07f, // Lens separation distance in meters
|
||||
.interpupillaryDistance = 0.07f, // IPD (distance between pupils) in meters
|
||||
|
|
|
|||
BIN
examples/shaders/resources/models/old_car_new.glb
Normal file
BIN
examples/shaders/resources/models/plane.glb
Normal file
BIN
examples/shaders/resources/old_car_d.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
examples/shaders/resources/old_car_e.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
examples/shaders/resources/old_car_mra.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
examples/shaders/resources/old_car_n.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
examples/shaders/resources/road_a.png
Normal file
|
After Width: | Height: | Size: 623 KiB |
BIN
examples/shaders/resources/road_mra.png
Normal file
|
After Width: | Height: | Size: 657 KiB |
BIN
examples/shaders/resources/road_n.png
Normal file
|
After Width: | Height: | Size: 645 KiB |
22
examples/shaders/resources/shaders/glsl100/lightmap.fs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec2 fragTexCoord2;
|
||||
varying vec3 fragPosition;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform sampler2D texture1;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||
vec4 texelColor2 = texture2D(texture1, fragTexCoord2);
|
||||
|
||||
gl_FragColor = texelColor * texelColor2;
|
||||
}
|
||||
31
examples/shaders/resources/shaders/glsl100/lightmap.vs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#version 100
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec2 vertexTexCoord2;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec2 fragTexCoord2;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send vertex attributes to fragment shader
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragTexCoord2 = vertexTexCoord2;
|
||||
fragColor = vertexColor;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||
}
|
||||
156
examples/shaders/resources/shaders/glsl100/pbr.fs
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
#define MAX_LIGHTS 4
|
||||
#define LIGHT_DIRECTIONAL 0
|
||||
#define LIGHT_POINT 1
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
struct Light {
|
||||
int enabled;
|
||||
int type;
|
||||
vec3 position;
|
||||
vec3 target;
|
||||
vec4 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying in vec3 fragPosition;
|
||||
varying in vec2 fragTexCoord;
|
||||
varying in vec4 fragColor;
|
||||
varying in vec3 fragNormal;
|
||||
varying in vec4 shadowPos;
|
||||
varying in mat3 TBN;
|
||||
|
||||
|
||||
// Input uniform values
|
||||
uniform int numOfLights;
|
||||
uniform sampler2D albedoMap;
|
||||
uniform sampler2D mraMap;
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D emissiveMap; // r: Hight g:emissive
|
||||
|
||||
uniform vec2 tiling;
|
||||
uniform vec2 offset;
|
||||
|
||||
uniform int useTexAlbedo;
|
||||
uniform int useTexNormal;
|
||||
uniform int useTexMRA;
|
||||
uniform int useTexEmissive;
|
||||
|
||||
uniform vec4 albedoColor;
|
||||
uniform vec4 emissiveColor;
|
||||
uniform float normalValue;
|
||||
uniform float metallicValue;
|
||||
uniform float roughnessValue;
|
||||
uniform float aoValue;
|
||||
uniform float emissivePower;
|
||||
|
||||
// Input lighting values
|
||||
uniform Light lights[MAX_LIGHTS];
|
||||
uniform vec3 viewPos;
|
||||
|
||||
uniform vec3 ambientColor;
|
||||
uniform float ambient;
|
||||
|
||||
// refl in range 0 to 1
|
||||
// returns base reflectivity to 1
|
||||
// incrase reflectivity when surface view at larger angle
|
||||
vec3 schlickFresnel(float hDotV,vec3 refl)
|
||||
{
|
||||
return refl + (1.0 - refl) * pow(1.0 - hDotV,5.0);
|
||||
}
|
||||
|
||||
float ggxDistribution(float nDotH,float roughness)
|
||||
{
|
||||
float a = roughness * roughness * roughness * roughness;
|
||||
float d = nDotH * nDotH * (a - 1.0) + 1.0;
|
||||
d = PI * d * d;
|
||||
return a / max(d,0.0000001);
|
||||
}
|
||||
|
||||
float geomSmith(float nDotV,float nDotL,float roughness)
|
||||
{
|
||||
float r = roughness + 1.0;
|
||||
float k = r * r / 8.0;
|
||||
float ik = 1.0 - k;
|
||||
float ggx1 = nDotV / (nDotV * ik + k);
|
||||
float ggx2 = nDotL / (nDotL * ik + k);
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
vec3 pbr(){
|
||||
vec3 albedo = texture2D(albedoMap,vec2(fragTexCoord.x*tiling.x+offset.x,fragTexCoord.y*tiling.y+offset.y)).rgb;
|
||||
albedo = vec3(albedoColor.x*albedo.x,albedoColor.y*albedo.y,albedoColor.z*albedo.z);
|
||||
float metallic = clamp(metallicValue,0.0,1.0);
|
||||
float roughness = clamp(roughnessValue,0.0,1.0);
|
||||
float ao = clamp(aoValue,0.0,1.0);
|
||||
if(useTexMRA == 1) {
|
||||
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x * tiling.x + offset.x, fragTexCoord.y * tiling.y + offset.y));
|
||||
metallic = clamp(mra.r+metallicValue,0.04,1.0);
|
||||
roughness = clamp(mra.g+roughnessValue,0.04,1.0);
|
||||
ao = (mra.b+aoValue)*0.5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vec3 N = normalize(fragNormal);
|
||||
if(useTexNormal == 1) {
|
||||
N = texture2D(normalMap, vec2(fragTexCoord.x * tiling.x + offset.y, fragTexCoord.y * tiling.y + offset.y)).rgb;
|
||||
N = normalize(N * 2.0 - 1.0);
|
||||
N = normalize(N * TBN);
|
||||
}
|
||||
|
||||
vec3 V = normalize(viewPos - fragPosition);
|
||||
|
||||
vec3 e = vec3(0);
|
||||
e = (texture2D(emissiveMap, vec2(fragTexCoord.x*tiling.x+offset.x, fragTexCoord.y*tiling.y+offset.y)).rgb).g * emissiveColor.rgb*emissivePower * float(useTexEmissive);
|
||||
|
||||
//return N;//vec3(metallic,metallic,metallic);
|
||||
//if dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
|
||||
vec3 baseRefl = mix(vec3(0.04),albedo.rgb,metallic);
|
||||
vec3 Lo = vec3(0.0); // acumulate lighting lum
|
||||
|
||||
for(int i=0;i<numOfLights;++i){
|
||||
|
||||
vec3 L = normalize(lights[i].position - fragPosition); // calc light vector
|
||||
vec3 H = normalize(V + L); // calc halfway bisecting vector
|
||||
float dist = length(lights[i].position - fragPosition); // calc distance to light
|
||||
float attenuation = 1.0 / (dist * dist * 0.23); // calc attenuation
|
||||
vec3 radiance = lights[i].color.rgb * lights[i].intensity * attenuation; // calc input radiance,light energy comming in
|
||||
|
||||
//Cook-Torrance BRDF distribution function
|
||||
float nDotV = max(dot(N,V),0.0000001);
|
||||
float nDotL = max(dot(N,L),0.0000001);
|
||||
float hDotV = max(dot(H,V),0.0);
|
||||
float nDotH = max(dot(N,H),0.0);
|
||||
float D = ggxDistribution(nDotH,roughness); // larger the more micro-facets aligned to H
|
||||
float G = geomSmith(nDotV,nDotL,roughness); // smaller the more micro-facets shadow
|
||||
vec3 F = schlickFresnel(hDotV, baseRefl); // fresnel proportion of specular reflectance
|
||||
|
||||
vec3 spec = (D * G * F) / (4.0 * nDotV * nDotL);
|
||||
// difuse and spec light can't be above 1.0
|
||||
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
||||
vec3 kD = vec3(1.0) - F;
|
||||
//mult kD by the inverse of metallnes , only non-metals should have diffuse light
|
||||
kD *= 1.0 - metallic;
|
||||
Lo += ((kD * albedo.rgb / PI + spec) * radiance * nDotL)*float(lights[i].enabled); // angle of light has impact on result
|
||||
}
|
||||
vec3 ambient_final = (ambientColor + albedo)* ambient * 0.5;
|
||||
return ambient_final+Lo*ao+e;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = pbr();
|
||||
|
||||
//HDR tonemapping
|
||||
color = pow(color,color + vec3(1.0));
|
||||
//gamma correction
|
||||
color = pow(color,vec3(1.0/2.2));
|
||||
|
||||
gl_FragColor = vec4(color,1.0);
|
||||
|
||||
}
|
||||
75
examples/shaders/resources/shaders/glsl100/pbr.vs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#version 100
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec3 vertexTangent;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
uniform mat4 matNormal;
|
||||
uniform vec3 lightPos;
|
||||
uniform vec4 difColor;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
varying vec3 fragNormal;
|
||||
varying mat3 TBN;
|
||||
|
||||
const float normalOffset = 0.1;
|
||||
|
||||
// https://github.com/glslify/glsl-inverse
|
||||
mat3 inverse(mat3 m)
|
||||
{
|
||||
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||
|
||||
float b01 = a22*a11 - a12*a21;
|
||||
float b11 = -a22*a10 + a12*a20;
|
||||
float b21 = a21*a10 - a11*a20;
|
||||
|
||||
float det = a00*b01 + a01*b11 + a02*b21;
|
||||
|
||||
return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
|
||||
b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
|
||||
b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
|
||||
}
|
||||
|
||||
// https://github.com/glslify/glsl-transpose
|
||||
mat3 transpose(mat3 m)
|
||||
{
|
||||
return mat3(m[0][0], m[1][0], m[2][0],
|
||||
m[0][1], m[1][1], m[2][1],
|
||||
m[0][2], m[1][2], m[2][2]);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// calc binormal from vertex normal and tangent
|
||||
vec3 vertexBinormal = cross(vertexNormal, vertexTangent);
|
||||
// calc fragment normal based on normal transformations
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
// calc fragment position based on model transformations
|
||||
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||
|
||||
fragTexCoord = vertexTexCoord*2.0;
|
||||
|
||||
fragNormal = normalize(normalMatrix*vertexNormal);
|
||||
vec3 fragTangent = normalize(normalMatrix*vertexTangent);
|
||||
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
|
||||
vec3 fragBinormal = normalize(normalMatrix*vertexBinormal);
|
||||
fragBinormal = cross(fragNormal, fragTangent);
|
||||
|
||||
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
||||
20
examples/shaders/resources/shaders/glsl120/lightmap.fs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#version 120
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec2 fragTexCoord2;
|
||||
varying vec3 fragPosition;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform sampler2D texture1;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||
vec4 texelColor2 = texture2D(texture1, fragTexCoord2);
|
||||
|
||||
gl_FragColor = texelColor * texelColor2;
|
||||
}
|
||||
31
examples/shaders/resources/shaders/glsl120/lightmap.vs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#version 120
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec2 vertexTexCoord2;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec2 fragTexCoord2;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// NOTE: Add here your custom variables
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send vertex attributes to fragment shader
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragTexCoord2 = vertexTexCoord2;
|
||||
fragColor = vertexColor;
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||
}
|
||||
156
examples/shaders/resources/shaders/glsl120/pbr.fs
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
#version 120
|
||||
|
||||
precision mediump float;
|
||||
|
||||
#define MAX_LIGHTS 4
|
||||
#define LIGHT_DIRECTIONAL 0
|
||||
#define LIGHT_POINT 1
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
struct Light {
|
||||
int enabled;
|
||||
int type;
|
||||
vec3 position;
|
||||
vec3 target;
|
||||
vec4 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying in vec3 fragPosition;
|
||||
varying in vec2 fragTexCoord;
|
||||
varying in vec4 fragColor;
|
||||
varying in vec3 fragNormal;
|
||||
varying in vec4 shadowPos;
|
||||
varying in mat3 TBN;
|
||||
|
||||
|
||||
// Input uniform values
|
||||
uniform int numOfLights;
|
||||
uniform sampler2D albedoMap;
|
||||
uniform sampler2D mraMap;
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D emissiveMap; // r: Hight g:emissive
|
||||
|
||||
uniform vec2 tiling;
|
||||
uniform vec2 offset;
|
||||
|
||||
uniform int useTexAlbedo;
|
||||
uniform int useTexNormal;
|
||||
uniform int useTexMRA;
|
||||
uniform int useTexEmissive;
|
||||
|
||||
uniform vec4 albedoColor;
|
||||
uniform vec4 emissiveColor;
|
||||
uniform float normalValue;
|
||||
uniform float metallicValue;
|
||||
uniform float roughnessValue;
|
||||
uniform float aoValue;
|
||||
uniform float emissivePower;
|
||||
|
||||
// Input lighting values
|
||||
uniform Light lights[MAX_LIGHTS];
|
||||
uniform vec3 viewPos;
|
||||
|
||||
uniform vec3 ambientColor;
|
||||
uniform float ambient;
|
||||
|
||||
// refl in range 0 to 1
|
||||
// returns base reflectivity to 1
|
||||
// incrase reflectivity when surface view at larger angle
|
||||
vec3 schlickFresnel(float hDotV,vec3 refl)
|
||||
{
|
||||
return refl + (1.0 - refl) * pow(1.0 - hDotV,5.0);
|
||||
}
|
||||
|
||||
float ggxDistribution(float nDotH,float roughness)
|
||||
{
|
||||
float a = roughness * roughness * roughness * roughness;
|
||||
float d = nDotH * nDotH * (a - 1.0) + 1.0;
|
||||
d = PI * d * d;
|
||||
return a / max(d,0.0000001);
|
||||
}
|
||||
|
||||
float geomSmith(float nDotV,float nDotL,float roughness)
|
||||
{
|
||||
float r = roughness + 1.0;
|
||||
float k = r * r / 8.0;
|
||||
float ik = 1.0 - k;
|
||||
float ggx1 = nDotV / (nDotV * ik + k);
|
||||
float ggx2 = nDotL / (nDotL * ik + k);
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
vec3 pbr(){
|
||||
vec3 albedo = texture2D(albedoMap,vec2(fragTexCoord.x*tiling.x+offset.x,fragTexCoord.y*tiling.y+offset.y)).rgb;
|
||||
albedo = vec3(albedoColor.x*albedo.x,albedoColor.y*albedo.y,albedoColor.z*albedo.z);
|
||||
float metallic = clamp(metallicValue,0.0,1.0);
|
||||
float roughness = clamp(roughnessValue,0.0,1.0);
|
||||
float ao = clamp(aoValue,0.0,1.0);
|
||||
if(useTexMRA == 1) {
|
||||
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x * tiling.x + offset.x, fragTexCoord.y * tiling.y + offset.y));
|
||||
metallic = clamp(mra.r+metallicValue,0.04,1.0);
|
||||
roughness = clamp(mra.g+roughnessValue,0.04,1.0);
|
||||
ao = (mra.b+aoValue)*0.5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vec3 N = normalize(fragNormal);
|
||||
if(useTexNormal == 1) {
|
||||
N = texture2D(normalMap, vec2(fragTexCoord.x * tiling.x + offset.y, fragTexCoord.y * tiling.y + offset.y)).rgb;
|
||||
N = normalize(N * 2.0 - 1.0);
|
||||
N = normalize(N * TBN);
|
||||
}
|
||||
|
||||
vec3 V = normalize(viewPos - fragPosition);
|
||||
|
||||
vec3 e = vec3(0);
|
||||
e = (texture2D(emissiveMap, vec2(fragTexCoord.x*tiling.x+offset.x, fragTexCoord.y*tiling.y+offset.y)).rgb).g * emissiveColor.rgb*emissivePower * float(useTexEmissive);
|
||||
|
||||
//return N;//vec3(metallic,metallic,metallic);
|
||||
//if dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
|
||||
vec3 baseRefl = mix(vec3(0.04),albedo.rgb,metallic);
|
||||
vec3 Lo = vec3(0.0); // acumulate lighting lum
|
||||
|
||||
for(int i=0;i<numOfLights;++i){
|
||||
|
||||
vec3 L = normalize(lights[i].position - fragPosition); // calc light vector
|
||||
vec3 H = normalize(V + L); // calc halfway bisecting vector
|
||||
float dist = length(lights[i].position - fragPosition); // calc distance to light
|
||||
float attenuation = 1.0 / (dist * dist * 0.23); // calc attenuation
|
||||
vec3 radiance = lights[i].color.rgb * lights[i].intensity * attenuation; // calc input radiance,light energy comming in
|
||||
|
||||
//Cook-Torrance BRDF distribution function
|
||||
float nDotV = max(dot(N,V),0.0000001);
|
||||
float nDotL = max(dot(N,L),0.0000001);
|
||||
float hDotV = max(dot(H,V),0.0);
|
||||
float nDotH = max(dot(N,H),0.0);
|
||||
float D = ggxDistribution(nDotH,roughness); // larger the more micro-facets aligned to H
|
||||
float G = geomSmith(nDotV,nDotL,roughness); // smaller the more micro-facets shadow
|
||||
vec3 F = schlickFresnel(hDotV, baseRefl); // fresnel proportion of specular reflectance
|
||||
|
||||
vec3 spec = (D * G * F) / (4.0 * nDotV * nDotL);
|
||||
// difuse and spec light can't be above 1.0
|
||||
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
||||
vec3 kD = vec3(1.0) - F;
|
||||
//mult kD by the inverse of metallnes , only non-metals should have diffuse light
|
||||
kD *= 1.0 - metallic;
|
||||
Lo += ((kD * albedo.rgb / PI + spec) * radiance * nDotL)*float(lights[i].enabled); // angle of light has impact on result
|
||||
}
|
||||
vec3 ambient_final = (ambientColor + albedo)* ambient * 0.5;
|
||||
return ambient_final+Lo*ao+e;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = pbr();
|
||||
|
||||
//HDR tonemapping
|
||||
color = pow(color,color + vec3(1.0));
|
||||
//gamma correction
|
||||
color = pow(color,vec3(1.0/2.2));
|
||||
|
||||
gl_FragColor = vec4(color,1.0);
|
||||
|
||||
}
|
||||
75
examples/shaders/resources/shaders/glsl120/pbr.vs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#version 120
|
||||
|
||||
// Input vertex attributes
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
attribute vec3 vertexTangent;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
uniform mat4 matNormal;
|
||||
uniform vec3 lightPos;
|
||||
uniform vec4 difColor;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
varying vec3 fragPosition;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
varying vec3 fragNormal;
|
||||
varying mat3 TBN;
|
||||
|
||||
const float normalOffset = 0.1;
|
||||
|
||||
// https://github.com/glslify/glsl-inverse
|
||||
mat3 inverse(mat3 m)
|
||||
{
|
||||
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
|
||||
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
|
||||
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
|
||||
|
||||
float b01 = a22*a11 - a12*a21;
|
||||
float b11 = -a22*a10 + a12*a20;
|
||||
float b21 = a21*a10 - a11*a20;
|
||||
|
||||
float det = a00*b01 + a01*b11 + a02*b21;
|
||||
|
||||
return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
|
||||
b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
|
||||
b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
|
||||
}
|
||||
|
||||
// https://github.com/glslify/glsl-transpose
|
||||
mat3 transpose(mat3 m)
|
||||
{
|
||||
return mat3(m[0][0], m[1][0], m[2][0],
|
||||
m[0][1], m[1][1], m[2][1],
|
||||
m[0][2], m[1][2], m[2][2]);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// calc binormal from vertex normal and tangent
|
||||
vec3 vertexBinormal = cross(vertexNormal, vertexTangent);
|
||||
// calc fragment normal based on normal transformations
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
// calc fragment position based on model transformations
|
||||
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||
|
||||
fragTexCoord = vertexTexCoord*2.0;
|
||||
|
||||
fragNormal = normalize(normalMatrix*vertexNormal);
|
||||
vec3 fragTangent = normalize(normalMatrix*vertexTangent);
|
||||
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
|
||||
vec3 fragBinormal = normalize(normalMatrix*vertexBinormal);
|
||||
fragBinormal = cross(fragNormal, fragTangent);
|
||||
|
||||
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
||||
159
examples/shaders/resources/shaders/glsl330/pbr.fs
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#version 330
|
||||
|
||||
#define MAX_LIGHTS 4
|
||||
#define LIGHT_DIRECTIONAL 0
|
||||
#define LIGHT_POINT 1
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
struct Light {
|
||||
int enabled;
|
||||
int type;
|
||||
vec3 position;
|
||||
vec3 target;
|
||||
vec4 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec3 fragPosition;
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
in vec3 fragNormal;
|
||||
in vec4 shadowPos;
|
||||
in mat3 TBN;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
// Input uniform values
|
||||
|
||||
uniform int numOfLights;
|
||||
uniform sampler2D albedoMap;
|
||||
uniform sampler2D mraMap;
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D emissiveMap; // r: Hight g:emissive
|
||||
|
||||
uniform vec2 tiling;
|
||||
uniform vec2 offset;
|
||||
|
||||
uniform int useTexAlbedo;
|
||||
uniform int useTexNormal;
|
||||
uniform int useTexMRA;
|
||||
uniform int useTexEmissive;
|
||||
|
||||
uniform vec4 albedoColor;
|
||||
uniform vec4 emissiveColor;
|
||||
uniform float normalValue;
|
||||
uniform float metallicValue;
|
||||
uniform float roughnessValue;
|
||||
uniform float aoValue;
|
||||
uniform float emissivePower;
|
||||
|
||||
// Input lighting values
|
||||
uniform Light lights[MAX_LIGHTS];
|
||||
uniform vec3 viewPos;
|
||||
|
||||
uniform vec3 ambientColor;
|
||||
uniform float ambient;
|
||||
|
||||
// refl in range 0 to 1
|
||||
// returns base reflectivity to 1
|
||||
// incrase reflectivity when surface view at larger angle
|
||||
vec3 schlickFresnel(float hDotV,vec3 refl)
|
||||
{
|
||||
return refl + (1.0 - refl) * pow(1.0 - hDotV,5.0);
|
||||
}
|
||||
|
||||
float ggxDistribution(float nDotH,float roughness)
|
||||
{
|
||||
float a = roughness * roughness * roughness * roughness;
|
||||
float d = nDotH * nDotH * (a - 1.0) + 1.0;
|
||||
d = PI * d * d;
|
||||
return a / max(d,0.0000001);
|
||||
}
|
||||
|
||||
float geomSmith(float nDotV,float nDotL,float roughness)
|
||||
{
|
||||
float r = roughness + 1.0;
|
||||
float k = r * r / 8.0;
|
||||
float ik = 1.0 - k;
|
||||
float ggx1 = nDotV / (nDotV * ik + k);
|
||||
float ggx2 = nDotL / (nDotL * ik + k);
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
vec3 pbr(){
|
||||
vec3 albedo = texture(albedoMap,vec2(fragTexCoord.x*tiling.x+offset.x,fragTexCoord.y*tiling.y+offset.y)).rgb;
|
||||
albedo = vec3(albedoColor.x*albedo.x,albedoColor.y*albedo.y,albedoColor.z*albedo.z);
|
||||
float metallic = clamp(metallicValue,0.0,1.0);
|
||||
float roughness = clamp(roughnessValue,0.0,1.0);
|
||||
float ao = clamp(aoValue,0.0,1.0);
|
||||
if(useTexMRA == 1) {
|
||||
vec4 mra = texture(mraMap, vec2(fragTexCoord.x * tiling.x + offset.x, fragTexCoord.y * tiling.y + offset.y)) * useTexMRA;
|
||||
metallic = clamp(mra.r+metallicValue,0.04,1.0);
|
||||
roughness = clamp(mra.g+roughnessValue,0.04,1.0);
|
||||
ao = (mra.b+aoValue)*0.5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vec3 N = normalize(fragNormal);
|
||||
if(useTexNormal == 1) {
|
||||
N = texture(normalMap, vec2(fragTexCoord.x * tiling.x + offset.y, fragTexCoord.y * tiling.y + offset.y)).rgb;
|
||||
N = normalize(N * 2.0 - 1.0);
|
||||
N = normalize(N * TBN);
|
||||
}
|
||||
|
||||
vec3 V = normalize(viewPos - fragPosition);
|
||||
|
||||
vec3 e = vec3(0);
|
||||
e = (texture(emissiveMap, vec2(fragTexCoord.x*tiling.x+offset.x, fragTexCoord.y*tiling.y+offset.y)).rgb).g * emissiveColor.rgb*emissivePower * useTexEmissive;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//return N;//vec3(metallic,metallic,metallic);
|
||||
//if dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
|
||||
vec3 baseRefl = mix(vec3(0.04),albedo.rgb,metallic);
|
||||
vec3 Lo = vec3(0.0); // acumulate lighting lum
|
||||
|
||||
for(int i=0;i<numOfLights;++i){
|
||||
|
||||
vec3 L = normalize(lights[i].position - fragPosition); // calc light vector
|
||||
vec3 H = normalize(V + L); // calc halfway bisecting vector
|
||||
float dist = length(lights[i].position - fragPosition); // calc distance to light
|
||||
float attenuation = 1.0 / (dist * dist * 0.23); // calc attenuation
|
||||
vec3 radiance = lights[i].color.rgb * lights[i].intensity * attenuation; // calc input radiance,light energy comming in
|
||||
|
||||
//Cook-Torrance BRDF distribution function
|
||||
float nDotV = max(dot(N,V),0.0000001);
|
||||
float nDotL = max(dot(N,L),0.0000001);
|
||||
float hDotV = max(dot(H,V),0.0);
|
||||
float nDotH = max(dot(N,H),0.0);
|
||||
float D = ggxDistribution(nDotH,roughness); // larger the more micro-facets aligned to H
|
||||
float G = geomSmith(nDotV,nDotL,roughness); // smaller the more micro-facets shadow
|
||||
vec3 F = schlickFresnel(hDotV, baseRefl); // fresnel proportion of specular reflectance
|
||||
|
||||
vec3 spec = (D * G * F) / (4.0 * nDotV * nDotL);
|
||||
// difuse and spec light can't be above 1.0
|
||||
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
|
||||
vec3 kD = vec3(1.0) - F;
|
||||
//mult kD by the inverse of metallnes , only non-metals should have diffuse light
|
||||
kD *= 1.0 - metallic;
|
||||
Lo += ((kD * albedo.rgb / PI + spec) * radiance * nDotL)*lights[i].enabled; // angle of light has impact on result
|
||||
}
|
||||
vec3 ambient_final = (ambientColor + albedo)* ambient * 0.5;
|
||||
return ambient_final+Lo*ao+e;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = pbr();
|
||||
|
||||
//HDR tonemapping
|
||||
color = pow(color,color + vec3(1.0));
|
||||
//gamma correction
|
||||
color = pow(color,vec3(1.0/2.2));
|
||||
|
||||
finalColor = vec4(color,1.0);
|
||||
}
|
||||
49
examples/shaders/resources/shaders/glsl330/pbr.vs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#version 330
|
||||
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
in vec3 vertexTangent;
|
||||
in vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
uniform mat4 matNormal;
|
||||
uniform vec3 lightPos;
|
||||
uniform vec4 difColor;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec3 fragPosition;
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
out vec3 fragNormal;
|
||||
out mat3 TBN;
|
||||
|
||||
const float normalOffset = 0.1;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// calc binormal from vertex normal and tangent
|
||||
vec3 vertexBinormal = cross(vertexNormal, vertexTangent);
|
||||
// calc fragment normal based on normal transformations
|
||||
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
|
||||
// calc fragment position based on model transformations
|
||||
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0f));
|
||||
|
||||
fragTexCoord = vertexTexCoord*2.0;
|
||||
|
||||
fragNormal = normalize(normalMatrix*vertexNormal);
|
||||
vec3 fragTangent = normalize(normalMatrix*vertexTangent);
|
||||
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
|
||||
vec3 fragBinormal = normalize(normalMatrix*vertexBinormal);
|
||||
fragBinormal = cross(fragNormal, fragTangent);
|
||||
|
||||
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
}
|
||||
466
examples/shaders/rpbr.h
Normal file
|
|
@ -0,0 +1,466 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.pbr - Some useful functions to deal with pbr materials and lights
|
||||
*
|
||||
* CONFIGURATION:
|
||||
*
|
||||
* #define RPBR_IMPLEMENTATION
|
||||
* Generates the implementation of the library into the included file.
|
||||
* If not defined, the library is in header only mode and can be included in other headers
|
||||
* or source files without problems. But only ONE file should hold the implementation.
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2023-2024 Afan OLOVCIC (@_DevDad) 2017-2020 Victor Fisac(@victorfisac),Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef RPBR_H
|
||||
#define RPBR_H
|
||||
#include "raylib.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define MAX_LIGHTS 4 // Max dynamic lights supported by shader
|
||||
#define SHADER_LOC_MAP_MRA SHADER_LOC_MAP_METALNESS //METALLIC, ROUGHNESS and AO
|
||||
#define SHADER_LOC_MAP_EMISSIVE SHADER_LOC_MAP_HEIGHT //EMISSIVE
|
||||
#define MATERIAL_MAP_MRA MATERIAL_MAP_METALNESS
|
||||
#define MATERIAL_MAP_EMISSIVE MATERIAL_MAP_HEIGHT
|
||||
#define NULL 0
|
||||
#define COLOR_TO_ARRAY(c)
|
||||
|
||||
typedef struct {
|
||||
int enabled;
|
||||
int type;
|
||||
Vector3 position;
|
||||
Vector3 target;
|
||||
float color[4];
|
||||
float intensity;
|
||||
|
||||
int enabledLoc;
|
||||
int typeLoc;
|
||||
int positionLoc;
|
||||
int targetLoc;
|
||||
int colorLoc;
|
||||
int intensityLoc;
|
||||
} PBRLight;
|
||||
|
||||
typedef enum {
|
||||
LIGHT_DIRECTIONAL = 0,
|
||||
LIGHT_POINT,
|
||||
LIGHT_SPOT
|
||||
} PBRLightType;
|
||||
|
||||
typedef struct{
|
||||
Shader pbrShader;
|
||||
Shader skyShader;
|
||||
unsigned int cubemap;
|
||||
unsigned int irradiance;
|
||||
unsigned int prefilter;
|
||||
unsigned int brdf;
|
||||
int modelMatrixLoc;
|
||||
int pbrViewLoc;
|
||||
int skyViewLoc;
|
||||
int skyResolutionLoc;
|
||||
} PBREnvironment;
|
||||
|
||||
typedef enum{
|
||||
PBR_COLOR_ALBEDO = 0,
|
||||
PBR_COLOR_EMISSIVE
|
||||
}PBRColorType;
|
||||
|
||||
typedef enum{
|
||||
PBR_VEC2_TILING = 0,
|
||||
PBR_VEC2_OFFSET
|
||||
}PBRVec2Type;
|
||||
|
||||
typedef enum{
|
||||
PBR_PARAM_NORMAL =0,
|
||||
PBR_PARAM_METALLIC,
|
||||
PBR_PARAM_ROUGHNESS,
|
||||
PBR_PARAM_EMISSIVE,
|
||||
PBR_PARAM_AO
|
||||
}PBRFloatType;
|
||||
|
||||
typedef enum{
|
||||
PBR_TEXTURE_ALBEDO = 0,
|
||||
PBR_TEXTURE_NORMAL,
|
||||
PBR_TEXTURE_MRA,
|
||||
PBR_TEXTURE_EMISSIVE
|
||||
}PBRTexType;
|
||||
|
||||
// Textures are moved to material from params to pack better and use less textures on the end
|
||||
// texture MRAE 4Channel R: Metallic G: Roughness B: A: Ambient Occlusion
|
||||
// texEmissive use just one channel, so we have 3 channels still to use if we need
|
||||
typedef struct {
|
||||
Shader pbrShader;
|
||||
float albedo[4];
|
||||
float normal;
|
||||
float metallic;
|
||||
float roughness;
|
||||
float ao;
|
||||
float emissive[4];
|
||||
float ambient[3];
|
||||
float emissivePower;
|
||||
|
||||
Texture2D texAlbedo;
|
||||
Texture2D texNormal;
|
||||
Texture2D texMRA;//r: Metallic g: Roughness b: AO a:Empty
|
||||
Texture2D texEmissive; //Emissive Texture
|
||||
// Using float4 to store tilling at 1st and 2nd position and offset at 3rd and 4th
|
||||
float texTiling[2];
|
||||
float texOffset[2];
|
||||
|
||||
int useTexAlbedo;
|
||||
int useTexNormal;
|
||||
int useTexMRA;
|
||||
int useTexEmissive;
|
||||
|
||||
int albedoLoc;
|
||||
int normalLoc;
|
||||
int metallicLoc;
|
||||
int roughnessLoc;
|
||||
int aoLoc;
|
||||
int emissiveColorLoc;
|
||||
int emissivePowerLoc;
|
||||
|
||||
int texTilingLoc;
|
||||
int texOffsetLoc;
|
||||
|
||||
int useTexAlbedoLoc;
|
||||
int useTexNormalLoc;
|
||||
int useTexMRAELoc;
|
||||
int useTexEmissiveLoc;
|
||||
} PBRMaterial;
|
||||
|
||||
typedef struct{
|
||||
Model model;
|
||||
PBRMaterial pbrMat;
|
||||
}PBRModel;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Create a light and get shader locations
|
||||
PBRLight PBRLightCreate(int type, Vector3 position, Vector3 target, Color color,float intensity, Shader shader);
|
||||
// Send light properties to shader
|
||||
void PBRLightUpdate(Shader shader, PBRLight light);
|
||||
|
||||
//For now until we do real skylight
|
||||
void PBRSetAmbient(Shader shader, Color color, float intensity);
|
||||
|
||||
PBRModel PBRModelLoad(const char *fileName);
|
||||
PBRModel PBRModelLoadFromMesh(Mesh mesh);
|
||||
|
||||
void PBRLoadTextures(PBRMaterial *pbrMat,PBRTexType pbrTexType,const char *fileName);
|
||||
void UnloadPBRMaterial(PBRMaterial pbrMat);
|
||||
void PBRSetColor(PBRMaterial *pbrMat,PBRColorType pbrColorType,Color color);
|
||||
void PBRSetVec2(PBRMaterial *pbrMat,PBRVec2Type type,Vector2 value);
|
||||
void PBRSetFloat(PBRMaterial *pbrMat, PBRFloatType pbrParamType, float value);
|
||||
|
||||
void PBRMaterialSetup( PBRMaterial *pbrMat,Shader pbrShader, PBREnvironment* environment);
|
||||
void PBRSetMaterial(PBRModel* model,PBRMaterial* pbrMat,int matIndex);
|
||||
void PBRDrawModel(PBRModel pbrModel, Vector3 position, float scale);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //RPBR_H
|
||||
|
||||
/***********************************************************************************
|
||||
*
|
||||
* RPBR IMPLEMENTATION
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(RPBR_IMPLEMENTATION)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static int lightsCount = 0; // Current amount of created lights
|
||||
|
||||
// Create a light and get shader locations
|
||||
PBRLight PBRLightCreate(int type, Vector3 position, Vector3 target, Color color,float intensity, Shader shader)
|
||||
{
|
||||
PBRLight light = { 0 };
|
||||
|
||||
if (lightsCount < MAX_LIGHTS)
|
||||
{
|
||||
light.enabled = 1;
|
||||
light.type = type;
|
||||
light.position = position;
|
||||
light.target = target;
|
||||
light.color[0] = (float)color.r/(float)255;
|
||||
light.color[1] = (float)color.g/(float)255;
|
||||
light.color[2] = (float)color.b/(float)255;
|
||||
light.color[3] = (float)color.a/(float)255;
|
||||
light.intensity = intensity;
|
||||
// NOTE: Lighting shader naming must be the provided ones
|
||||
light.enabledLoc = GetShaderLocation(shader, TextFormat("lights[%i].enabled", lightsCount));
|
||||
light.typeLoc = GetShaderLocation(shader, TextFormat("lights[%i].type", lightsCount));
|
||||
light.positionLoc = GetShaderLocation(shader, TextFormat("lights[%i].position", lightsCount));
|
||||
light.targetLoc = GetShaderLocation(shader, TextFormat("lights[%i].target", lightsCount));
|
||||
light.colorLoc = GetShaderLocation(shader, TextFormat("lights[%i].color", lightsCount));
|
||||
light.intensityLoc = GetShaderLocation(shader, TextFormat("lights[%i].intensity", lightsCount));
|
||||
PBRLightUpdate(shader, light);
|
||||
|
||||
lightsCount++;
|
||||
}
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
// Send light properties to shader
|
||||
// NOTE: Light shader locations should be available
|
||||
void PBRLightUpdate(Shader shader, PBRLight light)
|
||||
{
|
||||
SetShaderValue(shader, light.enabledLoc, &light.enabled, SHADER_UNIFORM_INT);
|
||||
SetShaderValue(shader, light.typeLoc, &light.type, SHADER_UNIFORM_INT);
|
||||
// Send to shader light position values
|
||||
float position[3] = { light.position.x, light.position.y, light.position.z };
|
||||
SetShaderValue(shader, light.positionLoc, position, SHADER_UNIFORM_VEC3);
|
||||
|
||||
// Send to shader light target position values
|
||||
float target[3] = { light.target.x, light.target.y, light.target.z };
|
||||
SetShaderValue(shader, light.targetLoc, target, SHADER_UNIFORM_VEC3);
|
||||
SetShaderValue(shader, light.colorLoc, light.color, SHADER_UNIFORM_VEC4);
|
||||
SetShaderValue(shader, light.intensityLoc, &light.intensity, SHADER_UNIFORM_FLOAT);
|
||||
}
|
||||
|
||||
void PBRSetAmbient(Shader shader, Color color, float intensity){
|
||||
float col[3] = {color.r/255,color.g/255,color.b/255};
|
||||
SetShaderValue(shader, GetShaderLocation(shader, "ambientColor"), col, SHADER_UNIFORM_VEC3);
|
||||
SetShaderValue(shader, GetShaderLocation(shader, "ambient"), &intensity, SHADER_UNIFORM_FLOAT);
|
||||
}
|
||||
|
||||
void PBRMaterialSetup(PBRMaterial *pbrMat, Shader pbrShader, PBREnvironment* environment){
|
||||
pbrMat->pbrShader = pbrShader;
|
||||
|
||||
pbrMat->texAlbedo = (Texture2D){0};
|
||||
pbrMat->texNormal = (Texture2D){0};
|
||||
pbrMat->texMRA = (Texture2D){0};
|
||||
pbrMat->texEmissive = (Texture2D){0};
|
||||
|
||||
//PBRParam
|
||||
pbrMat->albedo[0] = 1.0;
|
||||
pbrMat->albedo[1] = 1.0;
|
||||
pbrMat->albedo[2] = 1.0;
|
||||
pbrMat->albedo[3] = 1.0;
|
||||
pbrMat->metallic = 0;
|
||||
pbrMat->roughness = 0;
|
||||
pbrMat->ao = 1.0;
|
||||
pbrMat->normal = 1;
|
||||
pbrMat->emissive[0] = 0;
|
||||
pbrMat->emissive[1] = 0;
|
||||
pbrMat->emissive[2] = 0;
|
||||
pbrMat->emissive[3] = 0;
|
||||
|
||||
pbrMat->texTiling[0] = 1.0;
|
||||
pbrMat->texTiling[1] = 1.0;
|
||||
pbrMat->texOffset[0] = 0.0;
|
||||
pbrMat->texOffset[1] = 0.0;
|
||||
pbrMat->emissivePower = 1.0;
|
||||
// Set up PBR shader material locations
|
||||
|
||||
pbrMat->albedoLoc = GetShaderLocation(pbrMat->pbrShader, "albedoColor");
|
||||
pbrMat->normalLoc = GetShaderLocation(pbrMat->pbrShader, "normalValue");
|
||||
pbrMat->metallicLoc = GetShaderLocation(pbrMat->pbrShader, "metallicValue");
|
||||
pbrMat->roughnessLoc = GetShaderLocation(pbrMat->pbrShader, "roughnessValue");
|
||||
pbrMat->aoLoc = GetShaderLocation(pbrMat->pbrShader, "aoValue");
|
||||
pbrMat->emissiveColorLoc = GetShaderLocation(pbrMat->pbrShader, "emissiveColor");
|
||||
pbrMat->emissivePowerLoc = GetShaderLocation(pbrMat->pbrShader, "emissivePower");
|
||||
|
||||
pbrMat->texTilingLoc = GetShaderLocation(pbrMat->pbrShader, "tiling");
|
||||
pbrMat->texOffsetLoc = GetShaderLocation(pbrMat->pbrShader, "offset");
|
||||
|
||||
pbrMat->useTexAlbedoLoc = GetShaderLocation(pbrMat->pbrShader, "useTexAlbedo");
|
||||
pbrMat->useTexNormalLoc = GetShaderLocation(pbrMat->pbrShader, "useTexNormal");
|
||||
pbrMat->useTexMRAELoc = GetShaderLocation(pbrMat->pbrShader, "useTexMRA");
|
||||
pbrMat->useTexEmissiveLoc = GetShaderLocation(pbrMat->pbrShader, "useTexEmissive");
|
||||
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->albedoLoc,pbrMat->albedo,SHADER_UNIFORM_VEC4);
|
||||
SetShaderValue(pbrMat->pbrShader, pbrMat->emissiveColorLoc, pbrMat->emissive, SHADER_UNIFORM_VEC4);
|
||||
SetShaderValue(pbrMat->pbrShader, pbrMat->emissivePowerLoc, &pbrMat->emissivePower, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->metallicLoc,&pbrMat->metallic,SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->roughnessLoc,&pbrMat->roughness,SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->aoLoc,&pbrMat->ao,SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->normalLoc,&pbrMat->normal,SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->texTilingLoc,pbrMat->texTiling,SHADER_UNIFORM_VEC2);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->texOffsetLoc,pbrMat->texOffset,SHADER_UNIFORM_VEC2);
|
||||
}
|
||||
|
||||
void PBRLoadTextures(PBRMaterial *pbrMat,PBRTexType pbrTexType,const char *fileName){
|
||||
if(pbrMat == NULL) return;
|
||||
switch(pbrTexType){
|
||||
case PBR_TEXTURE_ALBEDO:
|
||||
pbrMat->texAlbedo = LoadTexture(fileName);
|
||||
pbrMat->useTexAlbedo = 1;
|
||||
break;
|
||||
case PBR_TEXTURE_MRA:
|
||||
pbrMat->texMRA = LoadTexture(fileName);
|
||||
pbrMat->useTexMRA = 1;
|
||||
break;
|
||||
case PBR_TEXTURE_NORMAL:
|
||||
pbrMat->texNormal = LoadTexture(fileName);
|
||||
pbrMat->useTexNormal = 1;
|
||||
break;
|
||||
case PBR_TEXTURE_EMISSIVE:
|
||||
pbrMat->texEmissive = LoadTexture(fileName);
|
||||
pbrMat->useTexEmissive = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UnloadPBRMaterial(PBRMaterial pbrMat){
|
||||
if(pbrMat.useTexAlbedo == 1) UnloadTexture(pbrMat.texAlbedo);
|
||||
if(pbrMat.useTexNormal == 1) UnloadTexture(pbrMat.texNormal);
|
||||
if(pbrMat.useTexMRA == 1) UnloadTexture(pbrMat.texMRA);
|
||||
if(pbrMat.useTexEmissive == 1) UnloadTexture(pbrMat.texEmissive);
|
||||
}
|
||||
|
||||
void PBRSetColor(PBRMaterial *pbrMat,PBRColorType pbrColorType,Color color){
|
||||
if(pbrMat == NULL) return;
|
||||
switch(pbrColorType){
|
||||
case PBR_COLOR_ALBEDO:
|
||||
pbrMat->albedo[0] = (float) color.r / 255;
|
||||
pbrMat->albedo[1] = (float) color.g / 255;
|
||||
pbrMat->albedo[2] = (float) color.b / 255;
|
||||
pbrMat->albedo[3] = (float) color.a / 255;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->albedoLoc,pbrMat->albedo,SHADER_UNIFORM_VEC4);
|
||||
break;
|
||||
case PBR_COLOR_EMISSIVE:
|
||||
pbrMat->emissive[0] = (float) color.r / 255;
|
||||
pbrMat->emissive[1] = (float) color.g / 255;
|
||||
pbrMat->emissive[2] = (float) color.b / 255;
|
||||
pbrMat->emissive[3] = (float) color.a / 255;
|
||||
SetShaderValue(pbrMat->pbrShader, pbrMat->emissiveColorLoc, pbrMat->emissive, SHADER_UNIFORM_VEC4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PBRSetFloat(PBRMaterial *pbrMat, PBRFloatType pbrParamType, float value){
|
||||
if(pbrMat == NULL) return;
|
||||
switch(pbrParamType){
|
||||
case PBR_PARAM_METALLIC:
|
||||
pbrMat->metallic = value;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->metallicLoc,&pbrMat->metallic,SHADER_UNIFORM_FLOAT);
|
||||
break;
|
||||
case PBR_PARAM_ROUGHNESS:
|
||||
pbrMat->roughness = value;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->roughnessLoc,&pbrMat->roughness,SHADER_UNIFORM_FLOAT);
|
||||
break;
|
||||
case PBR_PARAM_NORMAL:
|
||||
pbrMat->normal = value;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->normalLoc,&pbrMat->normal,SHADER_UNIFORM_FLOAT);
|
||||
break;
|
||||
case PBR_PARAM_AO:
|
||||
pbrMat->ao = value;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->aoLoc,&pbrMat->ao,SHADER_UNIFORM_FLOAT);
|
||||
break;
|
||||
case PBR_PARAM_EMISSIVE:
|
||||
pbrMat->emissivePower = value;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->emissivePowerLoc,&pbrMat->emissivePower,SHADER_UNIFORM_FLOAT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PBRSetVec2(PBRMaterial *pbrMat,PBRVec2Type type,Vector2 value){
|
||||
switch(type){
|
||||
case PBR_VEC2_TILING:
|
||||
pbrMat->texTiling[0] = value.x;
|
||||
pbrMat->texTiling[1] = value.y;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->texTilingLoc,&pbrMat->texTiling,SHADER_UNIFORM_VEC2);
|
||||
break;
|
||||
case PBR_VEC2_OFFSET:
|
||||
pbrMat->texOffset[0] = value.x;
|
||||
pbrMat->texOffset[1] = value.y;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->texOffsetLoc,&pbrMat->texOffset,SHADER_UNIFORM_VEC2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PBRSetMaterial(PBRModel* model,PBRMaterial* pbrMat,int matIndex){
|
||||
|
||||
|
||||
model->pbrMat = *pbrMat;
|
||||
model->model.materials[matIndex].shader = model->pbrMat.pbrShader;
|
||||
pbrMat->pbrShader.locs[SHADER_LOC_MAP_MRA] = GetShaderLocation(pbrMat->pbrShader, "mraMap");
|
||||
pbrMat->pbrShader.locs[SHADER_LOC_MAP_EMISSIVE] = GetShaderLocation(pbrMat->pbrShader, "emissiveMap");
|
||||
pbrMat->pbrShader.locs[SHADER_LOC_MAP_NORMAL] = GetShaderLocation(pbrMat->pbrShader, "normalMap");
|
||||
|
||||
if(pbrMat->useTexAlbedo) {
|
||||
model->model.materials[matIndex].maps[MATERIAL_MAP_ALBEDO].texture = pbrMat->texAlbedo;
|
||||
}
|
||||
if(pbrMat->useTexMRA) {
|
||||
model->model.materials[matIndex].maps[MATERIAL_MAP_MRA].texture = pbrMat->texMRA;
|
||||
}
|
||||
if(pbrMat->useTexNormal) {
|
||||
model->model.materials[matIndex].maps[MATERIAL_MAP_NORMAL].texture = pbrMat->texNormal;
|
||||
}
|
||||
if(pbrMat->useTexEmissive) {
|
||||
model->model.materials[matIndex].maps[MATERIAL_MAP_EMISSIVE].texture = pbrMat->texEmissive;
|
||||
}
|
||||
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->useTexAlbedoLoc,&pbrMat->useTexAlbedo,SHADER_UNIFORM_INT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->useTexNormalLoc,&pbrMat->useTexNormal,SHADER_UNIFORM_INT);
|
||||
SetShaderValue(pbrMat->pbrShader, pbrMat->useTexMRAELoc, &pbrMat->useTexMRA, SHADER_UNIFORM_INT);
|
||||
SetShaderValue(pbrMat->pbrShader, pbrMat->useTexEmissiveLoc, &pbrMat->useTexEmissive, SHADER_UNIFORM_INT);
|
||||
}
|
||||
|
||||
void PBRDrawModel(PBRModel pbrModel, Vector3 position, float scale){
|
||||
PBRMaterial *pbrMat = &pbrModel.pbrMat;
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->albedoLoc,pbrMat->albedo,SHADER_UNIFORM_VEC4);
|
||||
SetShaderValue(pbrMat->pbrShader, pbrMat->emissiveColorLoc, pbrMat->emissive, SHADER_UNIFORM_VEC4);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->metallicLoc,&pbrMat->metallic,SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->roughnessLoc,&pbrMat->roughness,SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->aoLoc,&pbrMat->ao,SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->normalLoc,&pbrMat->normal,SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->texTilingLoc,pbrMat->texTiling,SHADER_UNIFORM_VEC2);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->texOffsetLoc,pbrMat->texOffset,SHADER_UNIFORM_VEC2);
|
||||
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->useTexAlbedoLoc,&pbrMat->useTexAlbedo,SHADER_UNIFORM_INT);
|
||||
SetShaderValue(pbrMat->pbrShader,pbrMat->useTexNormalLoc,&pbrMat->useTexNormal,SHADER_UNIFORM_INT);
|
||||
SetShaderValue(pbrMat->pbrShader, pbrMat->useTexMRAELoc, &pbrMat->useTexMRA, SHADER_UNIFORM_INT);
|
||||
SetShaderValue(pbrMat->pbrShader, pbrMat->useTexEmissiveLoc, &pbrMat->useTexEmissive, SHADER_UNIFORM_INT);
|
||||
|
||||
DrawModel(pbrModel.model,position,scale,WHITE);
|
||||
}
|
||||
|
||||
PBRModel PBRModelLoad(const char *fileName){
|
||||
PBRModel pbrModel = (PBRModel){0};
|
||||
pbrModel.model = LoadModel(fileName);
|
||||
return pbrModel;
|
||||
}
|
||||
|
||||
PBRModel PBRModelLoadFromMesh(Mesh mesh){
|
||||
PBRModel pbrModel = (PBRModel){0};
|
||||
pbrModel.model = LoadModelFromMesh(mesh);
|
||||
return pbrModel;
|
||||
}
|
||||
#endif // RPBR_IMPLEMENTATION
|
||||
171
examples/shaders/shaders_basic_pbr.c
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Model Defuse Normal Shader (adapted for HTML5 platform)
|
||||
*
|
||||
* This example is prepared to compile for PLATFORM_WEB and PLATFORM_DESKTOP
|
||||
* As you will notice, code structure is slightly different to the other examples...
|
||||
* To compile it for PLATFORM_WEB just uncomment #define PLATFORM_WEB at beginning
|
||||
*
|
||||
* This example has been created using raylib 5.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2023-2024 Afan OLOVCIC (@_DevDad) 2015 Ramon Santamaria (@raysan5)
|
||||
* Model: "Old Rusty Car" (https://skfb.ly/LxRy) by Renafox is licensed under Creative Commons Attribution-NonCommercial (http://creativecommons.org/licenses/by-nc/4.0/).
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#define RPBR_IMPLEMENTATION
|
||||
#include "rpbr.h"
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#define GLSL_VERSION 330
|
||||
#else // PLATFORM_ANDROID, PLATFORM_WEB
|
||||
#define GLSL_VERSION 120
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Main Entry Point
|
||||
//----------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - basic pbr");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = { 0 };
|
||||
camera.position = (Vector3){ 2.0f, 2.0f, 6.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 0.5f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0f; // Camera field-of-view Y
|
||||
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
|
||||
|
||||
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/pbr.vs",GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/pbr.fs",GLSL_VERSION));
|
||||
|
||||
|
||||
|
||||
PBRModel model = PBRModelLoad("resources/models/old_car_new.glb");
|
||||
//if we use obj file formator if model doesn't have tangents we have to calculate MeshTangents
|
||||
//by using raylib function GenMeshTangents(mesh) for example: obj file doesn't support tangents
|
||||
//GenMeshTangents(&model.model.meshes[0]);
|
||||
|
||||
PBRMaterial model_mat = (PBRMaterial){0};
|
||||
PBRMaterialSetup(&model_mat, shader, NULL); //environment = NULL for now
|
||||
PBRLoadTextures(&model_mat, PBR_TEXTURE_ALBEDO, "resources/old_car_d.png");
|
||||
PBRLoadTextures(&model_mat, PBR_TEXTURE_MRA, "resources/old_car_mra.png");
|
||||
PBRLoadTextures(&model_mat, PBR_TEXTURE_NORMAL, "resources/old_car_n.png");
|
||||
PBRLoadTextures(&model_mat, PBR_TEXTURE_EMISSIVE, "resources/old_car_e.png");
|
||||
PBRSetColor(&model_mat,PBR_COLOR_EMISSIVE, (Color){255,162,0,255});
|
||||
PBRSetVec2(&model_mat, PBR_VEC2_TILING,(Vector2){0.5,0.5});
|
||||
PBRSetMaterial(&model,&model_mat,0);
|
||||
|
||||
PBRModel floor = PBRModelLoad("resources/models/plane.glb");
|
||||
|
||||
PBRMaterial floor_mat = (PBRMaterial){0};
|
||||
PBRMaterialSetup(&floor_mat, shader, NULL);
|
||||
PBRLoadTextures(&floor_mat, PBR_TEXTURE_ALBEDO, "resources/road_a.png");
|
||||
PBRLoadTextures(&floor_mat, PBR_TEXTURE_MRA, "resources/road_mra.png");
|
||||
PBRLoadTextures(&floor_mat, PBR_TEXTURE_NORMAL, "resources/road_n.png");
|
||||
PBRSetVec2(&floor_mat, PBR_VEC2_TILING,(Vector2){0.5,0.5});
|
||||
PBRSetMaterial(&floor,&floor_mat,0);
|
||||
|
||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||
int numOfLightsLoc = GetShaderLocation(shader, "numOfLights");
|
||||
int numOfLights = 4;
|
||||
SetShaderValue(shader, numOfLightsLoc, &numOfLights, SHADER_UNIFORM_INT);
|
||||
|
||||
Color ambCol = (Color){26,32,135,255};
|
||||
float ambIntens = 0.02;
|
||||
|
||||
int albedoLoc = GetShaderLocation(shader, "albedo");
|
||||
PBRSetAmbient(shader,ambCol,ambIntens);
|
||||
|
||||
// Create lights
|
||||
PBRLight lights[MAX_LIGHTS] = { 0 };
|
||||
lights[0] = PBRLightCreate(LIGHT_POINT, (Vector3){ -1, 1, -2 }, (Vector3){0,0,0}, YELLOW,4, shader);
|
||||
lights[1] = PBRLightCreate(LIGHT_POINT, (Vector3){ 2, 1, 1 }, (Vector3){0,0,0}, GREEN,3.3, shader);
|
||||
lights[2] = PBRLightCreate(LIGHT_POINT, (Vector3){ -2, 1, 1 }, (Vector3){0,0,0}, RED,8.3, shader);
|
||||
lights[3] = PBRLightCreate(LIGHT_POINT, (Vector3){ 1, 1, -2 }, (Vector3){0,0,0}, BLUE,2, shader);
|
||||
SetShaderValueV(shader, GetShaderLocation(shader, "lights"), lights, SHADER_UNIFORM_FLOAT, numOfLights);
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second-------------------------------------------------------------
|
||||
|
||||
int emissiveCnt = 0;
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera, CAMERA_ORBITAL);
|
||||
|
||||
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
|
||||
float cameraPos[3] = {camera.position.x, camera.position.y, camera.position.z};
|
||||
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
|
||||
|
||||
// Check key inputs to enable/disable lights
|
||||
if (IsKeyPressed(KEY_Y)) { lights[0].enabled = !lights[0].enabled; }
|
||||
if (IsKeyPressed(KEY_G)) { lights[1].enabled = !lights[1].enabled; }
|
||||
if (IsKeyPressed(KEY_R)) { lights[2].enabled = !lights[2].enabled; }
|
||||
if (IsKeyPressed(KEY_B)) { lights[3].enabled = !lights[3].enabled; }
|
||||
|
||||
// Update light values (actually, only enable/disable them)
|
||||
for (int i = 0; i < MAX_LIGHTS; i++) PBRLightUpdate(shader, lights[i]);
|
||||
emissiveCnt--;
|
||||
if(emissiveCnt<=0){
|
||||
emissiveCnt = GetRandomValue(0,20);
|
||||
PBRSetFloat(&model_mat,PBR_PARAM_EMISSIVE,(float)GetRandomValue(0,100)/100);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
BeginMode3D(camera);
|
||||
|
||||
PBRDrawModel(floor, (Vector3){0,0,0}, 5.0f);
|
||||
PBRDrawModel(model, (Vector3) {0, 0.0, 0}, 0.005);
|
||||
|
||||
// Draw spheres to show where the lights are
|
||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
||||
Color col = (Color) {lights[i].color[0] * 255, lights[i].color[1] * 255, lights[i].color[2] * 255,
|
||||
lights[i].color[3] * 255};
|
||||
if (lights[i].enabled) DrawSphereEx(lights[i].position, 0.2f, 8, 8, col);
|
||||
else DrawSphereWires(lights[i].position, 0.2f, 8, 8, ColorAlpha(col, 0.3f));
|
||||
}
|
||||
EndMode3D();
|
||||
|
||||
DrawText("(c) Old Rusty Car model by Renafox (https://skfb.ly/LxRy)", screenWidth - 320, screenHeight - 20, 10, GRAY);
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
UnloadModel(floor.model); // Unload model
|
||||
UnloadModel(model.model); // Unload model
|
||||
UnloadShader(shader); // Unload Shader
|
||||
UnloadPBRMaterial(floor_mat); // Unload PBRMaterial
|
||||
UnloadPBRMaterial(model_mat); // Unload PBRMaterial
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -170,4 +170,3 @@ int main(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
130
examples/textures/textures_image_kernel.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Image loading and texture creation
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* Example originally created with raylib 1.3, last time updated with raylib 1.3
|
||||
*
|
||||
* 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) 2015-2023 Karim Salem (@kimo-s)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
void NormalizeKernel(float *kernel, int size)
|
||||
{
|
||||
float sum = 0.0f;
|
||||
for (int i = 0; i < size; i++) sum += kernel[i];
|
||||
|
||||
if (sum != 0.0f)
|
||||
{
|
||||
for (int i = 0; i < size; i++) kernel[i] /= sum;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image convolution");
|
||||
|
||||
Image image = LoadImage("resources/cat.png"); // Loaded in CPU memory (RAM)
|
||||
|
||||
float gaussiankernel[] = {
|
||||
1.0f, 2.0f, 1.0f,
|
||||
2.0f, 4.0f, 2.0f,
|
||||
1.0f, 2.0f, 1.0f };
|
||||
|
||||
float sobelkernel[] = {
|
||||
1.0f, 0.0f, -1.0f,
|
||||
2.0f, 0.0f, -2.0f,
|
||||
1.0f, 0.0f, -1.0f };
|
||||
|
||||
float sharpenkernel[] = {
|
||||
0.0f, -1.0f, 0.0f,
|
||||
-1.0f, 5.0f, -1.0f,
|
||||
0.0f, -1.0f, 0.0f };
|
||||
|
||||
NormalizeKernel(gaussiankernel, 9);
|
||||
NormalizeKernel(sharpenkernel, 9);
|
||||
NormalizeKernel(sobelkernel, 9);
|
||||
|
||||
Image catSharpend = ImageCopy(image);
|
||||
ImageKernelConvolution(&catSharpend, sharpenkernel, 9);
|
||||
|
||||
Image catSobel = ImageCopy(image);
|
||||
ImageKernelConvolution(&catSobel, sobelkernel, 9);
|
||||
|
||||
Image catGaussian = ImageCopy(image);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
ImageKernelConvolution(&catGaussian, gaussiankernel, 9);
|
||||
}
|
||||
|
||||
ImageCrop(&image, (Rectangle){ 0, 0, (float)200, (float)450 });
|
||||
ImageCrop(&catGaussian, (Rectangle){ 0, 0, (float)200, (float)450 });
|
||||
ImageCrop(&catSobel, (Rectangle){ 0, 0, (float)200, (float)450 });
|
||||
ImageCrop(&catSharpend, (Rectangle){ 0, 0, (float)200, (float)450 });
|
||||
|
||||
// Images converted to texture, GPU memory (VRAM)
|
||||
Texture2D texture = LoadTextureFromImage(image);
|
||||
Texture2D catSharpendTexture = LoadTextureFromImage(catSharpend);
|
||||
Texture2D catSobelTexture = LoadTextureFromImage(catSobel);
|
||||
Texture2D catGaussianTexture = LoadTextureFromImage(catGaussian);
|
||||
|
||||
// Once images have been converted to texture and uploaded to VRAM,
|
||||
// they can be unloaded from RAM
|
||||
UnloadImage(image);
|
||||
UnloadImage(catGaussian);
|
||||
UnloadImage(catSobel);
|
||||
UnloadImage(catSharpend);
|
||||
|
||||
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);
|
||||
|
||||
DrawTexture(catSharpendTexture, 0, 0, WHITE);
|
||||
DrawTexture(catSobelTexture, 200, 0, WHITE);
|
||||
DrawTexture(catGaussianTexture, 400, 0, WHITE);
|
||||
DrawTexture(texture, 600, 0, WHITE);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture);
|
||||
UnloadTexture(catGaussianTexture);
|
||||
UnloadTexture(catSobelTexture);
|
||||
UnloadTexture(catSharpendTexture);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
examples/textures/textures_image_kernel.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
logo/raylib.icns
Normal file
BIN
logo/raylib_1024x1024.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
|
|
@ -9,13 +9,13 @@
|
|||
{
|
||||
"name": "RAYLIB_VERSION_MAJOR",
|
||||
"type": "INT",
|
||||
"value": 4,
|
||||
"value": 5,
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"name": "RAYLIB_VERSION_MINOR",
|
||||
"type": "INT",
|
||||
"value": 6,
|
||||
"value": 1,
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
{
|
||||
"name": "RAYLIB_VERSION",
|
||||
"type": "STRING",
|
||||
"value": "4.6-dev",
|
||||
"value": "5.1-dev",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
|
|
@ -1329,6 +1329,48 @@
|
|||
"description": "Filepaths entries"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AutomationEvent",
|
||||
"description": "Automation event",
|
||||
"fields": [
|
||||
{
|
||||
"type": "unsigned int",
|
||||
"name": "frame",
|
||||
"description": "Event frame"
|
||||
},
|
||||
{
|
||||
"type": "unsigned int",
|
||||
"name": "type",
|
||||
"description": "Event type (AutomationEventType)"
|
||||
},
|
||||
{
|
||||
"type": "int[4]",
|
||||
"name": "params",
|
||||
"description": "Event parameters (if required)"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AutomationEventList",
|
||||
"description": "Automation event list",
|
||||
"fields": [
|
||||
{
|
||||
"type": "unsigned int",
|
||||
"name": "capacity",
|
||||
"description": "Events max entries (MAX_AUTOMATION_EVENTS)"
|
||||
},
|
||||
{
|
||||
"type": "unsigned int",
|
||||
"name": "count",
|
||||
"description": "Events entries count"
|
||||
},
|
||||
{
|
||||
"type": "AutomationEvent *",
|
||||
"name": "events",
|
||||
"description": "Events entries"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
|
|
@ -3092,16 +3134,16 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "WindowShouldClose",
|
||||
"description": "Check if KEY_ESCAPE pressed or Close icon pressed",
|
||||
"returnType": "bool"
|
||||
},
|
||||
{
|
||||
"name": "CloseWindow",
|
||||
"description": "Close window and unload OpenGL context",
|
||||
"returnType": "void"
|
||||
},
|
||||
{
|
||||
"name": "WindowShouldClose",
|
||||
"description": "Check if application should close (KEY_ESCAPE pressed or windows close icon clicked)",
|
||||
"returnType": "bool"
|
||||
},
|
||||
{
|
||||
"name": "IsWindowReady",
|
||||
"description": "Check if window has been initialized successfully",
|
||||
|
|
@ -3467,27 +3509,6 @@
|
|||
"description": "Disable waiting for events on EndDrawing(), automatic events polling",
|
||||
"returnType": "void"
|
||||
},
|
||||
{
|
||||
"name": "SwapScreenBuffer",
|
||||
"description": "Swap back buffer with front buffer (screen drawing)",
|
||||
"returnType": "void"
|
||||
},
|
||||
{
|
||||
"name": "PollInputEvents",
|
||||
"description": "Register all input events",
|
||||
"returnType": "void"
|
||||
},
|
||||
{
|
||||
"name": "WaitTime",
|
||||
"description": "Wait for some time (halt program execution)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "double",
|
||||
"name": "seconds"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ShowCursor",
|
||||
"description": "Shows cursor",
|
||||
|
|
@ -3971,11 +3992,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetFPS",
|
||||
"description": "Get current FPS",
|
||||
"returnType": "int"
|
||||
},
|
||||
{
|
||||
"name": "GetFrameTime",
|
||||
"description": "Get time in seconds for last frame drawn (delta time)",
|
||||
|
|
@ -3986,6 +4002,43 @@
|
|||
"description": "Get elapsed time in seconds since InitWindow()",
|
||||
"returnType": "double"
|
||||
},
|
||||
{
|
||||
"name": "GetFPS",
|
||||
"description": "Get current FPS",
|
||||
"returnType": "int"
|
||||
},
|
||||
{
|
||||
"name": "SwapScreenBuffer",
|
||||
"description": "Swap back buffer with front buffer (screen drawing)",
|
||||
"returnType": "void"
|
||||
},
|
||||
{
|
||||
"name": "PollInputEvents",
|
||||
"description": "Register all input events",
|
||||
"returnType": "void"
|
||||
},
|
||||
{
|
||||
"name": "WaitTime",
|
||||
"description": "Wait for some time (halt program execution)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "double",
|
||||
"name": "seconds"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SetRandomSeed",
|
||||
"description": "Set the seed for the random number generator",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "unsigned int",
|
||||
"name": "seed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetRandomValue",
|
||||
"description": "Get a random value between min and max (both included)",
|
||||
|
|
@ -4002,13 +4055,32 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "SetRandomSeed",
|
||||
"description": "Set the seed for the random number generator",
|
||||
"returnType": "void",
|
||||
"name": "LoadRandomSequence",
|
||||
"description": "Load random values sequence, no values repeated",
|
||||
"returnType": "int *",
|
||||
"params": [
|
||||
{
|
||||
"type": "unsigned int",
|
||||
"name": "seed"
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "min"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "max"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "UnloadRandomSequence",
|
||||
"description": "Unload random values sequence",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "int *",
|
||||
"name": "sequence"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -4034,6 +4106,17 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenURL",
|
||||
"description": "Open URL with default system browser (if available)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "const char *",
|
||||
"name": "url"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "TraceLog",
|
||||
"description": "Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)",
|
||||
|
|
@ -4101,17 +4184,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenURL",
|
||||
"description": "Open URL with default system browser (if available)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "const char *",
|
||||
"name": "url"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SetTraceLogCallback",
|
||||
"description": "Set custom trace log",
|
||||
|
|
@ -4548,6 +4620,86 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LoadAutomationEventList",
|
||||
"description": "Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS",
|
||||
"returnType": "AutomationEventList",
|
||||
"params": [
|
||||
{
|
||||
"type": "const char *",
|
||||
"name": "fileName"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "UnloadAutomationEventList",
|
||||
"description": "Unload automation events list from file",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "AutomationEventList *",
|
||||
"name": "list"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ExportAutomationEventList",
|
||||
"description": "Export automation events list as text file",
|
||||
"returnType": "bool",
|
||||
"params": [
|
||||
{
|
||||
"type": "AutomationEventList",
|
||||
"name": "list"
|
||||
},
|
||||
{
|
||||
"type": "const char *",
|
||||
"name": "fileName"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SetAutomationEventList",
|
||||
"description": "Set automation event list to record to",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "AutomationEventList *",
|
||||
"name": "list"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SetAutomationEventBaseFrame",
|
||||
"description": "Set automation event internal base frame to start recording",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "frame"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "StartAutomationEventRecording",
|
||||
"description": "Start recording automation events (AutomationEventList must be set)",
|
||||
"returnType": "void"
|
||||
},
|
||||
{
|
||||
"name": "StopAutomationEventRecording",
|
||||
"description": "Stop recording automation events",
|
||||
"returnType": "void"
|
||||
},
|
||||
{
|
||||
"name": "PlayAutomationEvent",
|
||||
"description": "Play a recorded automation event",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "AutomationEvent",
|
||||
"name": "event"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "IsKeyPressed",
|
||||
"description": "Check if a key has been pressed once",
|
||||
|
|
@ -4603,6 +4755,16 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetKeyPressed",
|
||||
"description": "Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty",
|
||||
"returnType": "int"
|
||||
},
|
||||
{
|
||||
"name": "GetCharPressed",
|
||||
"description": "Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty",
|
||||
"returnType": "int"
|
||||
},
|
||||
{
|
||||
"name": "SetExitKey",
|
||||
"description": "Set a custom key to exit program (default is ESC)",
|
||||
|
|
@ -4614,16 +4776,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetKeyPressed",
|
||||
"description": "Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty",
|
||||
"returnType": "int"
|
||||
},
|
||||
{
|
||||
"name": "GetCharPressed",
|
||||
"description": "Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty",
|
||||
"returnType": "int"
|
||||
},
|
||||
{
|
||||
"name": "IsGamepadAvailable",
|
||||
"description": "Check if a gamepad is available",
|
||||
|
|
@ -5083,7 +5235,7 @@
|
|||
},
|
||||
{
|
||||
"name": "DrawLineV",
|
||||
"description": "Draw a line (Vector version)",
|
||||
"description": "Draw a line (using gl lines)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
|
|
@ -5102,7 +5254,7 @@
|
|||
},
|
||||
{
|
||||
"name": "DrawLineEx",
|
||||
"description": "Draw a line defining thickness",
|
||||
"description": "Draw a line (using triangles/quads)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
|
|
@ -5123,136 +5275,9 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawLineBezier",
|
||||
"description": "Draw a line using cubic-bezier curves in-out",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "startPos"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "endPos"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawLineBezierQuad",
|
||||
"description": "Draw line using quadratic bezier curves with a control point",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "startPos"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "endPos"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "controlPos"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawLineBezierCubic",
|
||||
"description": "Draw line using cubic bezier curves with 2 control points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "startPos"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "endPos"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "startControlPos"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "endControlPos"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawLineBSpline",
|
||||
"description": "Draw a B-Spline line, minimum 4 points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2 *",
|
||||
"name": "points"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "pointCount"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawLineCatmullRom",
|
||||
"description": "Draw a Catmull Rom spline line, minimum 4 points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2 *",
|
||||
"name": "points"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "pointCount"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawLineStrip",
|
||||
"description": "Draw lines sequence",
|
||||
"description": "Draw lines sequence (using gl lines)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
|
|
@ -5269,6 +5294,29 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawLineBezier",
|
||||
"description": "Draw line segment cubic-bezier in-out interpolation",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "startPos"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "endPos"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawCircle",
|
||||
"description": "Draw a color-filled circle",
|
||||
|
|
@ -5423,6 +5471,25 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawCircleLinesV",
|
||||
"description": "Draw circle outline (Vector version)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "center"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "radius"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawEllipse",
|
||||
"description": "Draw ellipse",
|
||||
|
|
@ -5985,6 +6052,387 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineLinear",
|
||||
"description": "Draw spline: Linear, minimum 2 points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2 *",
|
||||
"name": "points"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "pointCount"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineBasis",
|
||||
"description": "Draw spline: B-Spline, minimum 4 points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2 *",
|
||||
"name": "points"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "pointCount"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineCatmullRom",
|
||||
"description": "Draw spline: Catmull-Rom, minimum 4 points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2 *",
|
||||
"name": "points"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "pointCount"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineBezierQuadratic",
|
||||
"description": "Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2 *",
|
||||
"name": "points"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "pointCount"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineBezierCubic",
|
||||
"description": "Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2 *",
|
||||
"name": "points"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "pointCount"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineSegmentLinear",
|
||||
"description": "Draw spline segment: Linear, 2 points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p2"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineSegmentBasis",
|
||||
"description": "Draw spline segment: B-Spline, 4 points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p2"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p3"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p4"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineSegmentCatmullRom",
|
||||
"description": "Draw spline segment: Catmull-Rom, 4 points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p2"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p3"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p4"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineSegmentBezierQuadratic",
|
||||
"description": "Draw spline segment: Quadratic Bezier, 2 points, 1 control point",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "c2"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p3"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawSplineSegmentBezierCubic",
|
||||
"description": "Draw spline segment: Cubic Bezier, 2 points, 2 control points",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "c2"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "c3"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p4"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "thick"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetSplinePointLinear",
|
||||
"description": "Get (evaluate) spline point: Linear",
|
||||
"returnType": "Vector2",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "startPos"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "endPos"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "t"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetSplinePointBasis",
|
||||
"description": "Get (evaluate) spline point: B-Spline",
|
||||
"returnType": "Vector2",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p2"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p3"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p4"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "t"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetSplinePointCatmullRom",
|
||||
"description": "Get (evaluate) spline point: Catmull-Rom",
|
||||
"returnType": "Vector2",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p2"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p3"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p4"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "t"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetSplinePointBezierQuad",
|
||||
"description": "Get (evaluate) spline point: Quadratic Bezier",
|
||||
"returnType": "Vector2",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "c2"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p3"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "t"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetSplinePointBezierCubic",
|
||||
"description": "Get (evaluate) spline point: Cubic Bezier",
|
||||
"returnType": "Vector2",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p1"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "c2"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "c3"
|
||||
},
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "p4"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "t"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CheckCollisionRecs",
|
||||
"description": "Check collision between two rectangles",
|
||||
|
|
@ -6768,6 +7216,25 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ImageKernelConvolution",
|
||||
"description": "Apply Custom Square image convolution kernel",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Image *",
|
||||
"name": "image"
|
||||
},
|
||||
{
|
||||
"type": "float*",
|
||||
"name": "kernel"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "kernelSize"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ImageResize",
|
||||
"description": "Resize image (Bicubic scaling algorithm)",
|
||||
|
|
@ -10339,6 +10806,11 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GetMasterVolume",
|
||||
"description": "Get master volume (listener)",
|
||||
"returnType": "float"
|
||||
},
|
||||
{
|
||||
"name": "LoadWave",
|
||||
"description": "Load wave data from file",
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ return {
|
|||
{
|
||||
name = "RAYLIB_VERSION_MAJOR",
|
||||
type = "INT",
|
||||
value = 4,
|
||||
value = 5,
|
||||
description = ""
|
||||
},
|
||||
{
|
||||
name = "RAYLIB_VERSION_MINOR",
|
||||
type = "INT",
|
||||
value = 6,
|
||||
value = 1,
|
||||
description = ""
|
||||
},
|
||||
{
|
||||
|
|
@ -27,7 +27,7 @@ return {
|
|||
{
|
||||
name = "RAYLIB_VERSION",
|
||||
type = "STRING",
|
||||
value = "4.6-dev",
|
||||
value = "5.1-dev",
|
||||
description = ""
|
||||
},
|
||||
{
|
||||
|
|
@ -1329,6 +1329,48 @@ return {
|
|||
description = "Filepaths entries"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "AutomationEvent",
|
||||
description = "Automation event",
|
||||
fields = {
|
||||
{
|
||||
type = "unsigned int",
|
||||
name = "frame",
|
||||
description = "Event frame"
|
||||
},
|
||||
{
|
||||
type = "unsigned int",
|
||||
name = "type",
|
||||
description = "Event type (AutomationEventType)"
|
||||
},
|
||||
{
|
||||
type = "int[4]",
|
||||
name = "params",
|
||||
description = "Event parameters (if required)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "AutomationEventList",
|
||||
description = "Automation event list",
|
||||
fields = {
|
||||
{
|
||||
type = "unsigned int",
|
||||
name = "capacity",
|
||||
description = "Events max entries (MAX_AUTOMATION_EVENTS)"
|
||||
},
|
||||
{
|
||||
type = "unsigned int",
|
||||
name = "count",
|
||||
description = "Events entries count"
|
||||
},
|
||||
{
|
||||
type = "AutomationEvent *",
|
||||
name = "events",
|
||||
description = "Events entries"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
aliases = {
|
||||
|
|
@ -3044,16 +3086,16 @@ return {
|
|||
{type = "const char *", name = "title"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "WindowShouldClose",
|
||||
description = "Check if KEY_ESCAPE pressed or Close icon pressed",
|
||||
returnType = "bool"
|
||||
},
|
||||
{
|
||||
name = "CloseWindow",
|
||||
description = "Close window and unload OpenGL context",
|
||||
returnType = "void"
|
||||
},
|
||||
{
|
||||
name = "WindowShouldClose",
|
||||
description = "Check if application should close (KEY_ESCAPE pressed or windows close icon clicked)",
|
||||
returnType = "bool"
|
||||
},
|
||||
{
|
||||
name = "IsWindowReady",
|
||||
description = "Check if window has been initialized successfully",
|
||||
|
|
@ -3344,24 +3386,6 @@ return {
|
|||
description = "Disable waiting for events on EndDrawing(), automatic events polling",
|
||||
returnType = "void"
|
||||
},
|
||||
{
|
||||
name = "SwapScreenBuffer",
|
||||
description = "Swap back buffer with front buffer (screen drawing)",
|
||||
returnType = "void"
|
||||
},
|
||||
{
|
||||
name = "PollInputEvents",
|
||||
description = "Register all input events",
|
||||
returnType = "void"
|
||||
},
|
||||
{
|
||||
name = "WaitTime",
|
||||
description = "Wait for some time (halt program execution)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "double", name = "seconds"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "ShowCursor",
|
||||
description = "Shows cursor",
|
||||
|
|
@ -3686,11 +3710,6 @@ return {
|
|||
{type = "int", name = "fps"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetFPS",
|
||||
description = "Get current FPS",
|
||||
returnType = "int"
|
||||
},
|
||||
{
|
||||
name = "GetFrameTime",
|
||||
description = "Get time in seconds for last frame drawn (delta time)",
|
||||
|
|
@ -3701,6 +3720,37 @@ return {
|
|||
description = "Get elapsed time in seconds since InitWindow()",
|
||||
returnType = "double"
|
||||
},
|
||||
{
|
||||
name = "GetFPS",
|
||||
description = "Get current FPS",
|
||||
returnType = "int"
|
||||
},
|
||||
{
|
||||
name = "SwapScreenBuffer",
|
||||
description = "Swap back buffer with front buffer (screen drawing)",
|
||||
returnType = "void"
|
||||
},
|
||||
{
|
||||
name = "PollInputEvents",
|
||||
description = "Register all input events",
|
||||
returnType = "void"
|
||||
},
|
||||
{
|
||||
name = "WaitTime",
|
||||
description = "Wait for some time (halt program execution)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "double", name = "seconds"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "SetRandomSeed",
|
||||
description = "Set the seed for the random number generator",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "unsigned int", name = "seed"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetRandomValue",
|
||||
description = "Get a random value between min and max (both included)",
|
||||
|
|
@ -3711,11 +3761,21 @@ return {
|
|||
}
|
||||
},
|
||||
{
|
||||
name = "SetRandomSeed",
|
||||
description = "Set the seed for the random number generator",
|
||||
name = "LoadRandomSequence",
|
||||
description = "Load random values sequence, no values repeated",
|
||||
returnType = "int *",
|
||||
params = {
|
||||
{type = "unsigned int", name = "count"},
|
||||
{type = "int", name = "min"},
|
||||
{type = "int", name = "max"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "UnloadRandomSequence",
|
||||
description = "Unload random values sequence",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "unsigned int", name = "seed"}
|
||||
{type = "int *", name = "sequence"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -3734,6 +3794,14 @@ return {
|
|||
{type = "unsigned int", name = "flags"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "OpenURL",
|
||||
description = "Open URL with default system browser (if available)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "const char *", name = "url"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "TraceLog",
|
||||
description = "Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)",
|
||||
|
|
@ -3777,14 +3845,6 @@ return {
|
|||
{type = "void *", name = "ptr"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "OpenURL",
|
||||
description = "Open URL with default system browser (if available)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "const char *", name = "url"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "SetTraceLogCallback",
|
||||
description = "Set custom trace log",
|
||||
|
|
@ -4077,6 +4137,65 @@ return {
|
|||
{type = "int *", name = "outputSize"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "LoadAutomationEventList",
|
||||
description = "Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS",
|
||||
returnType = "AutomationEventList",
|
||||
params = {
|
||||
{type = "const char *", name = "fileName"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "UnloadAutomationEventList",
|
||||
description = "Unload automation events list from file",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "AutomationEventList *", name = "list"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "ExportAutomationEventList",
|
||||
description = "Export automation events list as text file",
|
||||
returnType = "bool",
|
||||
params = {
|
||||
{type = "AutomationEventList", name = "list"},
|
||||
{type = "const char *", name = "fileName"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "SetAutomationEventList",
|
||||
description = "Set automation event list to record to",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "AutomationEventList *", name = "list"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "SetAutomationEventBaseFrame",
|
||||
description = "Set automation event internal base frame to start recording",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "int", name = "frame"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "StartAutomationEventRecording",
|
||||
description = "Start recording automation events (AutomationEventList must be set)",
|
||||
returnType = "void"
|
||||
},
|
||||
{
|
||||
name = "StopAutomationEventRecording",
|
||||
description = "Stop recording automation events",
|
||||
returnType = "void"
|
||||
},
|
||||
{
|
||||
name = "PlayAutomationEvent",
|
||||
description = "Play a recorded automation event",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "AutomationEvent", name = "event"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "IsKeyPressed",
|
||||
description = "Check if a key has been pressed once",
|
||||
|
|
@ -4117,14 +4236,6 @@ return {
|
|||
{type = "int", name = "key"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "SetExitKey",
|
||||
description = "Set a custom key to exit program (default is ESC)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "int", name = "key"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetKeyPressed",
|
||||
description = "Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty",
|
||||
|
|
@ -4135,6 +4246,14 @@ return {
|
|||
description = "Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty",
|
||||
returnType = "int"
|
||||
},
|
||||
{
|
||||
name = "SetExitKey",
|
||||
description = "Set a custom key to exit program (default is ESC)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "int", name = "key"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "IsGamepadAvailable",
|
||||
description = "Check if a gamepad is available",
|
||||
|
|
@ -4453,7 +4572,7 @@ return {
|
|||
},
|
||||
{
|
||||
name = "DrawLineV",
|
||||
description = "Draw a line (Vector version)",
|
||||
description = "Draw a line (using gl lines)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "startPos"},
|
||||
|
|
@ -4463,7 +4582,7 @@ return {
|
|||
},
|
||||
{
|
||||
name = "DrawLineEx",
|
||||
description = "Draw a line defining thickness",
|
||||
description = "Draw a line (using triangles/quads)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "startPos"},
|
||||
|
|
@ -4472,67 +4591,9 @@ return {
|
|||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawLineBezier",
|
||||
description = "Draw a line using cubic-bezier curves in-out",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "startPos"},
|
||||
{type = "Vector2", name = "endPos"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawLineBezierQuad",
|
||||
description = "Draw line using quadratic bezier curves with a control point",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "startPos"},
|
||||
{type = "Vector2", name = "endPos"},
|
||||
{type = "Vector2", name = "controlPos"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawLineBezierCubic",
|
||||
description = "Draw line using cubic bezier curves with 2 control points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "startPos"},
|
||||
{type = "Vector2", name = "endPos"},
|
||||
{type = "Vector2", name = "startControlPos"},
|
||||
{type = "Vector2", name = "endControlPos"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawLineBSpline",
|
||||
description = "Draw a B-Spline line, minimum 4 points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2 *", name = "points"},
|
||||
{type = "int", name = "pointCount"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawLineCatmullRom",
|
||||
description = "Draw a Catmull Rom spline line, minimum 4 points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2 *", name = "points"},
|
||||
{type = "int", name = "pointCount"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawLineStrip",
|
||||
description = "Draw lines sequence",
|
||||
description = "Draw lines sequence (using gl lines)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2 *", name = "points"},
|
||||
|
|
@ -4540,6 +4601,17 @@ return {
|
|||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawLineBezier",
|
||||
description = "Draw line segment cubic-bezier in-out interpolation",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "startPos"},
|
||||
{type = "Vector2", name = "endPos"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawCircle",
|
||||
description = "Draw a color-filled circle",
|
||||
|
|
@ -4610,6 +4682,16 @@ return {
|
|||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawCircleLinesV",
|
||||
description = "Draw circle outline (Vector version)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "center"},
|
||||
{type = "float", name = "radius"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawEllipse",
|
||||
description = "Draw ellipse",
|
||||
|
|
@ -4866,6 +4948,180 @@ return {
|
|||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineLinear",
|
||||
description = "Draw spline: Linear, minimum 2 points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2 *", name = "points"},
|
||||
{type = "int", name = "pointCount"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineBasis",
|
||||
description = "Draw spline: B-Spline, minimum 4 points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2 *", name = "points"},
|
||||
{type = "int", name = "pointCount"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineCatmullRom",
|
||||
description = "Draw spline: Catmull-Rom, minimum 4 points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2 *", name = "points"},
|
||||
{type = "int", name = "pointCount"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineBezierQuadratic",
|
||||
description = "Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2 *", name = "points"},
|
||||
{type = "int", name = "pointCount"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineBezierCubic",
|
||||
description = "Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2 *", name = "points"},
|
||||
{type = "int", name = "pointCount"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineSegmentLinear",
|
||||
description = "Draw spline segment: Linear, 2 points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "p2"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineSegmentBasis",
|
||||
description = "Draw spline segment: B-Spline, 4 points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "p2"},
|
||||
{type = "Vector2", name = "p3"},
|
||||
{type = "Vector2", name = "p4"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineSegmentCatmullRom",
|
||||
description = "Draw spline segment: Catmull-Rom, 4 points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "p2"},
|
||||
{type = "Vector2", name = "p3"},
|
||||
{type = "Vector2", name = "p4"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineSegmentBezierQuadratic",
|
||||
description = "Draw spline segment: Quadratic Bezier, 2 points, 1 control point",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "c2"},
|
||||
{type = "Vector2", name = "p3"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawSplineSegmentBezierCubic",
|
||||
description = "Draw spline segment: Cubic Bezier, 2 points, 2 control points",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "c2"},
|
||||
{type = "Vector2", name = "c3"},
|
||||
{type = "Vector2", name = "p4"},
|
||||
{type = "float", name = "thick"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetSplinePointLinear",
|
||||
description = "Get (evaluate) spline point: Linear",
|
||||
returnType = "Vector2",
|
||||
params = {
|
||||
{type = "Vector2", name = "startPos"},
|
||||
{type = "Vector2", name = "endPos"},
|
||||
{type = "float", name = "t"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetSplinePointBasis",
|
||||
description = "Get (evaluate) spline point: B-Spline",
|
||||
returnType = "Vector2",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "p2"},
|
||||
{type = "Vector2", name = "p3"},
|
||||
{type = "Vector2", name = "p4"},
|
||||
{type = "float", name = "t"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetSplinePointCatmullRom",
|
||||
description = "Get (evaluate) spline point: Catmull-Rom",
|
||||
returnType = "Vector2",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "p2"},
|
||||
{type = "Vector2", name = "p3"},
|
||||
{type = "Vector2", name = "p4"},
|
||||
{type = "float", name = "t"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetSplinePointBezierQuad",
|
||||
description = "Get (evaluate) spline point: Quadratic Bezier",
|
||||
returnType = "Vector2",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "c2"},
|
||||
{type = "Vector2", name = "p3"},
|
||||
{type = "float", name = "t"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetSplinePointBezierCubic",
|
||||
description = "Get (evaluate) spline point: Cubic Bezier",
|
||||
returnType = "Vector2",
|
||||
params = {
|
||||
{type = "Vector2", name = "p1"},
|
||||
{type = "Vector2", name = "c2"},
|
||||
{type = "Vector2", name = "c3"},
|
||||
{type = "Vector2", name = "p4"},
|
||||
{type = "float", name = "t"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "CheckCollisionRecs",
|
||||
description = "Check collision between two rectangles",
|
||||
|
|
@ -5286,6 +5542,16 @@ return {
|
|||
{type = "int", name = "blurSize"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "ImageKernelConvolution",
|
||||
description = "Apply Custom Square image convolution kernel",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Image *", name = "image"},
|
||||
{type = "float*", name = "kernel"},
|
||||
{type = "int", name = "kernelSize"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "ImageResize",
|
||||
description = "Resize image (Bicubic scaling algorithm)",
|
||||
|
|
@ -7195,6 +7461,11 @@ return {
|
|||
{type = "float", name = "volume"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "GetMasterVolume",
|
||||
description = "Get master volume (listener)",
|
||||
returnType = "float"
|
||||
},
|
||||
{
|
||||
name = "LoadWave",
|
||||
description = "Load wave data from file",
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
<raylibAPI>
|
||||
<Defines count="56">
|
||||
<Define name="RAYLIB_H" type="GUARD" value="" desc="" />
|
||||
<Define name="RAYLIB_VERSION_MAJOR" type="INT" value="4" desc="" />
|
||||
<Define name="RAYLIB_VERSION_MINOR" type="INT" value="6" desc="" />
|
||||
<Define name="RAYLIB_VERSION_MAJOR" type="INT" value="5" desc="" />
|
||||
<Define name="RAYLIB_VERSION_MINOR" type="INT" value="1" desc="" />
|
||||
<Define name="RAYLIB_VERSION_PATCH" type="INT" value="0" desc="" />
|
||||
<Define name="RAYLIB_VERSION" type="STRING" value="4.6-dev" desc="" />
|
||||
<Define name="RAYLIB_VERSION" type="STRING" value="5.1-dev" 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="PI" type="FLOAT" value="3.14159265358979323846" desc="" />
|
||||
|
|
@ -58,7 +58,7 @@
|
|||
<Define name="SHADER_LOC_MAP_DIFFUSE" type="UNKNOWN" value="SHADER_LOC_MAP_ALBEDO" desc="" />
|
||||
<Define name="SHADER_LOC_MAP_SPECULAR" type="UNKNOWN" value="SHADER_LOC_MAP_METALNESS" desc="" />
|
||||
</Defines>
|
||||
<Structs count="32">
|
||||
<Structs count="34">
|
||||
<Struct name="Vector2" fieldCount="2" desc="Vector2, 2 components">
|
||||
<Field type="float" name="x" desc="Vector x component" />
|
||||
<Field type="float" name="y" desc="Vector y component" />
|
||||
|
|
@ -283,6 +283,16 @@
|
|||
<Field type="unsigned int" name="count" desc="Filepaths entries count" />
|
||||
<Field type="char **" name="paths" desc="Filepaths entries" />
|
||||
</Struct>
|
||||
<Struct name="AutomationEvent" fieldCount="3" desc="Automation event">
|
||||
<Field type="unsigned int" name="frame" desc="Event frame" />
|
||||
<Field type="unsigned int" name="type" desc="Event type (AutomationEventType)" />
|
||||
<Field type="int[4]" name="params" desc="Event parameters (if required)" />
|
||||
</Struct>
|
||||
<Struct name="AutomationEventList" fieldCount="3" desc="Automation event list">
|
||||
<Field type="unsigned int" name="capacity" desc="Events max entries (MAX_AUTOMATION_EVENTS)" />
|
||||
<Field type="unsigned int" name="count" desc="Events entries count" />
|
||||
<Field type="AutomationEvent *" name="events" desc="Events entries" />
|
||||
</Struct>
|
||||
</Structs>
|
||||
<Aliases count="5">
|
||||
<Alias type="Quaternion" name="Vector4" desc="Quaternion, 4 components (Vector4 alias)" />
|
||||
|
|
@ -660,16 +670,16 @@
|
|||
<Param type="unsigned int" name="frames" desc="" />
|
||||
</Callback>
|
||||
</Callbacks>
|
||||
<Functions count="529">
|
||||
<Functions count="553">
|
||||
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
||||
<Param type="int" name="width" desc="" />
|
||||
<Param type="int" name="height" desc="" />
|
||||
<Param type="const char *" name="title" desc="" />
|
||||
</Function>
|
||||
<Function name="WindowShouldClose" retType="bool" paramCount="0" desc="Check if KEY_ESCAPE pressed or Close icon pressed">
|
||||
</Function>
|
||||
<Function name="CloseWindow" retType="void" paramCount="0" desc="Close window and unload OpenGL context">
|
||||
</Function>
|
||||
<Function name="WindowShouldClose" retType="bool" paramCount="0" desc="Check if application should close (KEY_ESCAPE pressed or windows close icon clicked)">
|
||||
</Function>
|
||||
<Function name="IsWindowReady" retType="bool" paramCount="0" desc="Check if window has been initialized successfully">
|
||||
</Function>
|
||||
<Function name="IsWindowFullscreen" retType="bool" paramCount="0" desc="Check if window is currently fullscreen">
|
||||
|
|
@ -785,13 +795,6 @@
|
|||
</Function>
|
||||
<Function name="DisableEventWaiting" retType="void" paramCount="0" desc="Disable waiting for events on EndDrawing(), automatic events polling">
|
||||
</Function>
|
||||
<Function name="SwapScreenBuffer" retType="void" paramCount="0" desc="Swap back buffer with front buffer (screen drawing)">
|
||||
</Function>
|
||||
<Function name="PollInputEvents" retType="void" paramCount="0" desc="Register all input events">
|
||||
</Function>
|
||||
<Function name="WaitTime" retType="void" paramCount="1" desc="Wait for some time (halt program execution)">
|
||||
<Param type="double" name="seconds" desc="" />
|
||||
</Function>
|
||||
<Function name="ShowCursor" retType="void" paramCount="0" desc="Shows cursor">
|
||||
</Function>
|
||||
<Function name="HideCursor" retType="void" paramCount="0" desc="Hides cursor">
|
||||
|
|
@ -931,18 +934,33 @@
|
|||
<Function name="SetTargetFPS" retType="void" paramCount="1" desc="Set target FPS (maximum)">
|
||||
<Param type="int" name="fps" desc="" />
|
||||
</Function>
|
||||
<Function name="GetFPS" retType="int" paramCount="0" desc="Get current FPS">
|
||||
</Function>
|
||||
<Function name="GetFrameTime" retType="float" paramCount="0" desc="Get time in seconds for last frame drawn (delta time)">
|
||||
</Function>
|
||||
<Function name="GetTime" retType="double" paramCount="0" desc="Get elapsed time in seconds since InitWindow()">
|
||||
</Function>
|
||||
<Function name="GetFPS" retType="int" paramCount="0" desc="Get current FPS">
|
||||
</Function>
|
||||
<Function name="SwapScreenBuffer" retType="void" paramCount="0" desc="Swap back buffer with front buffer (screen drawing)">
|
||||
</Function>
|
||||
<Function name="PollInputEvents" retType="void" paramCount="0" desc="Register all input events">
|
||||
</Function>
|
||||
<Function name="WaitTime" retType="void" paramCount="1" desc="Wait for some time (halt program execution)">
|
||||
<Param type="double" name="seconds" desc="" />
|
||||
</Function>
|
||||
<Function name="SetRandomSeed" retType="void" paramCount="1" desc="Set the seed for the random number generator">
|
||||
<Param type="unsigned int" name="seed" desc="" />
|
||||
</Function>
|
||||
<Function name="GetRandomValue" retType="int" paramCount="2" desc="Get a random value between min and max (both included)">
|
||||
<Param type="int" name="min" desc="" />
|
||||
<Param type="int" name="max" desc="" />
|
||||
</Function>
|
||||
<Function name="SetRandomSeed" retType="void" paramCount="1" desc="Set the seed for the random number generator">
|
||||
<Param type="unsigned int" name="seed" desc="" />
|
||||
<Function name="LoadRandomSequence" retType="int *" paramCount="3" desc="Load random values sequence, no values repeated">
|
||||
<Param type="unsigned int" name="count" desc="" />
|
||||
<Param type="int" name="min" desc="" />
|
||||
<Param type="int" name="max" desc="" />
|
||||
</Function>
|
||||
<Function name="UnloadRandomSequence" retType="void" paramCount="1" desc="Unload random values sequence">
|
||||
<Param type="int *" name="sequence" desc="" />
|
||||
</Function>
|
||||
<Function name="TakeScreenshot" retType="void" paramCount="1" desc="Takes a screenshot of current screen (filename extension defines format)">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
|
|
@ -950,6 +968,9 @@
|
|||
<Function name="SetConfigFlags" retType="void" paramCount="1" desc="Setup init configuration flags (view FLAGS)">
|
||||
<Param type="unsigned int" name="flags" desc="" />
|
||||
</Function>
|
||||
<Function name="OpenURL" retType="void" paramCount="1" desc="Open URL with default system browser (if available)">
|
||||
<Param type="const char *" name="url" desc="" />
|
||||
</Function>
|
||||
<Function name="TraceLog" retType="void" paramCount="3" desc="Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)">
|
||||
<Param type="int" name="logLevel" desc="" />
|
||||
<Param type="const char *" name="text" desc="" />
|
||||
|
|
@ -968,9 +989,6 @@
|
|||
<Function name="MemFree" retType="void" paramCount="1" desc="Internal memory free">
|
||||
<Param type="void *" name="ptr" desc="" />
|
||||
</Function>
|
||||
<Function name="OpenURL" retType="void" paramCount="1" desc="Open URL with default system browser (if available)">
|
||||
<Param type="const char *" name="url" desc="" />
|
||||
</Function>
|
||||
<Function name="SetTraceLogCallback" retType="void" paramCount="1" desc="Set custom trace log">
|
||||
<Param type="TraceLogCallback" name="callback" desc="" />
|
||||
</Function>
|
||||
|
|
@ -1091,6 +1109,29 @@
|
|||
<Param type="const unsigned char *" name="data" desc="" />
|
||||
<Param type="int *" name="outputSize" desc="" />
|
||||
</Function>
|
||||
<Function name="LoadAutomationEventList" retType="AutomationEventList" paramCount="1" desc="Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
</Function>
|
||||
<Function name="UnloadAutomationEventList" retType="void" paramCount="1" desc="Unload automation events list from file">
|
||||
<Param type="AutomationEventList *" name="list" desc="" />
|
||||
</Function>
|
||||
<Function name="ExportAutomationEventList" retType="bool" paramCount="2" desc="Export automation events list as text file">
|
||||
<Param type="AutomationEventList" name="list" desc="" />
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
</Function>
|
||||
<Function name="SetAutomationEventList" retType="void" paramCount="1" desc="Set automation event list to record to">
|
||||
<Param type="AutomationEventList *" name="list" desc="" />
|
||||
</Function>
|
||||
<Function name="SetAutomationEventBaseFrame" retType="void" paramCount="1" desc="Set automation event internal base frame to start recording">
|
||||
<Param type="int" name="frame" desc="" />
|
||||
</Function>
|
||||
<Function name="StartAutomationEventRecording" retType="void" paramCount="0" desc="Start recording automation events (AutomationEventList must be set)">
|
||||
</Function>
|
||||
<Function name="StopAutomationEventRecording" retType="void" paramCount="0" desc="Stop recording automation events">
|
||||
</Function>
|
||||
<Function name="PlayAutomationEvent" retType="void" paramCount="1" desc="Play a recorded automation event">
|
||||
<Param type="AutomationEvent" name="event" desc="" />
|
||||
</Function>
|
||||
<Function name="IsKeyPressed" retType="bool" paramCount="1" desc="Check if a key has been pressed once">
|
||||
<Param type="int" name="key" desc="" />
|
||||
</Function>
|
||||
|
|
@ -1106,13 +1147,13 @@
|
|||
<Function name="IsKeyUp" retType="bool" paramCount="1" desc="Check if a key is NOT being pressed">
|
||||
<Param type="int" name="key" desc="" />
|
||||
</Function>
|
||||
<Function name="SetExitKey" retType="void" paramCount="1" desc="Set a custom key to exit program (default is ESC)">
|
||||
<Param type="int" name="key" desc="" />
|
||||
</Function>
|
||||
<Function name="GetKeyPressed" retType="int" paramCount="0" desc="Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty">
|
||||
</Function>
|
||||
<Function name="GetCharPressed" retType="int" paramCount="0" desc="Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty">
|
||||
</Function>
|
||||
<Function name="SetExitKey" retType="void" paramCount="1" desc="Set a custom key to exit program (default is ESC)">
|
||||
<Param type="int" name="key" desc="" />
|
||||
</Function>
|
||||
<Function name="IsGamepadAvailable" retType="bool" paramCount="1" desc="Check if a gamepad is available">
|
||||
<Param type="int" name="gamepad" desc="" />
|
||||
</Function>
|
||||
|
|
@ -1246,55 +1287,28 @@
|
|||
<Param type="int" name="endPosY" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawLineV" retType="void" paramCount="3" desc="Draw a line (Vector version)">
|
||||
<Function name="DrawLineV" retType="void" paramCount="3" desc="Draw a line (using gl lines)">
|
||||
<Param type="Vector2" name="startPos" desc="" />
|
||||
<Param type="Vector2" name="endPos" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawLineEx" retType="void" paramCount="4" desc="Draw a line defining thickness">
|
||||
<Function name="DrawLineEx" retType="void" paramCount="4" desc="Draw a line (using triangles/quads)">
|
||||
<Param type="Vector2" name="startPos" desc="" />
|
||||
<Param type="Vector2" name="endPos" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawLineBezier" retType="void" paramCount="4" desc="Draw a line using cubic-bezier curves in-out">
|
||||
<Param type="Vector2" name="startPos" desc="" />
|
||||
<Param type="Vector2" name="endPos" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawLineBezierQuad" retType="void" paramCount="5" desc="Draw line using quadratic bezier curves with a control point">
|
||||
<Param type="Vector2" name="startPos" desc="" />
|
||||
<Param type="Vector2" name="endPos" desc="" />
|
||||
<Param type="Vector2" name="controlPos" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawLineBezierCubic" retType="void" paramCount="6" desc="Draw line using cubic bezier curves with 2 control points">
|
||||
<Param type="Vector2" name="startPos" desc="" />
|
||||
<Param type="Vector2" name="endPos" desc="" />
|
||||
<Param type="Vector2" name="startControlPos" desc="" />
|
||||
<Param type="Vector2" name="endControlPos" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawLineBSpline" retType="void" paramCount="4" desc="Draw a B-Spline line, minimum 4 points">
|
||||
<Function name="DrawLineStrip" retType="void" paramCount="3" desc="Draw lines sequence (using gl lines)">
|
||||
<Param type="Vector2 *" name="points" desc="" />
|
||||
<Param type="int" name="pointCount" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawLineCatmullRom" retType="void" paramCount="4" desc="Draw a Catmull Rom spline line, minimum 4 points">
|
||||
<Param type="Vector2 *" name="points" desc="" />
|
||||
<Param type="int" name="pointCount" desc="" />
|
||||
<Function name="DrawLineBezier" retType="void" paramCount="4" desc="Draw line segment cubic-bezier in-out interpolation">
|
||||
<Param type="Vector2" name="startPos" desc="" />
|
||||
<Param type="Vector2" name="endPos" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawLineStrip" retType="void" paramCount="3" desc="Draw lines sequence">
|
||||
<Param type="Vector2 *" name="points" desc="" />
|
||||
<Param type="int" name="pointCount" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawCircle" retType="void" paramCount="4" desc="Draw a color-filled circle">
|
||||
<Param type="int" name="centerX" desc="" />
|
||||
<Param type="int" name="centerY" desc="" />
|
||||
|
|
@ -1335,6 +1349,11 @@
|
|||
<Param type="float" name="radius" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawCircleLinesV" retType="void" paramCount="3" desc="Draw circle outline (Vector version)">
|
||||
<Param type="Vector2" name="center" desc="" />
|
||||
<Param type="float" name="radius" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawEllipse" retType="void" paramCount="5" desc="Draw ellipse">
|
||||
<Param type="int" name="centerX" desc="" />
|
||||
<Param type="int" name="centerY" desc="" />
|
||||
|
|
@ -1481,6 +1500,105 @@
|
|||
<Param type="float" name="lineThick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineLinear" retType="void" paramCount="4" desc="Draw spline: Linear, minimum 2 points">
|
||||
<Param type="Vector2 *" name="points" desc="" />
|
||||
<Param type="int" name="pointCount" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineBasis" retType="void" paramCount="4" desc="Draw spline: B-Spline, minimum 4 points">
|
||||
<Param type="Vector2 *" name="points" desc="" />
|
||||
<Param type="int" name="pointCount" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineCatmullRom" retType="void" paramCount="4" desc="Draw spline: Catmull-Rom, minimum 4 points">
|
||||
<Param type="Vector2 *" name="points" desc="" />
|
||||
<Param type="int" name="pointCount" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineBezierQuadratic" retType="void" paramCount="4" desc="Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...]">
|
||||
<Param type="Vector2 *" name="points" desc="" />
|
||||
<Param type="int" name="pointCount" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineBezierCubic" retType="void" paramCount="4" desc="Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...]">
|
||||
<Param type="Vector2 *" name="points" desc="" />
|
||||
<Param type="int" name="pointCount" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineSegmentLinear" retType="void" paramCount="4" desc="Draw spline segment: Linear, 2 points">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="p2" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineSegmentBasis" retType="void" paramCount="6" desc="Draw spline segment: B-Spline, 4 points">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="p2" desc="" />
|
||||
<Param type="Vector2" name="p3" desc="" />
|
||||
<Param type="Vector2" name="p4" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineSegmentCatmullRom" retType="void" paramCount="6" desc="Draw spline segment: Catmull-Rom, 4 points">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="p2" desc="" />
|
||||
<Param type="Vector2" name="p3" desc="" />
|
||||
<Param type="Vector2" name="p4" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineSegmentBezierQuadratic" retType="void" paramCount="5" desc="Draw spline segment: Quadratic Bezier, 2 points, 1 control point">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="c2" desc="" />
|
||||
<Param type="Vector2" name="p3" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawSplineSegmentBezierCubic" retType="void" paramCount="6" desc="Draw spline segment: Cubic Bezier, 2 points, 2 control points">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="c2" desc="" />
|
||||
<Param type="Vector2" name="c3" desc="" />
|
||||
<Param type="Vector2" name="p4" desc="" />
|
||||
<Param type="float" name="thick" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="GetSplinePointLinear" retType="Vector2" paramCount="3" desc="Get (evaluate) spline point: Linear">
|
||||
<Param type="Vector2" name="startPos" desc="" />
|
||||
<Param type="Vector2" name="endPos" desc="" />
|
||||
<Param type="float" name="t" desc="" />
|
||||
</Function>
|
||||
<Function name="GetSplinePointBasis" retType="Vector2" paramCount="5" desc="Get (evaluate) spline point: B-Spline">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="p2" desc="" />
|
||||
<Param type="Vector2" name="p3" desc="" />
|
||||
<Param type="Vector2" name="p4" desc="" />
|
||||
<Param type="float" name="t" desc="" />
|
||||
</Function>
|
||||
<Function name="GetSplinePointCatmullRom" retType="Vector2" paramCount="5" desc="Get (evaluate) spline point: Catmull-Rom">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="p2" desc="" />
|
||||
<Param type="Vector2" name="p3" desc="" />
|
||||
<Param type="Vector2" name="p4" desc="" />
|
||||
<Param type="float" name="t" desc="" />
|
||||
</Function>
|
||||
<Function name="GetSplinePointBezierQuad" retType="Vector2" paramCount="4" desc="Get (evaluate) spline point: Quadratic Bezier">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="c2" desc="" />
|
||||
<Param type="Vector2" name="p3" desc="" />
|
||||
<Param type="float" name="t" desc="" />
|
||||
</Function>
|
||||
<Function name="GetSplinePointBezierCubic" retType="Vector2" paramCount="5" desc="Get (evaluate) spline point: Cubic Bezier">
|
||||
<Param type="Vector2" name="p1" desc="" />
|
||||
<Param type="Vector2" name="c2" desc="" />
|
||||
<Param type="Vector2" name="c3" desc="" />
|
||||
<Param type="Vector2" name="p4" desc="" />
|
||||
<Param type="float" name="t" desc="" />
|
||||
</Function>
|
||||
<Function name="CheckCollisionRecs" retType="bool" paramCount="2" desc="Check collision between two rectangles">
|
||||
<Param type="Rectangle" name="rec1" desc="" />
|
||||
<Param type="Rectangle" name="rec2" desc="" />
|
||||
|
|
@ -1688,6 +1806,11 @@
|
|||
<Param type="Image *" name="image" desc="" />
|
||||
<Param type="int" name="blurSize" desc="" />
|
||||
</Function>
|
||||
<Function name="ImageKernelConvolution" retType="void" paramCount="3" desc="Apply Custom Square image convolution kernel">
|
||||
<Param type="Image *" name="image" desc="" />
|
||||
<Param type="float*" name="kernel" desc="" />
|
||||
<Param type="int" name="kernelSize" desc="" />
|
||||
</Function>
|
||||
<Function name="ImageResize" retType="void" paramCount="3" desc="Resize image (Bicubic scaling algorithm)">
|
||||
<Param type="Image *" name="image" desc="" />
|
||||
<Param type="int" name="newWidth" desc="" />
|
||||
|
|
@ -2632,6 +2755,8 @@
|
|||
<Function name="SetMasterVolume" retType="void" paramCount="1" desc="Set master volume (listener)">
|
||||
<Param type="float" name="volume" desc="" />
|
||||
</Function>
|
||||
<Function name="GetMasterVolume" retType="float" paramCount="0" desc="Get master volume (listener)">
|
||||
</Function>
|
||||
<Function name="LoadWave" retType="Wave" paramCount="1" desc="Load wave data from file">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
</Function>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ project(example)
|
|||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Dependencies
|
||||
set(RAYLIB_VERSION 4.5.0)
|
||||
set(RAYLIB_VERSION 5.0)
|
||||
find_package(raylib ${RAYLIB_VERSION} QUIET) # QUIET or REQUIRED
|
||||
if (NOT raylib_FOUND) # If there's none, fetch and build raylib
|
||||
include(FetchContent)
|
||||
|
|
|
|||
|
|
@ -375,6 +375,7 @@ RLAPI void ImageAlphaClear(Image *image, Color color, float threshold);
|
|||
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
|
||||
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 ImageKernelConvolution(Image *image, float* kernel, int kernelSize); // Apply Custom Square image convolution kernel
|
||||
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm)
|
||||
RLAPI void 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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Setup the project and settings
|
||||
project(raylib C)
|
||||
set(PROJECT_VERSION 4.5.0)
|
||||
set(API_VERSION 450)
|
||||
set(PROJECT_VERSION 5.0.0)
|
||||
set(API_VERSION 500)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(JoinPaths)
|
||||
|
|
@ -62,12 +62,10 @@ if (NOT BUILD_SHARED_LIBS)
|
|||
add_library(raylib_static ALIAS raylib)
|
||||
else()
|
||||
MESSAGE(STATUS "Building raylib shared library")
|
||||
if (WIN32)
|
||||
target_compile_definitions(raylib
|
||||
PRIVATE $<BUILD_INTERFACE:BUILD_LIBTYPE_SHARED>
|
||||
INTERFACE $<INSTALL_INTERFACE:USE_LIBTYPE_SHARED>
|
||||
)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if (${PLATFORM} MATCHES "Web")
|
||||
|
|
@ -84,6 +82,11 @@ if (WITH_PIC OR BUILD_SHARED_LIBS)
|
|||
set_property(TARGET raylib PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
endif ()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
# Hide raylib's symbols by default so RLAPI can expose them
|
||||
set_property(TARGET raylib PROPERTY C_VISIBILITY_PRESET hidden)
|
||||
endif ()
|
||||
|
||||
target_link_libraries(raylib "${LIBS_PRIVATE}")
|
||||
|
||||
# Sets some compile time definitions for the pre-processor
|
||||
|
|
|
|||
14
src/Makefile
|
|
@ -114,7 +114,7 @@ HOST_PLATFORM_OS ?= WINDOWS
|
|||
PLATFORM_OS ?= WINDOWS
|
||||
|
||||
# Determine PLATFORM_OS when required
|
||||
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_WEB))
|
||||
ifeq ($(PLATFORM),$(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_DESKTOP_SDL PLATFORM_WEB PLATFORM_ANDROID))
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows!
|
||||
# ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
|
|
@ -190,8 +190,12 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
|||
ANDROID_TOOLCHAIN = $(ANDROID_NDK)/toolchains/llvm/prebuilt/windows-x86_64
|
||||
else
|
||||
ANDROID_NDK ?= /usr/lib/android/ndk
|
||||
ifeq ($(PLATFORM_OS), OSX)
|
||||
ANDROID_TOOLCHAIN = $(ANDROID_NDK)/toolchains/llvm/prebuilt/darwin-x86_64
|
||||
else
|
||||
ANDROID_TOOLCHAIN = $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64
|
||||
endif
|
||||
endif
|
||||
|
||||
# NOTE: Sysroot can also be reference from $(ANDROID_NDK)/sysroot
|
||||
ANDROID_SYSROOT ?= $(ANDROID_TOOLCHAIN)/sysroot
|
||||
|
|
@ -376,7 +380,7 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
|||
# -Werror=format-security
|
||||
CFLAGS += -Wa,--noexecstack -Wformat -no-canonical-prefixes
|
||||
# Preprocessor macro definitions
|
||||
CFLAGS += -D__ANDROID__ -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION) -DMAL_NO_OSS
|
||||
CFLAGS += -D__ANDROID__ -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION)
|
||||
endif
|
||||
|
||||
# Define required compilation flags for raylib SHARED lib
|
||||
|
|
@ -385,7 +389,13 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED)
|
|||
# BE CAREFUL: It seems that for gcc -fpic is not the same as -fPIC
|
||||
# MinGW32 just doesn't need -fPIC, it shows warnings
|
||||
CFLAGS += -fPIC -DBUILD_LIBTYPE_SHARED
|
||||
|
||||
# hide all symbols by default, so RLAPI can expose them
|
||||
ifeq ($(PLATFORM_OS),$(filter $(PLATFORM_OS), LINUX BSD OSX))
|
||||
CFLAGS += -fvisibility=hidden
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_DRM)
|
||||
# without EGL_NO_X11 eglplatform.h tears Xlib.h in which tears X.h in
|
||||
# which contains a conflicting type Font
|
||||
|
|
|
|||
5
src/external/rprand.h
vendored
|
|
@ -200,8 +200,7 @@ int *rprand_load_sequence(unsigned int count, int min, int max)
|
|||
|
||||
for (unsigned int i = 0; i < count;)
|
||||
{
|
||||
value = ((int)rprand_xoshiro()%(abs(max - min) + 1)) + min;
|
||||
value_is_dup = false;
|
||||
value = ((unsigned int)rprand_xoshiro()%(abs(max - min) + 1)) + min;
|
||||
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
|
|
@ -217,6 +216,8 @@ int *rprand_load_sequence(unsigned int count, int min, int max)
|
|||
sequence[i] = value;
|
||||
i++;
|
||||
}
|
||||
|
||||
value_is_dup = false;
|
||||
}
|
||||
|
||||
return sequence;
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||
static void CharCallback(GLFWwindow *window, unsigned int key); // GLFW3 Char Key Callback, runs on key pressed (get char value)
|
||||
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed
|
||||
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y); // GLFW3 Cursor Position Callback, runs on mouse move
|
||||
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
|
||||
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Scrolling Callback, runs on mouse wheel
|
||||
static void CursorEnterCallback(GLFWwindow *window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
|
||||
static void JoystickCallback(int jid, int event); // GLFW3 Joystick Connected/Disconnected Callback
|
||||
|
||||
|
|
@ -1137,7 +1137,7 @@ void PollInputEvents(void)
|
|||
//for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.position[i] = (Vector2){ 0, 0 };
|
||||
|
||||
// Map touch position to mouse position for convenience
|
||||
// WARNING: If the target desktop device supports touch screen, this behavious should be reviewed!
|
||||
// WARNING: If the target desktop device supports touch screen, this behaviour should be reviewed!
|
||||
// TODO: GLFW does not support multi-touch input just yet
|
||||
// https://www.codeproject.com/Articles/668404/Programming-for-Multi-Touch
|
||||
// https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages
|
||||
|
|
@ -1739,6 +1739,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
|
|||
// WARNING: GLFW could only return GLFW_PRESS (1) or GLFW_RELEASE (0) for now,
|
||||
// but future releases may add more actions (i.e. GLFW_REPEAT)
|
||||
CORE.Input.Mouse.currentButtonState[button] = action;
|
||||
CORE.Input.Touch.currentTouchState[button] = action;
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
|
|
|
|||
|
|
@ -48,8 +48,14 @@
|
|||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "SDL.h" // SDL base library (window/rendered, input, timming... functionality)
|
||||
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
|
||||
#include "SDL.h" // SDL base library (window/rendered, input, timing... functionality)
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// It seems it does not need to be included to work
|
||||
//#include "SDL_opengles2.h"
|
||||
#else
|
||||
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
|
|
@ -493,9 +499,9 @@ void SetWindowIcon(Image image)
|
|||
bmask = 0x001F, amask = 0;
|
||||
depth = 16, pitch = image.width * 2;
|
||||
break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8:
|
||||
rmask = 0xFF0000, gmask = 0x00FF00;
|
||||
bmask = 0x0000FF, amask = 0;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // Uses BGR for 24-bit
|
||||
rmask = 0x0000FF, gmask = 0x00FF00;
|
||||
bmask = 0xFF0000, amask = 0;
|
||||
depth = 24, pitch = image.width * 3;
|
||||
break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
|
||||
|
|
@ -592,7 +598,7 @@ void SetWindowMonitor(int monitor)
|
|||
// NOTE:
|
||||
// 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3,
|
||||
// see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba
|
||||
// 2. A workround for SDL2 is leaving fullscreen, moving the window, then entering full screen again.
|
||||
// 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again.
|
||||
const bool wasFullscreen = ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) ? true : false;
|
||||
|
||||
const int screenWidth = CORE.Window.screen.width;
|
||||
|
|
@ -611,7 +617,7 @@ void SetWindowMonitor(int monitor)
|
|||
// ending up positioned partly outside the target display.
|
||||
// 2. The workaround for that is, previously to moving the window,
|
||||
// setting the window size to the target display size, so they match.
|
||||
// 3. It was't done here because we can't assume changing the window size automatically
|
||||
// 3. It wasn't done here because we can't assume changing the window size automatically
|
||||
// is acceptable behavior by the user.
|
||||
SDL_SetWindowPosition(platform.window, usableBounds.x, usableBounds.y);
|
||||
CORE.Window.position.x = usableBounds.x;
|
||||
|
|
@ -935,6 +941,8 @@ int SetGamepadMappings(const char *mappings)
|
|||
// Set mouse position XY
|
||||
void SetMousePosition(int x, int y)
|
||||
{
|
||||
SDL_WarpMouseInWindow(platform.window, x, y);
|
||||
|
||||
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
|
||||
CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
|
||||
}
|
||||
|
|
@ -961,9 +969,6 @@ void PollInputEvents(void)
|
|||
CORE.Input.Keyboard.keyPressedQueueCount = 0;
|
||||
CORE.Input.Keyboard.charPressedQueueCount = 0;
|
||||
|
||||
// Reset key repeats
|
||||
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
|
||||
|
||||
// Reset mouse wheel
|
||||
CORE.Input.Mouse.currentWheelMove.x = 0;
|
||||
CORE.Input.Mouse.currentWheelMove.y = 0;
|
||||
|
|
@ -991,7 +996,7 @@ void PollInputEvents(void)
|
|||
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
|
||||
|
||||
int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE
|
||||
bool gestureUpdate = false; // Flag to note gestures require to update
|
||||
bool realTouch = false; // Flag to differentiate real touch gestures from mouse ones
|
||||
|
||||
// Register previous keys states
|
||||
// NOTE: Android supports up to 260 keys
|
||||
|
|
@ -1004,7 +1009,7 @@ void PollInputEvents(void)
|
|||
// Register previous mouse states
|
||||
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
|
||||
|
||||
// Poll input events for current plaform
|
||||
// Poll input events for current platform
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
// WARNING: Indexes into this array are obtained by using SDL_Scancode values, not SDL_Keycode values
|
||||
|
|
@ -1089,6 +1094,8 @@ void PollInputEvents(void)
|
|||
KeyboardKey key = ConvertScancodeToKey(event.key.keysym.scancode);
|
||||
if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 1;
|
||||
|
||||
if (event.key.repeat) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
||||
|
||||
// TODO: Put exitKey verification outside the switch?
|
||||
if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey])
|
||||
{
|
||||
|
|
@ -1102,6 +1109,25 @@ void PollInputEvents(void)
|
|||
if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0;
|
||||
} break;
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
// Check if there is space available in the key queue
|
||||
if (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)
|
||||
{
|
||||
// Add character to the queue
|
||||
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = event.text.text[0];
|
||||
CORE.Input.Keyboard.keyPressedQueueCount++;
|
||||
}
|
||||
|
||||
// Check if there is space available in the queue
|
||||
if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)
|
||||
{
|
||||
// Add character to the queue
|
||||
CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = event.text.text[0];
|
||||
CORE.Input.Keyboard.charPressedQueueCount++;
|
||||
}
|
||||
} break;
|
||||
|
||||
// Check mouse events
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
|
|
@ -1112,9 +1138,9 @@ void PollInputEvents(void)
|
|||
else if (btn == 1) btn = 2;
|
||||
|
||||
CORE.Input.Mouse.currentButtonState[btn] = 1;
|
||||
CORE.Input.Touch.currentTouchState[btn] = 1;
|
||||
|
||||
touchAction = 1;
|
||||
gestureUpdate = true;
|
||||
} break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
|
|
@ -1125,9 +1151,9 @@ void PollInputEvents(void)
|
|||
else if (btn == 1) btn = 2;
|
||||
|
||||
CORE.Input.Mouse.currentButtonState[btn] = 0;
|
||||
CORE.Input.Touch.currentTouchState[btn] = 0;
|
||||
|
||||
touchAction = 0;
|
||||
gestureUpdate = true;
|
||||
} break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
|
|
@ -1150,7 +1176,38 @@ void PollInputEvents(void)
|
|||
|
||||
CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition;
|
||||
touchAction = 2;
|
||||
gestureUpdate = true;
|
||||
} break;
|
||||
|
||||
// Check touch events
|
||||
// NOTE: These cases need to be reviewed on a real touch screen
|
||||
case SDL_FINGERDOWN:
|
||||
{
|
||||
const int touchId = (int)event.tfinger.fingerId;
|
||||
CORE.Input.Touch.currentTouchState[touchId] = 1;
|
||||
CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width;
|
||||
CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height;
|
||||
|
||||
touchAction = 1;
|
||||
realTouch = true;
|
||||
} break;
|
||||
case SDL_FINGERUP:
|
||||
{
|
||||
const int touchId = (int)event.tfinger.fingerId;
|
||||
CORE.Input.Touch.currentTouchState[touchId] = 0;
|
||||
CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width;
|
||||
CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height;
|
||||
|
||||
touchAction = 0;
|
||||
realTouch = true;
|
||||
} break;
|
||||
case SDL_FINGERMOTION:
|
||||
{
|
||||
const int touchId = (int)event.tfinger.fingerId;
|
||||
CORE.Input.Touch.position[touchId].x = event.tfinger.x * CORE.Window.screen.width;
|
||||
CORE.Input.Touch.position[touchId].y = event.tfinger.y * CORE.Window.screen.height;
|
||||
|
||||
touchAction = 2;
|
||||
realTouch = true;
|
||||
} break;
|
||||
|
||||
// Check gamepad events
|
||||
|
|
@ -1175,7 +1232,7 @@ void PollInputEvents(void)
|
|||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
if (gestureUpdate)
|
||||
if (touchAction > -1)
|
||||
{
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
|
@ -1190,7 +1247,7 @@ void PollInputEvents(void)
|
|||
gestureEvent.pointCount = 1;
|
||||
|
||||
// Register touch points position, only one point registered
|
||||
if (touchAction == 2) gestureEvent.position[0] = CORE.Input.Touch.position[0];
|
||||
if (touchAction == 2 || realTouch) gestureEvent.position[0] = CORE.Input.Touch.position[0];
|
||||
else gestureEvent.position[0] = GetMousePosition();
|
||||
|
||||
// Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height
|
||||
|
|
@ -1199,6 +1256,8 @@ void PollInputEvents(void)
|
|||
|
||||
// Gesture data is sent to gestures-system for processing
|
||||
ProcessGestureEvent(gestureEvent);
|
||||
|
||||
touchAction = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1310,7 +1369,7 @@ int InitPlatform(void)
|
|||
// Init OpenGL context
|
||||
platform.glContext = SDL_GL_CreateContext(platform.window);
|
||||
|
||||
// Check window and glContext have been initialized succesfully
|
||||
// Check window and glContext have been initialized successfully
|
||||
if ((platform.window != NULL) && (platform.glContext != NULL))
|
||||
{
|
||||
CORE.Window.ready = true;
|
||||
|
|
@ -1351,10 +1410,15 @@ int InitPlatform(void)
|
|||
//if (platform.gamepadgamepad == NULL) TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
|
||||
}
|
||||
|
||||
// Disable mouse events being interpreted as touch events
|
||||
// NOTE: This is wanted because there are SDL_FINGER* events available which provide unique data
|
||||
// Due to the way PollInputEvents() and rgestures.h are currently implemented, setting this won't break SUPPORT_MOUSE_GESTURES
|
||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||
|
||||
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Initialize timming system
|
||||
// Initialize timing system
|
||||
//----------------------------------------------------------------------------
|
||||
// NOTE: No need to call InitTimer(), let SDL manage it internally
|
||||
CORE.Time.previous = GetTime(); // Get time as double
|
||||
|
|
|
|||
|
|
@ -545,9 +545,6 @@ void PollInputEvents(void)
|
|||
CORE.Input.Keyboard.keyPressedQueueCount = 0;
|
||||
CORE.Input.Keyboard.charPressedQueueCount = 0;
|
||||
|
||||
// Reset key repeats
|
||||
for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
|
||||
|
||||
// Reset last gamepad button/axis registered state
|
||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
||||
//CORE.Input.Gamepad.axisCount = 0;
|
||||
|
|
@ -573,6 +570,7 @@ void PollInputEvents(void)
|
|||
{
|
||||
CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
|
||||
CORE.Input.Mouse.currentButtonState[i] = platform.currentButtonStateEvdev[i];
|
||||
CORE.Input.Touch.currentTouchState[i] = platform.currentButtonStateEvdev[i];
|
||||
}
|
||||
|
||||
// Register gamepads buttons events
|
||||
|
|
@ -603,7 +601,6 @@ void PollInputEvents(void)
|
|||
struct input_event event = { 0 };
|
||||
|
||||
int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE
|
||||
bool gestureUpdate = false; // Flag to note gestures require to update
|
||||
|
||||
// Try to read data from the mouse/touch/gesture and only continue if successful
|
||||
while (read(fd, &event, sizeof(event)) == (int)sizeof(event))
|
||||
|
|
@ -622,7 +619,6 @@ void PollInputEvents(void)
|
|||
CORE.Input.Touch.position[0].x = CORE.Input.Mouse.currentPosition.x;
|
||||
|
||||
touchAction = 2; // TOUCH_ACTION_MOVE
|
||||
gestureUpdate = true;
|
||||
}
|
||||
|
||||
if (event.code == REL_Y)
|
||||
|
|
@ -636,7 +632,6 @@ void PollInputEvents(void)
|
|||
CORE.Input.Touch.position[0].y = CORE.Input.Mouse.currentPosition.y;
|
||||
|
||||
touchAction = 2; // TOUCH_ACTION_MOVE
|
||||
gestureUpdate = true;
|
||||
}
|
||||
|
||||
if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value;
|
||||
|
|
@ -652,7 +647,6 @@ void PollInputEvents(void)
|
|||
CORE.Input.Touch.position[0].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width; // Scale according to absRange
|
||||
|
||||
touchAction = 2; // TOUCH_ACTION_MOVE
|
||||
gestureUpdate = true;
|
||||
}
|
||||
|
||||
if (event.code == ABS_Y)
|
||||
|
|
@ -661,7 +655,6 @@ void PollInputEvents(void)
|
|||
CORE.Input.Touch.position[0].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height; // Scale according to absRange
|
||||
|
||||
touchAction = 2; // TOUCH_ACTION_MOVE
|
||||
gestureUpdate = true;
|
||||
}
|
||||
|
||||
// Multitouch movement
|
||||
|
|
@ -697,7 +690,6 @@ void PollInputEvents(void)
|
|||
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;
|
||||
|
||||
touchAction = 0; // TOUCH_ACTION_UP
|
||||
gestureUpdate = true;
|
||||
}
|
||||
|
||||
if (event.value && !previousMouseLeftButtonState)
|
||||
|
|
@ -705,7 +697,6 @@ void PollInputEvents(void)
|
|||
platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;
|
||||
|
||||
touchAction = 1; // TOUCH_ACTION_DOWN
|
||||
gestureUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -721,7 +712,6 @@ void PollInputEvents(void)
|
|||
|
||||
if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN
|
||||
else touchAction = 0; // TOUCH_ACTION_UP
|
||||
gestureUpdate = true;
|
||||
}
|
||||
|
||||
if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;
|
||||
|
|
@ -750,7 +740,7 @@ void PollInputEvents(void)
|
|||
}
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
if (gestureUpdate)
|
||||
if (touchAction > -1)
|
||||
{
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
|
|
@ -765,7 +755,7 @@ void PollInputEvents(void)
|
|||
|
||||
ProcessGestureEvent(gestureEvent);
|
||||
|
||||
gestureUpdate = false;
|
||||
touchAction = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1696,6 +1686,7 @@ static void PollKeyboardEvents(void)
|
|||
// Event interface: 'value' is the value the event carries. Either a relative change for EV_REL,
|
||||
// absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for release, 1 for keypress and 2 for autorepeat
|
||||
CORE.Input.Keyboard.currentKeyState[keycode] = (event.value >= 1)? 1 : 0;
|
||||
CORE.Input.Keyboard.keyRepeatInFrame[keycode] = (event.value == 2)? 1 : 0;
|
||||
if (event.value >= 1)
|
||||
{
|
||||
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; // Register last key pressed
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ void PollInputEvents(void)
|
|||
CORE.Input.Keyboard.keyRepeatInFrame[i] = 0;
|
||||
}
|
||||
|
||||
// TODO: Poll input events for current plaform
|
||||
// TODO: Poll input events for current platform
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -561,13 +561,13 @@ int InitPlatform(void)
|
|||
|
||||
// TODO: Initialize input events system
|
||||
// It could imply keyboard, mouse, gamepad, touch...
|
||||
// Depending on the platform libraries/SDK it could use a callbacks mechanims
|
||||
// Depending on the platform libraries/SDK it could use a callback mechanism
|
||||
// For system events and inputs evens polling on a per-frame basis, use PollInputEvents()
|
||||
//----------------------------------------------------------------------------
|
||||
// ...
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// TODO: Initialize timming system
|
||||
// TODO: Initialize timing system
|
||||
//----------------------------------------------------------------------------
|
||||
InitTimer();
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
GLFWwindow *handle; // GLFW window handle (graphic device)
|
||||
bool ourFullscreen; // Internal var to filter our handling of fullscreen vs the user handling of fullscreen
|
||||
} PlatformData;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -140,6 +141,37 @@ bool WindowShouldClose(void)
|
|||
// Toggle fullscreen mode
|
||||
void ToggleFullscreen(void)
|
||||
{
|
||||
platform.ourFullscreen = true;
|
||||
bool enterFullscreen = false;
|
||||
|
||||
const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0);
|
||||
if (wasFullscreen)
|
||||
{
|
||||
EM_ASM(document.exitFullscreen(););
|
||||
|
||||
if (CORE.Window.flags & FLAG_FULLSCREEN_MODE) enterFullscreen = false;
|
||||
else enterFullscreen = true;
|
||||
|
||||
CORE.Window.fullscreen = false;
|
||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||
CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
||||
}
|
||||
else enterFullscreen = true;
|
||||
|
||||
if (enterFullscreen)
|
||||
{
|
||||
// NOTE: The setTimeouts handle the browser mode change delay
|
||||
EM_ASM(
|
||||
setTimeout(function()
|
||||
{
|
||||
Module.requestFullscreen(false, false);
|
||||
}, 100);
|
||||
);
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
}
|
||||
|
||||
// NOTE: Old notes below:
|
||||
/*
|
||||
EM_ASM
|
||||
(
|
||||
|
|
@ -204,14 +236,44 @@ void ToggleFullscreen(void)
|
|||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||
}
|
||||
*/
|
||||
|
||||
CORE.Window.fullscreen = !CORE.Window.fullscreen; // Toggle fullscreen flag
|
||||
}
|
||||
|
||||
// Toggle borderless windowed mode
|
||||
void ToggleBorderlessWindowed(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ToggleBorderlessWindowed() not available on target platform");
|
||||
platform.ourFullscreen = true;
|
||||
bool enterBorderless = false;
|
||||
|
||||
const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0);
|
||||
if (wasFullscreen)
|
||||
{
|
||||
EM_ASM(document.exitFullscreen(););
|
||||
|
||||
if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) enterBorderless = false;
|
||||
else enterBorderless = true;
|
||||
|
||||
CORE.Window.fullscreen = false;
|
||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||
CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
||||
}
|
||||
else enterBorderless = true;
|
||||
|
||||
if (enterBorderless)
|
||||
{
|
||||
// NOTE: 1. The setTimeouts handle the browser mode change delay
|
||||
// 2. The style unset handles the possibility of a width="value%" like on the default shell.html file
|
||||
EM_ASM(
|
||||
setTimeout(function()
|
||||
{
|
||||
Module.requestFullscreen(false, true);
|
||||
setTimeout(function()
|
||||
{
|
||||
canvas.style.width="unset";
|
||||
}, 100);
|
||||
}, 100);
|
||||
);
|
||||
CORE.Window.flags |= FLAG_BORDERLESS_WINDOWED_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
// Set window state: maximized, if resizable
|
||||
|
|
@ -235,13 +297,215 @@ void RestoreWindow(void)
|
|||
// Set window configuration state using flags
|
||||
void SetWindowState(unsigned int flags)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState() not available on target platform");
|
||||
// Check previous state and requested state to apply required changes
|
||||
// NOTE: In most cases the functions already change the flags internally
|
||||
|
||||
// State change: FLAG_VSYNC_HINT
|
||||
if ((flags & FLAG_VSYNC_HINT) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_VSYNC_HINT) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_BORDERLESS_WINDOWED_MODE
|
||||
if (((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) != (flags & FLAG_BORDERLESS_WINDOWED_MODE)) && ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0))
|
||||
{
|
||||
ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function
|
||||
}
|
||||
|
||||
// State change: FLAG_FULLSCREEN_MODE
|
||||
if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) != (flags & FLAG_FULLSCREEN_MODE))
|
||||
{
|
||||
ToggleFullscreen(); // NOTE: Window state flag updated inside function
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_RESIZABLE
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) != (flags & FLAG_WINDOW_RESIZABLE)) && ((flags & FLAG_WINDOW_RESIZABLE) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_TRUE);
|
||||
CORE.Window.flags |= FLAG_WINDOW_RESIZABLE;
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_UNDECORATED
|
||||
if ((flags & FLAG_WINDOW_UNDECORATED) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_UNDECORATED) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_HIDDEN
|
||||
if ((flags & FLAG_WINDOW_HIDDEN) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_HIDDEN) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_MINIMIZED
|
||||
if ((flags & FLAG_WINDOW_MINIMIZED) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MINIMIZED) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_MAXIMIZED
|
||||
if ((flags & FLAG_WINDOW_MAXIMIZED) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MAXIMIZED) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_UNFOCUSED
|
||||
if ((flags & FLAG_WINDOW_UNFOCUSED) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_UNFOCUSED) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_TOPMOST
|
||||
if ((flags & FLAG_WINDOW_TOPMOST) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_TOPMOST) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_ALWAYS_RUN
|
||||
if ((flags & FLAG_WINDOW_ALWAYS_RUN) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_ALWAYS_RUN) not available on target platform");
|
||||
}
|
||||
|
||||
// The following states can not be changed after window creation
|
||||
// NOTE: Review for PLATFORM_WEB
|
||||
|
||||
// State change: FLAG_WINDOW_TRANSPARENT
|
||||
if ((flags & FLAG_WINDOW_TRANSPARENT) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_TRANSPARENT) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_HIGHDPI
|
||||
if ((flags & FLAG_WINDOW_HIGHDPI) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_HIGHDPI) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_MOUSE_PASSTHROUGH
|
||||
if ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_MSAA_4X_HINT
|
||||
if ((flags & FLAG_MSAA_4X_HINT) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_MSAA_4X_HINT) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_INTERLACED_HINT
|
||||
if ((flags & FLAG_INTERLACED_HINT) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "SetWindowState(FLAG_INTERLACED_HINT) not available on target platform");
|
||||
}
|
||||
}
|
||||
|
||||
// Clear window configuration state flags
|
||||
void ClearWindowState(unsigned int flags)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState() not available on target platform");
|
||||
// Check previous state and requested state to apply required changes
|
||||
// NOTE: In most cases the functions already change the flags internally
|
||||
|
||||
// State change: FLAG_VSYNC_HINT
|
||||
if ((flags & FLAG_VSYNC_HINT) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_VSYNC_HINT) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_BORDERLESS_WINDOWED_MODE
|
||||
if (((CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0) && ((flags & FLAG_BORDERLESS_WINDOWED_MODE) > 0))
|
||||
{
|
||||
ToggleBorderlessWindowed(); // NOTE: Window state flag updated inside function
|
||||
}
|
||||
|
||||
// State change: FLAG_FULLSCREEN_MODE
|
||||
if (((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) && ((flags & FLAG_FULLSCREEN_MODE) > 0))
|
||||
{
|
||||
ToggleFullscreen(); // NOTE: Window state flag updated inside function
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_RESIZABLE
|
||||
if (((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) > 0) && ((flags & FLAG_WINDOW_RESIZABLE) > 0))
|
||||
{
|
||||
glfwSetWindowAttrib(platform.handle, GLFW_RESIZABLE, GLFW_FALSE);
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_RESIZABLE;
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_HIDDEN
|
||||
if ((flags & FLAG_WINDOW_HIDDEN) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_HIDDEN) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_MINIMIZED
|
||||
if ((flags & FLAG_WINDOW_MINIMIZED) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MINIMIZED) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_MAXIMIZED
|
||||
if ((flags & FLAG_WINDOW_MAXIMIZED) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MAXIMIZED) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_UNDECORATED
|
||||
if ((flags & FLAG_WINDOW_UNDECORATED) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_UNDECORATED) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_UNFOCUSED
|
||||
if ((flags & FLAG_WINDOW_UNFOCUSED) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_UNFOCUSED) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_TOPMOST
|
||||
if ((flags & FLAG_WINDOW_TOPMOST) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_TOPMOST) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_ALWAYS_RUN
|
||||
if ((flags & FLAG_WINDOW_ALWAYS_RUN) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_ALWAYS_RUN) not available on target platform");
|
||||
}
|
||||
|
||||
// The following states can not be changed after window creation
|
||||
// NOTE: Review for PLATFORM_WEB
|
||||
|
||||
// State change: FLAG_WINDOW_TRANSPARENT
|
||||
if ((flags & FLAG_WINDOW_TRANSPARENT) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_TRANSPARENT) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_HIGHDPI
|
||||
if ((flags & FLAG_WINDOW_HIGHDPI) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_HIGHDPI) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_WINDOW_MOUSE_PASSTHROUGH
|
||||
if ((flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_WINDOW_MOUSE_PASSTHROUGH) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_MSAA_4X_HINT
|
||||
if ((flags & FLAG_MSAA_4X_HINT) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_MSAA_4X_HINT) not available on target platform");
|
||||
}
|
||||
|
||||
// State change: FLAG_INTERLACED_HINT
|
||||
if ((flags & FLAG_INTERLACED_HINT) > 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "ClearWindowState(FLAG_INTERLACED_HINT) not available on target platform");
|
||||
}
|
||||
}
|
||||
|
||||
// Set icon for window
|
||||
|
|
@ -344,15 +608,19 @@ Vector2 GetMonitorPosition(int monitor)
|
|||
// Get selected monitor width (currently used by monitor)
|
||||
int GetMonitorWidth(int monitor)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetMonitorWidth() not implemented on target platform");
|
||||
return 0;
|
||||
// NOTE: Returned value is limited to the current monitor where the browser window is located
|
||||
int width = 0;
|
||||
width = EM_ASM_INT( { return screen.width; }, 0);
|
||||
return width;
|
||||
}
|
||||
|
||||
// Get selected monitor height (currently used by monitor)
|
||||
int GetMonitorHeight(int monitor)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetMonitorHeight() not implemented on target platform");
|
||||
return 0;
|
||||
// NOTE: Returned value is limited to the current monitor where the browser window is located
|
||||
int height = 0;
|
||||
height = EM_ASM_INT( { return screen.height; }, 0);
|
||||
return height;
|
||||
}
|
||||
|
||||
// Get selected monitor physical width in millimetres
|
||||
|
|
@ -386,8 +654,11 @@ const char *GetMonitorName(int monitor)
|
|||
// Get window position XY on monitor
|
||||
Vector2 GetWindowPosition(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetWindowPosition() not implemented on target platform");
|
||||
return (Vector2){ 0, 0 };
|
||||
// NOTE: Returned position is relative to the current monitor where the browser window is located
|
||||
Vector2 position = { 0, 0 };
|
||||
position.x = (float)EM_ASM_INT( { return window.screenX; }, 0);
|
||||
position.y = (float)EM_ASM_INT( { return window.screenY; }, 0);
|
||||
return position;
|
||||
}
|
||||
|
||||
// Get window scale DPI factor for current monitor
|
||||
|
|
@ -664,7 +935,7 @@ void PollInputEvents(void)
|
|||
|
||||
// TODO: This code does not seem to do anything??
|
||||
//if (CORE.Window.eventWaiting) glfwWaitEvents(); // Wait for in input events before continue (drawing is paused)
|
||||
//else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) --> WARNING: Where is key input reseted?
|
||||
//else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks) --> WARNING: Where is key input reset?
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -717,7 +988,12 @@ int InitPlatform(void)
|
|||
else glfwWindowHint(GLFW_FLOATING, GLFW_FALSE);
|
||||
|
||||
// NOTE: Some GLFW flags are not supported on HTML5
|
||||
// e.g.: GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_SCALE_TO_MONITOR, GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_MOUSE_PASSTHROUGH
|
||||
// e.g.: GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_COCOA_RETINA_FRAMEBUFFER, GLFW_MOUSE_PASSTHROUGH
|
||||
|
||||
// Scale content area based on the monitor content scale where window is placed on
|
||||
// NOTE: This feature requires emscripten 3.1.51
|
||||
//if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||
//else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
|
||||
|
||||
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
|
||||
{
|
||||
|
|
@ -775,6 +1051,9 @@ int InitPlatform(void)
|
|||
CORE.Window.display.width = CORE.Window.screen.width;
|
||||
CORE.Window.display.height = CORE.Window.screen.height;
|
||||
|
||||
// Init fullscreen toggle required var:
|
||||
platform.ourFullscreen = false;
|
||||
|
||||
if (CORE.Window.fullscreen)
|
||||
{
|
||||
// remember center for switchinging from fullscreen to window
|
||||
|
|
@ -908,7 +1187,7 @@ int InitPlatform(void)
|
|||
// Initialize input events callbacks
|
||||
//----------------------------------------------------------------------------
|
||||
// Setup callback functions for the DOM events
|
||||
emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback);
|
||||
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenFullscreenChangeCallback);
|
||||
|
||||
// WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review
|
||||
// Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas)
|
||||
|
|
@ -937,7 +1216,7 @@ int InitPlatform(void)
|
|||
emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback);
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Initialize timming system
|
||||
// Initialize timing system
|
||||
//----------------------------------------------------------------------------
|
||||
InitTimer();
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -1093,6 +1372,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
|
|||
// WARNING: GLFW could only return GLFW_PRESS (1) or GLFW_RELEASE (0) for now,
|
||||
// but future releases may add more actions (i.e. GLFW_REPEAT)
|
||||
CORE.Input.Mouse.currentButtonState[button] = action;
|
||||
CORE.Input.Touch.currentTouchState[button] = action;
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
|
||||
// Process mouse events as touches to be able to use mouse-gestures
|
||||
|
|
@ -1171,7 +1451,19 @@ static void CursorEnterCallback(GLFWwindow *window, int enter)
|
|||
// Register fullscreen change events
|
||||
static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData)
|
||||
{
|
||||
// TODO: Implement EmscriptenFullscreenChangeCallback()?
|
||||
// NOTE: 1. Reset the fullscreen flags if the user left fullscreen manually by pressing the Escape key
|
||||
// 2. Which is a necessary safeguard because that case will bypass the toggles CORE.Window.flags resets
|
||||
if (platform.ourFullscreen) platform.ourFullscreen = false;
|
||||
else
|
||||
{
|
||||
const bool wasFullscreen = EM_ASM_INT( { if (document.fullscreenElement) return 1; }, 0);
|
||||
if (!wasFullscreen)
|
||||
{
|
||||
CORE.Window.fullscreen = false;
|
||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||
CORE.Window.flags &= ~FLAG_BORDERLESS_WINDOWED_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
return 1; // The event was consumed by the callback handler
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,10 @@ typedef struct tagBITMAPINFOHEADER {
|
|||
#define MA_NO_WAV
|
||||
#define MA_NO_FLAC
|
||||
#define MA_NO_MP3
|
||||
#define MA_NO_RESOURCE_MANAGER
|
||||
#define MA_NO_NODE_GRAPH
|
||||
#define MA_NO_ENGINE
|
||||
#define MA_NO_GENERATION
|
||||
|
||||
// Threading model: Default: [0] COINIT_MULTITHREADED: COM calls objects on any thread (free threading)
|
||||
#define MA_COINIT_VALUE 2 // [2] COINIT_APARTMENTTHREADED: Each object has its own thread (apartment model)
|
||||
|
|
|
|||
21
src/raylib.h
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib v5.0 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
* raylib v5.1-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
*
|
||||
* FEATURES:
|
||||
* - NO external dependencies, all required libraries included with raylib
|
||||
|
|
@ -82,21 +82,26 @@
|
|||
#include <stdarg.h> // Required for: va_list - Only used by TraceLogCallback
|
||||
|
||||
#define RAYLIB_VERSION_MAJOR 5
|
||||
#define RAYLIB_VERSION_MINOR 0
|
||||
#define RAYLIB_VERSION_MINOR 1
|
||||
#define RAYLIB_VERSION_PATCH 0
|
||||
#define RAYLIB_VERSION "5.0"
|
||||
#define RAYLIB_VERSION "5.1-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
|
||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||
// NOTE: visibility("default") attribute makes symbols "visible" when compiled with -fvisibility=hidden
|
||||
#if defined(_WIN32)
|
||||
#if defined(BUILD_LIBTYPE_SHARED)
|
||||
#if defined(__TINYC__)
|
||||
#define __declspec(x) __attribute__((x))
|
||||
#endif
|
||||
#if defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
|
||||
#elif defined(USE_LIBTYPE_SHARED)
|
||||
#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
|
||||
#endif
|
||||
#else
|
||||
#if defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RLAPI __attribute__((visibility("default"))) // We are building as a Unix shared library (.so/.dylib)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef RLAPI
|
||||
|
|
@ -479,7 +484,6 @@ typedef struct VrDeviceInfo {
|
|||
int vResolution; // Vertical resolution in pixels
|
||||
float hScreenSize; // Horizontal size in meters
|
||||
float vScreenSize; // Vertical size in meters
|
||||
float vScreenCenter; // Screen center in meters
|
||||
float eyeToScreenDistance; // Distance between eye and display in meters
|
||||
float lensSeparationDistance; // Lens separation distance in meters
|
||||
float interpupillaryDistance; // IPD (distance between pupils) in meters
|
||||
|
|
@ -1329,6 +1333,7 @@ RLAPI void ImageAlphaClear(Image *image, Color color, float threshold);
|
|||
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
|
||||
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 ImageKernelConvolution(Image *image, float* kernel, int kernelSize); // Apply Custom Square image convolution kernel
|
||||
RLAPI void ImageResize(Image *image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm)
|
||||
RLAPI void 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
|
||||
|
|
@ -1475,6 +1480,7 @@ RLAPI const char *TextToUpper(const char *text); // Get upp
|
|||
RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string
|
||||
RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
|
||||
RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported)
|
||||
RLAPI float TextToFloat(const char *text); // Get float value from text (negative values not supported)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Basic 3d Shapes Drawing Functions (Module: models)
|
||||
|
|
@ -1530,9 +1536,10 @@ RLAPI void UpdateMeshBuffer(Mesh mesh, int index, const void *data, int dataSize
|
|||
RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU
|
||||
RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
|
||||
RLAPI void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms
|
||||
RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
|
||||
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
|
||||
RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents
|
||||
RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
|
||||
RLAPI bool ExportMeshAsCode(Mesh mesh, const char *fileName); // Export mesh as code file (.h) defining multiple arrays of vertex attributes
|
||||
|
||||
// Mesh generation functions
|
||||
RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@
|
|||
// Function specifiers definition
|
||||
#if defined(RAYMATH_IMPLEMENTATION)
|
||||
#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll).
|
||||
#define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll)
|
||||
#elif defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RMAPI __attribute__((visibility("default"))) // We are building raylib as a Unix shared library (.so/.dylib)
|
||||
#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
|
||||
#define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll)
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ void UpdateCamera(Camera *camera, int mode)
|
|||
|
||||
bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON));
|
||||
bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
||||
bool lockView = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
||||
bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
|
||||
bool rotateUp = false;
|
||||
|
||||
if (mode == CAMERA_ORBITAL)
|
||||
|
|
@ -471,8 +471,6 @@ void UpdateCamera(Camera *camera, int mode)
|
|||
if (IsKeyDown(KEY_E)) CameraRoll(camera, CAMERA_ROTATION_SPEED);
|
||||
|
||||
// Camera movement
|
||||
if (!IsGamepadAvailable(0))
|
||||
{
|
||||
// Camera pan (for CAMERA_FREE)
|
||||
if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
|
||||
{
|
||||
|
|
@ -494,8 +492,9 @@ void UpdateCamera(Camera *camera, int mode)
|
|||
if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
if (IsKeyDown(KEY_D)) CameraMoveRight(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
|
||||
}
|
||||
else
|
||||
|
||||
// Gamepad movement
|
||||
if (IsGamepadAvailable(0))
|
||||
{
|
||||
// Gamepad controller support
|
||||
CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
|
||||
|
|
|
|||
11
src/rcore.c
|
|
@ -1192,8 +1192,8 @@ VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device)
|
|||
// NOTE: Camera movement might seem more natural if we model the head.
|
||||
// Our axis of rotation is the base of our head, so we might want to add
|
||||
// some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions.
|
||||
config.viewOffset[0] = MatrixTranslate(-device.interpupillaryDistance*0.5f, 0.075f, 0.045f);
|
||||
config.viewOffset[1] = MatrixTranslate(device.interpupillaryDistance*0.5f, 0.075f, 0.045f);
|
||||
config.viewOffset[0] = MatrixTranslate(device.interpupillaryDistance*0.5f, 0.075f, 0.045f);
|
||||
config.viewOffset[1] = MatrixTranslate(-device.interpupillaryDistance*0.5f, 0.075f, 0.045f);
|
||||
|
||||
// Compute eyes Viewports
|
||||
/*
|
||||
|
|
@ -2623,8 +2623,9 @@ void PlayAutomationEvent(AutomationEvent event)
|
|||
{
|
||||
CORE.Input.Gamepad.axisState[event.params[0]][event.params[1]] = ((float)event.params[2]/32768.0f);
|
||||
} break;
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
case INPUT_GESTURE: GESTURES.current = event.params[0]; break; // param[0]: gesture (enum Gesture) -> rgestures.h: GESTURES.current
|
||||
|
||||
#endif
|
||||
// Window event
|
||||
case WINDOW_CLOSE: CORE.Window.shouldClose = true; break;
|
||||
case WINDOW_MAXIMIZE: MaximizeWindow(); break;
|
||||
|
|
@ -2632,11 +2633,13 @@ void PlayAutomationEvent(AutomationEvent event)
|
|||
case WINDOW_RESIZE: SetWindowSize(event.params[0], event.params[1]); break;
|
||||
|
||||
// Custom event
|
||||
#if defined(SUPPORT_SCREEN_CAPTURE)
|
||||
case ACTION_TAKE_SCREENSHOT:
|
||||
{
|
||||
TakeScreenshot(TextFormat("screenshot%03i.png", screenshotCounter));
|
||||
screenshotCounter++;
|
||||
} break;
|
||||
#endif
|
||||
case ACTION_SETTARGETFPS: SetTargetFPS(event.params[0]); break;
|
||||
default: break;
|
||||
}
|
||||
|
|
@ -3507,6 +3510,7 @@ static void RecordAutomationEvent(void)
|
|||
}
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||
// Gestures input currentEventList->events recording
|
||||
//-------------------------------------------------------------------------------------
|
||||
if (GESTURES.current != GESTURE_NONE)
|
||||
|
|
@ -3524,6 +3528,7 @@ static void RecordAutomationEvent(void)
|
|||
if (currentEventList->count == currentEventList->capacity) return; // Security check
|
||||
}
|
||||
//-------------------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
// Window events recording
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
|
|
|||
60
src/rlgl.h
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* rlgl v4.5 - A multi-OpenGL abstraction layer with an immediate-mode style API
|
||||
* rlgl v5.0 - A multi-OpenGL abstraction layer with an immediate-mode style API
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0)
|
||||
|
|
@ -109,16 +109,18 @@
|
|||
|
||||
#define RLGL_VERSION "4.5"
|
||||
|
||||
// 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
|
||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||
#if defined(_WIN32)
|
||||
#if defined(BUILD_LIBTYPE_SHARED)
|
||||
// NOTE: visibility(default) attribute makes symbols "visible" when compiled with -fvisibility=hidden
|
||||
#if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
|
||||
#elif defined(USE_LIBTYPE_SHARED)
|
||||
#elif defined(BUILD_LIBTYPE_SHARED)
|
||||
#define RLAPI __attribute__((visibility("default"))) // We are building he library as a Unix shared library (.so/.dylib)
|
||||
#elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED)
|
||||
#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// Function specifiers definition
|
||||
#ifndef RLAPI
|
||||
#define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
|
||||
|
|
@ -592,10 +594,10 @@ RLAPI bool rlEnableVertexArray(unsigned int vaoId); // Enable vertex array (
|
|||
RLAPI void rlDisableVertexArray(void); // Disable vertex array (VAO, if supported)
|
||||
RLAPI void rlEnableVertexBuffer(unsigned int id); // Enable vertex buffer (VBO)
|
||||
RLAPI void rlDisableVertexBuffer(void); // Disable vertex buffer (VBO)
|
||||
RLAPI void rlEnableVertexBufferElement(unsigned int id);// Enable vertex buffer element (VBO element)
|
||||
RLAPI void rlEnableVertexBufferElement(unsigned int id); // Enable vertex buffer element (VBO element)
|
||||
RLAPI void rlDisableVertexBufferElement(void); // Disable vertex buffer element (VBO element)
|
||||
RLAPI void rlEnableVertexAttribute(unsigned int index); // Enable vertex attribute index
|
||||
RLAPI void rlDisableVertexAttribute(unsigned int index);// Disable vertex attribute index
|
||||
RLAPI void rlDisableVertexAttribute(unsigned int index); // Disable vertex attribute index
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
RLAPI void rlEnableStatePointer(int vertexAttribType, void *buffer); // Enable attribute state pointer
|
||||
RLAPI void rlDisableStatePointer(int vertexAttribType); // Disable attribute state pointer
|
||||
|
|
@ -684,25 +686,25 @@ RLAPI void rlSetTexture(unsigned int id); // Set current texture f
|
|||
|
||||
// Vertex buffers management
|
||||
RLAPI unsigned int rlLoadVertexArray(void); // Load vertex array (vao) if supported
|
||||
RLAPI unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic); // Load a vertex buffer attribute
|
||||
RLAPI unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic); // Load a new attributes element buffer
|
||||
RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dataSize, int offset); // Update GPU buffer with new data
|
||||
RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset); // Update vertex buffer elements with new data
|
||||
RLAPI void rlUnloadVertexArray(unsigned int vaoId);
|
||||
RLAPI void rlUnloadVertexBuffer(unsigned int vboId);
|
||||
RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer);
|
||||
RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor);
|
||||
RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value
|
||||
RLAPI void rlDrawVertexArray(int offset, int count);
|
||||
RLAPI void rlDrawVertexArrayElements(int offset, int count, const void *buffer);
|
||||
RLAPI void rlDrawVertexArrayInstanced(int offset, int count, int instances);
|
||||
RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances);
|
||||
RLAPI unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic); // Load a vertex buffer object
|
||||
RLAPI unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic); // Load vertex buffer elements object
|
||||
RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dataSize, int offset); // Update vertex buffer object data on GPU buffer
|
||||
RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset); // Update vertex buffer elements data on GPU buffer
|
||||
RLAPI void rlUnloadVertexArray(unsigned int vaoId); // Unload vertex array (vao)
|
||||
RLAPI void rlUnloadVertexBuffer(unsigned int vboId); // Unload vertex buffer object
|
||||
RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer); // Set vertex attribute data configuration
|
||||
RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor); // Set vertex attribute data divisor
|
||||
RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value, when attribute to provided
|
||||
RLAPI void rlDrawVertexArray(int offset, int count); // Draw vertex array (currently active vao)
|
||||
RLAPI void rlDrawVertexArrayElements(int offset, int count, const void *buffer); // Draw vertex array elements
|
||||
RLAPI void rlDrawVertexArrayInstanced(int offset, int count, int instances); // Draw vertex array (currently active vao) with instancing
|
||||
RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances); // Draw vertex array elements with instancing
|
||||
|
||||
// Textures management
|
||||
RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU
|
||||
RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture data
|
||||
RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo)
|
||||
RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap
|
||||
RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update GPU texture with new data
|
||||
RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap data
|
||||
RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update texture with new data on GPU
|
||||
RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats
|
||||
RLAPI const char *rlGetPixelFormatName(unsigned int format); // Get name string for pixel format
|
||||
RLAPI void rlUnloadTexture(unsigned int id); // Unload texture from GPU memory
|
||||
|
|
@ -773,6 +775,12 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
|||
|
||||
#if defined(RLGL_IMPLEMENTATION)
|
||||
|
||||
// Expose OpenGL functions from glad in raylib
|
||||
#if defined(BUILD_LIBTYPE_SHARED)
|
||||
#define GLAD_API_CALL_EXPORT
|
||||
#define GLAD_API_CALL_EXPORT_BUILD
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
|
||||
|
|
@ -3787,6 +3795,10 @@ unsigned int rlLoadVertexArray(void)
|
|||
void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: Data type could be: GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT
|
||||
// Additional types (depends on OpenGL version or extensions):
|
||||
// - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED,
|
||||
// - GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV
|
||||
glVertexAttribPointer(index, compSize, type, normalized, stride, pointer);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
125
src/rmodels.c
|
|
@ -1850,6 +1850,104 @@ bool ExportMesh(Mesh mesh, const char *fileName)
|
|||
return success;
|
||||
}
|
||||
|
||||
// Export mesh as code file (.h) defining multiple arrays of vertex attributes
|
||||
bool ExportMeshAsCode(Mesh mesh, const char *fileName)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
#ifndef TEXT_BYTES_PER_LINE
|
||||
#define TEXT_BYTES_PER_LINE 20
|
||||
#endif
|
||||
|
||||
// NOTE: Text data buffer size is fixed to 64MB
|
||||
char *txtData = (char *)RL_CALLOC(64*1024*1024, sizeof(char)); // 64 MB
|
||||
|
||||
int byteCount = 0;
|
||||
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n");
|
||||
byteCount += sprintf(txtData + byteCount, "// //\n");
|
||||
byteCount += sprintf(txtData + byteCount, "// MeshAsCode exporter v1.0 - Mesh vertex data exported as arrays //\n");
|
||||
byteCount += sprintf(txtData + byteCount, "// //\n");
|
||||
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
|
||||
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
|
||||
byteCount += sprintf(txtData + byteCount, "// //\n");
|
||||
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2023 Ramon Santamaria (@raysan5) //\n");
|
||||
byteCount += sprintf(txtData + byteCount, "// //\n");
|
||||
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n");
|
||||
|
||||
// Get file name from path and convert variable name to uppercase
|
||||
char varFileName[256] = { 0 };
|
||||
strcpy(varFileName, GetFileNameWithoutExt(fileName));
|
||||
for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; }
|
||||
|
||||
// Add image information
|
||||
byteCount += sprintf(txtData + byteCount, "// Mesh basic information\n");
|
||||
byteCount += sprintf(txtData + byteCount, "#define %s_VERTEX_COUNT %i\n", varFileName, mesh.vertexCount);
|
||||
byteCount += sprintf(txtData + byteCount, "#define %s_TRIANGLE_COUNT %i\n\n", varFileName, mesh.triangleCount);
|
||||
|
||||
// Define vertex attributes data as separate arrays
|
||||
//-----------------------------------------------------------------------------------------
|
||||
if (mesh.vertices != NULL) // Vertex position (XYZ - 3 components per vertex - float)
|
||||
{
|
||||
byteCount += sprintf(txtData + byteCount, "static float %s_VERTEX_DATA[%i] = { ", varFileName, mesh.vertexCount*3);
|
||||
for (int i = 0; i < mesh.vertexCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.vertices[i]);
|
||||
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.vertices[mesh.vertexCount*3 - 1]);
|
||||
}
|
||||
|
||||
if (mesh.texcoords != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float)
|
||||
{
|
||||
byteCount += sprintf(txtData + byteCount, "static float %s_TEXCOORD_DATA[%i] = { ", varFileName, mesh.vertexCount*2);
|
||||
for (int i = 0; i < mesh.vertexCount*2 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.texcoords[i]);
|
||||
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.texcoords[mesh.vertexCount*2 - 1]);
|
||||
}
|
||||
|
||||
if (mesh.texcoords2 != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float)
|
||||
{
|
||||
byteCount += sprintf(txtData + byteCount, "static float %s_TEXCOORD2_DATA[%i] = { ", varFileName, mesh.vertexCount*2);
|
||||
for (int i = 0; i < mesh.vertexCount*2 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.texcoords2[i]);
|
||||
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.texcoords2[mesh.vertexCount*2 - 1]);
|
||||
}
|
||||
|
||||
if (mesh.normals != NULL) // Vertex normals (XYZ - 3 components per vertex - float)
|
||||
{
|
||||
byteCount += sprintf(txtData + byteCount, "static float %s_NORMAL_DATA[%i] = { ", varFileName, mesh.vertexCount*3);
|
||||
for (int i = 0; i < mesh.vertexCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.normals[i]);
|
||||
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.normals[mesh.vertexCount*3 - 1]);
|
||||
}
|
||||
|
||||
if (mesh.tangents != NULL) // Vertex tangents (XYZW - 4 components per vertex - float)
|
||||
{
|
||||
byteCount += sprintf(txtData + byteCount, "static float %s_TANGENT_DATA[%i] = { ", varFileName, mesh.vertexCount*4);
|
||||
for (int i = 0; i < mesh.vertexCount*4 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.tangents[i]);
|
||||
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.tangents[mesh.vertexCount*4 - 1]);
|
||||
}
|
||||
|
||||
if (mesh.colors != NULL) // Vertex colors (RGBA - 4 components per vertex - unsigned char)
|
||||
{
|
||||
byteCount += sprintf(txtData + byteCount, "static unsigned char %s_COLOR_DATA[%i] = { ", varFileName, mesh.vertexCount*4);
|
||||
for (int i = 0; i < mesh.vertexCount*4 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), mesh.colors[i]);
|
||||
byteCount += sprintf(txtData + byteCount, "0x%x };\n\n", mesh.colors[mesh.vertexCount*4 - 1]);
|
||||
}
|
||||
|
||||
if (mesh.indices != NULL) // Vertex indices (3 index per triangle - unsigned short)
|
||||
{
|
||||
byteCount += sprintf(txtData + byteCount, "static unsigned short %s_INDEX_DATA[%i] = { ", varFileName, mesh.triangleCount*3);
|
||||
for (int i = 0; i < mesh.triangleCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%i,\n" : "%i, "), mesh.indices[i]);
|
||||
byteCount += sprintf(txtData + byteCount, "%i };\n", mesh.indices[mesh.triangleCount*3 - 1]);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------
|
||||
|
||||
// NOTE: Text data size exported is determined by '\0' (NULL) character
|
||||
success = SaveFileText(fileName, txtData);
|
||||
|
||||
RL_FREE(txtData);
|
||||
|
||||
//if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image as code exported successfully", fileName);
|
||||
//else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image as code", fileName);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
#if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)
|
||||
// Process obj materials
|
||||
static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, int materialCount)
|
||||
|
|
@ -5155,16 +5253,29 @@ static Model LoadGLTF(const char *fileName)
|
|||
|
||||
if ((attribute->component_type == cgltf_component_type_r_8u) && (attribute->type == cgltf_type_vec4))
|
||||
{
|
||||
// Init raylib mesh bone ids to copy glTF attribute data
|
||||
// Handle 8-bit unsigned byte, vec4 format
|
||||
model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned char));
|
||||
|
||||
// Load 4 components of unsigned char data type into mesh.boneIds
|
||||
// for cgltf_attribute_type_joints we have:
|
||||
// - data.meshes[0] (256 vertices)
|
||||
// - 256 values, provided as cgltf_type_vec4 of bytes (4 byte per joint, stride 4)
|
||||
LOAD_ATTRIBUTE(attribute, 4, unsigned char, model.meshes[meshIndex].boneIds)
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported, use vec4 u8", fileName);
|
||||
else if ((attribute->component_type == cgltf_component_type_r_16u) && (attribute->type == cgltf_type_vec2))
|
||||
{
|
||||
// Handle 16-bit unsigned short, vec2 format
|
||||
model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*2, sizeof(unsigned short));
|
||||
LOAD_ATTRIBUTE(attribute, 2, unsigned short, model.meshes[meshIndex].boneIds)
|
||||
}
|
||||
else if ((attribute->component_type == cgltf_component_type_r_32u) && (attribute->type == cgltf_type_vec4))
|
||||
{
|
||||
// Handle 32-bit unsigned int, vec4 format
|
||||
model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(unsigned int));
|
||||
LOAD_ATTRIBUTE(attribute, 4, unsigned int, model.meshes[meshIndex].boneIds)
|
||||
}
|
||||
else if ((attribute->component_type == cgltf_component_type_r_32f) && (attribute->type == cgltf_type_vec2))
|
||||
{
|
||||
// Handle 32-bit float, vec2 format
|
||||
model.meshes[meshIndex].boneIds = RL_CALLOC(model.meshes[meshIndex].vertexCount*2, sizeof(float));
|
||||
LOAD_ATTRIBUTE(attribute, 2, float, model.meshes[meshIndex].boneIds)
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "MODEL: [%s] Joint attribute data format not supported", fileName);
|
||||
}
|
||||
else if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_weights) // WEIGHTS_n (vec4 / u8, u16, f32)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1546,6 +1546,92 @@ void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, fl
|
|||
// Draw spline: linear, minimum 2 points
|
||||
void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color)
|
||||
{
|
||||
if (pointCount < 2) return;
|
||||
|
||||
#if defined(SUPPORT_SPLINE_MITERS)
|
||||
Vector2 prevNormal = (Vector2){-(points[1].y - points[0].y), (points[1].x - points[0].x)};
|
||||
float prevLength = sqrtf(prevNormal.x*prevNormal.x + prevNormal.y*prevNormal.y);
|
||||
|
||||
if (prevLength > 0.0f)
|
||||
{
|
||||
prevNormal.x /= prevLength;
|
||||
prevNormal.y /= prevLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevNormal.x = 0.0f;
|
||||
prevNormal.y = 0.0f;
|
||||
}
|
||||
|
||||
Vector2 prevRadius = { 0.5f*thick*prevNormal.x, 0.5f*thick*prevNormal.y };
|
||||
|
||||
for (int i = 0; i < pointCount - 1; i++)
|
||||
{
|
||||
Vector2 normal = { 0 };
|
||||
|
||||
if (i < pointCount - 2)
|
||||
{
|
||||
normal = (Vector2){-(points[i + 2].y - points[i + 1].y), (points[i + 2].x - points[i + 1].x)};
|
||||
float normalLength = sqrtf(normal.x*normal.x + normal.y*normal.y);
|
||||
|
||||
if (normalLength > 0.0f)
|
||||
{
|
||||
normal.x /= normalLength;
|
||||
normal.y /= normalLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
normal.x = 0.0f;
|
||||
normal.y = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
normal = prevNormal;
|
||||
}
|
||||
|
||||
Vector2 radius = { prevNormal.x + normal.x, prevNormal.y + normal.y };
|
||||
float radiusLength = sqrtf(radius.x*radius.x + radius.y*radius.y);
|
||||
|
||||
if (radiusLength > 0.0f)
|
||||
{
|
||||
radius.x /= radiusLength;
|
||||
radius.y /= radiusLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
radius.x = 0.0f;
|
||||
radius.y = 0.0f;
|
||||
}
|
||||
|
||||
float cosTheta = radius.x*normal.x + radius.y*normal.y;
|
||||
|
||||
if (cosTheta != 0.0f)
|
||||
{
|
||||
radius.x *= (thick*0.5f/cosTheta);
|
||||
radius.y *= (thick*0.5f/cosTheta);
|
||||
}
|
||||
else
|
||||
{
|
||||
radius.x = 0.0f;
|
||||
radius.y = 0.0f;
|
||||
}
|
||||
|
||||
Vector2 strip[4] = {
|
||||
{ points[i].x - prevRadius.x, points[i].y - prevRadius.y },
|
||||
{ points[i].x + prevRadius.x, points[i].y + prevRadius.y },
|
||||
{ points[i + 1].x - radius.x, points[i + 1].y - radius.y },
|
||||
{ points[i + 1].x + radius.x, points[i + 1].y + radius.y }
|
||||
};
|
||||
|
||||
DrawTriangleStrip(strip, 4, color);
|
||||
|
||||
prevRadius = radius;
|
||||
prevNormal = normal;
|
||||
}
|
||||
|
||||
#else // !SUPPORT_SPLINE_MITTERS
|
||||
|
||||
Vector2 delta = { 0 };
|
||||
float length = 0.0f;
|
||||
float scale = 0.0f;
|
||||
|
|
@ -1567,8 +1653,10 @@ void DrawSplineLinear(Vector2 *points, int pointCount, float thick, Color color)
|
|||
|
||||
DrawTriangleStrip(strip, 4, color);
|
||||
}
|
||||
#if defined(SUPPORT_SPLINE_SEGMENT_CAPS)
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_SPLINE_SEGMENT_CAPS)
|
||||
// TODO: Add spline segment rounded caps at the begin/end of the spline
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -2132,11 +2220,11 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
|
|||
{
|
||||
bool collision = false;
|
||||
|
||||
int recCenterX = (int)(rec.x + rec.width/2.0f);
|
||||
int recCenterY = (int)(rec.y + rec.height/2.0f);
|
||||
float recCenterX = rec.x + rec.width/2.0f;
|
||||
float recCenterY = rec.y + rec.height/2.0f;
|
||||
|
||||
float dx = fabsf(center.x - (float)recCenterX);
|
||||
float dy = fabsf(center.y - (float)recCenterY);
|
||||
float dx = fabsf(center.x - recCenterX);
|
||||
float dy = fabsf(center.y - recCenterY);
|
||||
|
||||
if (dx > (rec.width/2.0f + radius)) { return false; }
|
||||
if (dy > (rec.height/2.0f + radius)) { return false; }
|
||||
|
|
|
|||
158
src/rtext.c
|
|
@ -604,7 +604,6 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
|||
|
||||
// Fill fontChars in case not provided externally
|
||||
// NOTE: By default we fill glyphCount consecutively, starting at 32 (Space)
|
||||
|
||||
if (codepoints == NULL)
|
||||
{
|
||||
codepoints = (int *)RL_MALLOC(codepointCount*sizeof(int));
|
||||
|
|
@ -612,7 +611,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
|||
genFontChars = true;
|
||||
}
|
||||
|
||||
chars = (GlyphInfo *)RL_MALLOC(codepointCount*sizeof(GlyphInfo));
|
||||
chars = (GlyphInfo *)RL_CALLOC(codepointCount, sizeof(GlyphInfo));
|
||||
|
||||
// NOTE: Using simple packaging, one char after another
|
||||
for (int i = 0; i < codepointCount; i++)
|
||||
|
|
@ -626,10 +625,22 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
|||
// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
|
||||
// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
|
||||
|
||||
if (type != FONT_SDF) chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
|
||||
else if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, FONT_SDF_CHAR_PADDING, FONT_SDF_ON_EDGE_VALUE, FONT_SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
|
||||
else chars[i].image.data = NULL;
|
||||
// Check if a glyph is available in the font
|
||||
// WARNING: if (index == 0), glyph not found, it could fallback to default .notdef glyph (if defined in font)
|
||||
int index = stbtt_FindGlyphIndex(&fontInfo, ch);
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FONT_DEFAULT:
|
||||
case FONT_BITMAP: chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); break;
|
||||
case FONT_SDF: if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, FONT_SDF_CHAR_PADDING, FONT_SDF_ON_EDGE_VALUE, FONT_SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (chars[i].image.data != NULL) // Glyph data has been found in the font
|
||||
{
|
||||
stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
|
||||
chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor);
|
||||
|
||||
|
|
@ -640,10 +651,15 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
|||
chars[i].image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
|
||||
|
||||
chars[i].offsetY += (int)((float)ascent*scaleFactor);
|
||||
}
|
||||
|
||||
// NOTE: We create an empty image for space character, it could be further required for atlas packing
|
||||
// NOTE: We create an empty image for space character,
|
||||
// it could be further required for atlas packing
|
||||
if (ch == 32)
|
||||
{
|
||||
stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
|
||||
chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor);
|
||||
|
||||
Image imSpace = {
|
||||
.data = RL_CALLOC(chars[i].advanceX*fontSize, 2),
|
||||
.width = chars[i].advanceX,
|
||||
|
|
@ -665,15 +681,11 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
|
|||
else ((unsigned char *)chars[i].image.data)[p] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// Get bounding box for character (maybe offset to account for chars that dip above or below the line)
|
||||
/*
|
||||
int chX1, chY1, chX2, chY2;
|
||||
stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2);
|
||||
|
||||
TRACELOGD("FONT: Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1);
|
||||
TRACELOGD("FONT: Character offsetY: %i", (int)((float)ascent*scaleFactor) + chY1);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Use some fallback glyph for codepoints not found in the font
|
||||
}
|
||||
}
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "FONT: Failed to process TTF font data");
|
||||
|
|
@ -1409,6 +1421,28 @@ int TextToInteger(const char *text)
|
|||
return value*sign;
|
||||
}
|
||||
|
||||
float TextToFloat(const char *text)
|
||||
{
|
||||
float value = 0.0f;
|
||||
float sign = 1.0f;
|
||||
|
||||
if ((text[0] == '+') || (text[0] == '-'))
|
||||
{
|
||||
if (text[0] == '-') sign = -1;
|
||||
text++;
|
||||
}
|
||||
int i = 0;
|
||||
for (; ((text[i] >= '0') && (text[i] <= '9')); ++i) value = value*10.0f + (float)(text[i] - '0');
|
||||
if (text[i++] != '.') return value*sign;
|
||||
float divisor = 10.0f;
|
||||
for (; ((text[i] >= '0') && (text[i] <= '9')); ++i)
|
||||
{
|
||||
value += ((float)(text[i] - '0'))/divisor;
|
||||
divisor = divisor*10.0f;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_TEXT_MANIPULATION)
|
||||
// Copy one string to another, returns bytes copied
|
||||
int TextCopy(char *dst, const char *src)
|
||||
|
|
@ -2018,6 +2052,7 @@ static int GetLine(const char *origin, char *buffer, int maxLength)
|
|||
static Font LoadBMFont(const char *fileName)
|
||||
{
|
||||
#define MAX_BUFFER_SIZE 256
|
||||
#define MAX_FONT_IMAGE_PAGES 8
|
||||
|
||||
Font font = { 0 };
|
||||
|
||||
|
|
@ -2029,7 +2064,8 @@ static Font LoadBMFont(const char *fileName)
|
|||
|
||||
int imWidth = 0;
|
||||
int imHeight = 0;
|
||||
char imFileName[129] = { 0 };
|
||||
int pageCount = 1;
|
||||
char imFileName[MAX_FONT_IMAGE_PAGES][129] = { 0 };
|
||||
|
||||
int base = 0; // Useless data
|
||||
int readBytes = 0; // Data bytes read
|
||||
|
|
@ -2048,17 +2084,26 @@ static Font LoadBMFont(const char *fileName)
|
|||
// Read line data
|
||||
readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE);
|
||||
searchPoint = strstr(buffer, "lineHeight");
|
||||
readVars = sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i", &fontSize, &base, &imWidth, &imHeight);
|
||||
readVars = sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i pages=%i", &fontSize, &base, &imWidth, &imHeight, &pageCount);
|
||||
fileTextPtr += (readBytes + 1);
|
||||
|
||||
if (readVars < 4) { UnloadFileText(fileText); return font; } // Some data not available, file malformed
|
||||
|
||||
if (pageCount > MAX_FONT_IMAGE_PAGES)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "FONT: [%s] Font defines more pages than supported: %i/%i", fileName, pageCount, MAX_FONT_IMAGE_PAGES);
|
||||
pageCount = MAX_FONT_IMAGE_PAGES;
|
||||
}
|
||||
|
||||
for (int i = 0; i < pageCount; i++)
|
||||
{
|
||||
readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE);
|
||||
searchPoint = strstr(buffer, "file");
|
||||
readVars = sscanf(searchPoint, "file=\"%128[^\"]\"", imFileName);
|
||||
readVars = sscanf(searchPoint, "file=\"%128[^\"]\"", imFileName[i]);
|
||||
fileTextPtr += (readBytes + 1);
|
||||
|
||||
if (readVars < 1) { UnloadFileText(fileText); return font; } // No fileName read
|
||||
}
|
||||
|
||||
readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE);
|
||||
searchPoint = strstr(buffer, "count");
|
||||
|
|
@ -2067,50 +2112,56 @@ static Font LoadBMFont(const char *fileName)
|
|||
|
||||
if (readVars < 1) { UnloadFileText(fileText); return font; } // No glyphCount read
|
||||
|
||||
// Compose correct path using route of .fnt file (fileName) and imFileName
|
||||
char *imPath = NULL;
|
||||
char *lastSlash = NULL;
|
||||
// Load all required images for further compose
|
||||
Image *imFonts = (Image *)RL_CALLOC(pageCount, sizeof(Image)); // Font atlases, multiple images
|
||||
|
||||
lastSlash = strrchr(fileName, '/');
|
||||
if (lastSlash == NULL) lastSlash = strrchr(fileName, '\\');
|
||||
|
||||
if (lastSlash != NULL)
|
||||
for (int i = 0; i < pageCount; i++)
|
||||
{
|
||||
// NOTE: We need some extra space to avoid memory corruption on next allocations!
|
||||
imPath = (char *)RL_CALLOC(TextLength(fileName) - TextLength(lastSlash) + TextLength(imFileName) + 4, 1);
|
||||
memcpy(imPath, fileName, TextLength(fileName) - TextLength(lastSlash) + 1);
|
||||
memcpy(imPath + TextLength(fileName) - TextLength(lastSlash) + 1, imFileName, TextLength(imFileName));
|
||||
}
|
||||
else imPath = imFileName;
|
||||
imFonts[i] = LoadImage(TextFormat("%s/%s", GetDirectoryPath(fileName), imFileName[i]));
|
||||
|
||||
TRACELOGD(" > Image loading path: %s", imPath);
|
||||
|
||||
Image imFont = LoadImage(imPath);
|
||||
|
||||
if (imFont.format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE)
|
||||
if (imFonts[i].format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE)
|
||||
{
|
||||
// Convert image to GRAYSCALE + ALPHA, using the mask as the alpha channel
|
||||
Image imFontAlpha = {
|
||||
.data = RL_CALLOC(imFont.width*imFont.height, 2),
|
||||
.width = imFont.width,
|
||||
.height = imFont.height,
|
||||
.data = RL_CALLOC(imFonts[i].width*imFonts[i].height, 2),
|
||||
.width = imFonts[i].width,
|
||||
.height = imFonts[i].height,
|
||||
.mipmaps = 1,
|
||||
.format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA
|
||||
};
|
||||
|
||||
for (int p = 0, i = 0; p < (imFont.width*imFont.height*2); p += 2, i++)
|
||||
for (int p = 0, pi = 0; p < (imFonts[i].width*imFonts[i].height*2); p += 2, pi++)
|
||||
{
|
||||
((unsigned char *)(imFontAlpha.data))[p] = 0xff;
|
||||
((unsigned char *)(imFontAlpha.data))[p + 1] = ((unsigned char *)imFont.data)[i];
|
||||
((unsigned char *)(imFontAlpha.data))[p + 1] = ((unsigned char *)imFonts[i].data)[pi];
|
||||
}
|
||||
|
||||
UnloadImage(imFont);
|
||||
imFont = imFontAlpha;
|
||||
UnloadImage(imFonts[i]);
|
||||
imFonts[i] = imFontAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
font.texture = LoadTextureFromImage(imFont);
|
||||
Image fullFont = imFonts[0];
|
||||
for (int i = 1; i < pageCount; i++) UnloadImage(imFonts[i]);
|
||||
|
||||
if (lastSlash != NULL) RL_FREE(imPath);
|
||||
// If multiple atlas, then merge atlas
|
||||
// NOTE: WARNING: This process could be really slow!
|
||||
if (pageCount > 1)
|
||||
{
|
||||
// Resize font atlas to draw additional images
|
||||
ImageResizeCanvas(&fullFont, imWidth, imHeight*pageCount, 0, 0, BLACK);
|
||||
|
||||
for (int i = 1; i < pageCount; i++)
|
||||
{
|
||||
Rectangle srcRec = { 0.0f, 0.0f, (float)imWidth, (float)imHeight };
|
||||
Rectangle destRec = { 0.0f, (float)imHeight*(float)i, (float)imWidth, (float)imHeight };
|
||||
ImageDraw(&fullFont, imFonts[i], srcRec, destRec, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
RL_FREE(imFonts);
|
||||
|
||||
font.texture = LoadTextureFromImage(fullFont);
|
||||
|
||||
// Fill font characters info data
|
||||
font.baseSize = fontSize;
|
||||
|
|
@ -2119,19 +2170,19 @@ static Font LoadBMFont(const char *fileName)
|
|||
font.glyphs = (GlyphInfo *)RL_MALLOC(glyphCount*sizeof(GlyphInfo));
|
||||
font.recs = (Rectangle *)RL_MALLOC(glyphCount*sizeof(Rectangle));
|
||||
|
||||
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;
|
||||
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX, pageID;
|
||||
|
||||
for (int i = 0; i < glyphCount; i++)
|
||||
{
|
||||
readBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE);
|
||||
readVars = sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i",
|
||||
&charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX);
|
||||
readVars = sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i page=%i",
|
||||
&charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX, &pageID);
|
||||
fileTextPtr += (readBytes + 1);
|
||||
|
||||
if (readVars == 8) // Make sure all char data has been properly read
|
||||
if (readVars == 9) // Make sure all char data has been properly read
|
||||
{
|
||||
// Get character rectangle in the font atlas texture
|
||||
font.recs[i] = (Rectangle){ (float)charX, (float)charY, (float)charWidth, (float)charHeight };
|
||||
font.recs[i] = (Rectangle){ (float)charX, (float)charY + (float)imHeight*pageID, (float)charWidth, (float)charHeight };
|
||||
|
||||
// Save data properly in sprite font
|
||||
font.glyphs[i].value = charId;
|
||||
|
|
@ -2139,13 +2190,13 @@ static Font LoadBMFont(const char *fileName)
|
|||
font.glyphs[i].offsetY = charOffsetY;
|
||||
font.glyphs[i].advanceX = charAdvanceX;
|
||||
|
||||
// Fill character image data from imFont data
|
||||
font.glyphs[i].image = ImageFromImage(imFont, font.recs[i]);
|
||||
// Fill character image data from full font data
|
||||
font.glyphs[i].image = ImageFromImage(fullFont, font.recs[i]);
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "FONT: [%s] Some characters data not correctly provided", fileName);
|
||||
}
|
||||
|
||||
UnloadImage(imFont);
|
||||
UnloadImage(fullFont);
|
||||
UnloadFileText(fileText);
|
||||
|
||||
if (font.texture.id == 0)
|
||||
|
|
@ -2158,6 +2209,7 @@ static Font LoadBMFont(const char *fileName)
|
|||
|
||||
return font;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SUPPORT_MODULE_RTEXT
|
||||
|
|
|
|||
186
src/rtextures.c
|
|
@ -1959,9 +1959,9 @@ void ImageBlurGaussian(Image *image, int blurSize) {
|
|||
float avgG = 0.0f;
|
||||
float avgB = 0.0f;
|
||||
float avgAlpha = 0.0f;
|
||||
int convolutionSize = blurSize+1;
|
||||
int convolutionSize = blurSize;
|
||||
|
||||
for (int i = 0; i < blurSize+1; i++)
|
||||
for (int i = 0; i < blurSize; i++)
|
||||
{
|
||||
avgR += pixelsCopy1[row*image->width + i].x;
|
||||
avgG += pixelsCopy1[row*image->width + i].y;
|
||||
|
|
@ -1969,19 +1969,14 @@ void ImageBlurGaussian(Image *image, int blurSize) {
|
|||
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++)
|
||||
for (int x = 0; x < image->width; x++)
|
||||
{
|
||||
if (x-blurSize >= 0)
|
||||
if (x-blurSize-1 >= 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;
|
||||
avgR -= pixelsCopy1[row*image->width + x-blurSize-1].x;
|
||||
avgG -= pixelsCopy1[row*image->width + x-blurSize-1].y;
|
||||
avgB -= pixelsCopy1[row*image->width + x-blurSize-1].z;
|
||||
avgAlpha -= pixelsCopy1[row*image->width + x-blurSize-1].w;
|
||||
convolutionSize--;
|
||||
}
|
||||
|
||||
|
|
@ -2008,9 +2003,9 @@ void ImageBlurGaussian(Image *image, int blurSize) {
|
|||
float avgG = 0.0f;
|
||||
float avgB = 0.0f;
|
||||
float avgAlpha = 0.0f;
|
||||
int convolutionSize = blurSize+1;
|
||||
int convolutionSize = blurSize;
|
||||
|
||||
for (int i = 0; i < blurSize+1; i++)
|
||||
for (int i = 0; i < blurSize; i++)
|
||||
{
|
||||
avgR += pixelsCopy2[i*image->width + col].x;
|
||||
avgG += pixelsCopy2[i*image->width + col].y;
|
||||
|
|
@ -2018,19 +2013,14 @@ void ImageBlurGaussian(Image *image, int blurSize) {
|
|||
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++)
|
||||
for (int y = 0; y < image->height; y++)
|
||||
{
|
||||
if (y-blurSize >= 0)
|
||||
if (y-blurSize-1 >= 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;
|
||||
avgR -= pixelsCopy2[(y-blurSize-1)*image->width + col].x;
|
||||
avgG -= pixelsCopy2[(y-blurSize-1)*image->width + col].y;
|
||||
avgB -= pixelsCopy2[(y-blurSize-1)*image->width + col].z;
|
||||
avgAlpha -= pixelsCopy2[(y-blurSize-1)*image->width + col].w;
|
||||
convolutionSize--;
|
||||
}
|
||||
if (y+blurSize < image->height)
|
||||
|
|
@ -2082,6 +2072,148 @@ void ImageBlurGaussian(Image *image, int blurSize) {
|
|||
ImageFormat(image, format);
|
||||
}
|
||||
|
||||
// The kernel matrix is assumed to be square. Only supply the width of the kernel.
|
||||
void ImageKernelConvolution(Image *image, float* kernel, int kernelSize){
|
||||
|
||||
if ((image->data == NULL) || (image->width == 0) || (image->height == 0) || kernel == NULL) return;
|
||||
|
||||
int kernelWidth = (int)sqrtf((float)kernelSize);
|
||||
if (kernelWidth*kernelWidth != kernelSize)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "IMAGE: Convolution kernel must be square to be applied");
|
||||
return;
|
||||
}
|
||||
|
||||
Color *pixels = LoadImageColors(*image);
|
||||
|
||||
Vector4 *imageCopy2 = RL_MALLOC((image->height)*(image->width)*sizeof(Vector4));
|
||||
Vector4 *temp = RL_MALLOC(kernelSize*sizeof(Vector4));
|
||||
|
||||
|
||||
for(int i = 0; i < kernelSize; i++){
|
||||
temp[i].x = 0.0f;
|
||||
temp[i].y = 0.0f;
|
||||
temp[i].z = 0.0f;
|
||||
temp[i].w = 0.0f;
|
||||
}
|
||||
|
||||
float rRes = 0.0f;
|
||||
float gRes = 0.0f;
|
||||
float bRes = 0.0f;
|
||||
float aRes = 0.0f;
|
||||
|
||||
|
||||
int startRange, endRange;
|
||||
if(kernelWidth % 2 == 0)
|
||||
{
|
||||
startRange = -kernelWidth/2;
|
||||
endRange = kernelWidth/2;
|
||||
} else
|
||||
{
|
||||
startRange = -kernelWidth/2;
|
||||
endRange = kernelWidth/2+1;
|
||||
}
|
||||
for(int x = 0; x < image->height; x++)
|
||||
{
|
||||
for(int y = 0; y < image->width; y++)
|
||||
{
|
||||
|
||||
for(int xk = startRange; xk < endRange; xk++)
|
||||
{
|
||||
for(int yk = startRange; yk < endRange; yk++)
|
||||
{
|
||||
int xkabs = xk + kernelWidth/2;
|
||||
int ykabs = yk + kernelWidth/2;
|
||||
size_t imgindex = image->width * (x+xk) + (y+yk);
|
||||
if(imgindex < 0 || imgindex >= image->width * image->height){
|
||||
temp[kernelWidth * xkabs + ykabs].x = 0.0f;
|
||||
temp[kernelWidth * xkabs + ykabs].y = 0.0f;
|
||||
temp[kernelWidth * xkabs + ykabs].z = 0.0f;
|
||||
temp[kernelWidth * xkabs + ykabs].w = 0.0f;
|
||||
} else {
|
||||
temp[kernelWidth * xkabs + ykabs].x = ((float)pixels[imgindex].r)/255.0f * kernel[kernelWidth * xkabs + ykabs];
|
||||
temp[kernelWidth * xkabs + ykabs].y = ((float)pixels[imgindex].g)/255.0f * kernel[kernelWidth * xkabs + ykabs];
|
||||
temp[kernelWidth * xkabs + ykabs].z = ((float)pixels[imgindex].b)/255.0f * kernel[kernelWidth * xkabs + ykabs];
|
||||
temp[kernelWidth * xkabs + ykabs].w = ((float)pixels[imgindex].a)/255.0f * kernel[kernelWidth * xkabs + ykabs];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < kernelSize; i++)
|
||||
{
|
||||
rRes += temp[i].x;
|
||||
gRes += temp[i].y;
|
||||
bRes += temp[i].z;
|
||||
aRes += temp[i].w;
|
||||
}
|
||||
|
||||
if(rRes < 0.0f)
|
||||
{
|
||||
rRes = 0.0f;
|
||||
}
|
||||
if(gRes < 0.0f)
|
||||
{
|
||||
gRes = 0.0f;
|
||||
}
|
||||
if(bRes < 0.0f)
|
||||
{
|
||||
bRes = 0.0f;
|
||||
}
|
||||
|
||||
if(rRes > 1.0f)
|
||||
{
|
||||
rRes = 1.0f;
|
||||
}
|
||||
if(gRes > 1.0f)
|
||||
{
|
||||
gRes = 1.0f;
|
||||
}
|
||||
if(bRes > 1.0f)
|
||||
{
|
||||
bRes = 1.0f;
|
||||
}
|
||||
|
||||
imageCopy2[image->width * (x) + (y)].x = rRes;
|
||||
imageCopy2[image->width * (x) + (y)].y = gRes;
|
||||
imageCopy2[image->width * (x) + (y)].z = bRes;
|
||||
imageCopy2[image->width * (x) + (y)].w = aRes;
|
||||
|
||||
rRes = 0.0f;
|
||||
gRes = 0.0f;
|
||||
bRes = 0.0f;
|
||||
aRes = 0.0f;
|
||||
|
||||
for(int i = 0; i < kernelSize; i++)
|
||||
{
|
||||
temp[i].x = 0.0f;
|
||||
temp[i].y = 0.0f;
|
||||
temp[i].z = 0.0f;
|
||||
temp[i].w = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (image->width) * (image->height); i++)
|
||||
{
|
||||
float alpha = (float)imageCopy2[i].w;
|
||||
pixels[i].r = (unsigned char)((imageCopy2[i].x)*255.0f);
|
||||
pixels[i].g = (unsigned char)((imageCopy2[i].y)*255.0f);
|
||||
pixels[i].b = (unsigned char)((imageCopy2[i].z)*255.0f);
|
||||
pixels[i].a = (unsigned char)((alpha)*255.0f);
|
||||
// printf("pixels[%d] = %d", i, pixels[i].r);
|
||||
}
|
||||
|
||||
|
||||
int format = image->format;
|
||||
RL_FREE(image->data);
|
||||
RL_FREE(imageCopy2);
|
||||
RL_FREE(temp);
|
||||
|
||||
image->data = pixels;
|
||||
image->format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
||||
ImageFormat(image, format);
|
||||
}
|
||||
|
||||
// Generate all mipmap levels for a provided image
|
||||
// NOTE 1: Supports POT and NPOT images
|
||||
// NOTE 2: image.data is scaled to include mipmap levels
|
||||
|
|
@ -3564,7 +3696,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
|
|||
// Draw text (default font) within an image (destination)
|
||||
void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color)
|
||||
{
|
||||
#if defined(SUPPORT_MODULE_RTEXT)
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
// Make sure default font is loaded to be used on image text drawing
|
||||
if (GetFontDefault().texture.id == 0) LoadFontDefault();
|
||||
|
||||
|
|
|
|||